PAC:处理器如何识破被动过手脚的指针?
TL;DR
Pointer Authentication 用秘密密钥和上下文信息为指针生成校验码,使用前再验证,帮助缓解部分指针篡改与控制流攻击。它不是加密,也不能代替内存安全;本文用“带封签的地址”解释 PAC 的保护范围。
Pointer Authentication 用秘密密钥和上下文信息为指针生成校验码,使用前再验证,帮助缓解部分指针篡改与控制流攻击。它不是加密,也不能代替内存安全;本文用“带封签的地址”解释 PAC 的保护范围。

程序里的指针通常只是一个地址,但在安全敏感的代码中,“知道地址”还不够:如果攻击者能悄悄把它改成另一个位置,程序可能跳去执行不该执行的代码。Arm 的 Pointer Authentication(PAC,指针认证)为指针增加一层校验,让处理器在关键使用点检查它是否被篡改。
给地址加一枚带上下文的封签
PAC 的直觉可以理解为给文件封口:程序使用秘密密钥、指针值以及上下文信息,计算出一小段认证码,并把它放进指针可用的位域中。需要使用指针时,处理器再根据相同密钥和上下文验证认证码。若地址被改动,或指针被放到了不匹配的上下文里,验证便可能失败,进而让程序异常,而不是悄悄按被篡改的地址继续执行。
上下文很重要。一个返回地址、函数指针或数据指针,可能采用不同的签名方式或修饰值。只有在程序对相应位置做了签名,并在使用时执行认证,PAC 才能发挥预期作用。它常被用于保护返回地址等控制流关键数据,降低某些利用内存破坏漏洞进行代码重定向的难度。
PAC 不是加密,也不是万能护盾
认证码的用途是“发现不匹配”,不是隐藏地址内容。PAC 不会把指针变成只有持钥者才能读懂的密文,也不会自动修复造成指针被覆盖的越界写。若攻击者找到可重用的合法指针、绕过签名点,或利用未受保护的数据,系统仍可能遭受攻击。实际保护还取决于密钥管理、编译器插桩、操作系统配置和软件代码路径。
它也容易和代码签名混为一谈。应用代码签名通常用于判断一个软件包是否来自可信发布者、内容是否被改过;PAC 则是运行时对进程中的指针做认证,两者保护对象和时间点都不同。名字里都有“认证”,但解决的问题并不一样。
因此,PAC 最适合被理解为控制流防护中的一道硬件辅助检查:指针在关键位置使用前先验封签。它能提高篡改指针的成本,却不能替代边界检查、内存安全语言、沙箱和漏洞修复。安全设计不应只问“硬件开没开”,还要问关键指针是否真正经过了签名与验证。



