<aside> 💡 简单来看就是几条指令(pac*, aut*, xpac*), 这些指令可以在CPU内部对地址做签名和验签(还有其他的,可以在文档找)

</aside>

paciasp
autiasp

pacia lr, sp
autia lr, sp

<aside> 💡 pac* 签名, aut* 验签, xpac* 将地址还原

</aside>

Untitled

Untitled

Untitled

<aside> 💡 有了这些指令 ROP protection 就变得很简单:进入函数时增加一条指令对返回地址签名,ret 前对返回地址验签; 如果返回地址被修改则不会继续执行

</aside>

// ROP protection example
paciasp
stp fp, lr, [sp, #-FRAME_SIZE]!
mov fp, sp
< function body >
ldp fp, lr, [sp], #FRAME_SIZE
autiasp
ret

<aside> 💡 PAC(Pointer Authentication Code) 是对地址签名的结果,由指令(pac*)生成,除了待签名的地址,还需要一个 128bit key 和一个 64 bit 的 context value; 其中 key 保存在系统寄存器中,context value 由具体的指令决定,比如 pacia x30, sp 就是将 sp 寄存器的值作为 context value 对x30 的值签名

</aside>

Untitled

<aside> 💡 PAC 直接保存到被签名的地址中; 有两种方式: with tagging, 不破坏原来的地址(48-bit va 和 高位的 tag),把PAC保存在 reserved bits; without tagging 会破坏原来的地址,导致其不可直接访问;具体使用哪种取决于 PCA 长度(越长越安全)等具体的需要

</aside>

Untitled

Untitled

ARMv8.3 Pointer Authentication