可以安全地假设指针只在最低的48位包含信息吗?

编程语言 2026-07-07

在x86_64上指向用户空间的指针必须以 0b0000000 开头,占用64位中的前7 位,剩余57位用于实际指针。用户态程序会不会得到内核空间的指针,还是可以安全地假设这些最高位为空?

此外,这是否取决于内核实现?我当然可以设想一个内核会把一个内核空间指针丢回去,解引用该指针其实是有用的,但在常见系统(如Windows、Linux、macOS等)上真的会发生吗?

解决方案

最初的前提有点可疑。对于四级分页,使用了48位,这会留下64-48=16个最高位——理论上可用。是16位,而不是12位。还有在某些x64处理器上可用的五级分页,其使用57位有效地址位,因此有64-57=7个未使用的最高位。

所以并不能安全地假设总是有12位可用;实际上可能只有7 位。

那是硬件方面的问题。也可能存在软件层面的限制,例如HWAsan的实现也在同一组位上使用。

至于内核地址——大体成立,但并非百分百保证。例如,在Linux里存在legacy vsyscall机制,它使用内核端的地址页;如今几乎不再使用,但作为反例相当有用。也就是说,存在诸如LASS(在投机性错误防护方面很有用)之类的可选硬件特性,它在硬件层面强制实行50-50的分割,因此未来可能会进一步加强这方面的约束。所以并非保证,但相当普遍。

不过也没必要把自己锁定在用户态。对地址进行正确的重新规范化其实很容易(如 shl rax, 16 ; sar rax, 16 那样的做法),而且适用于所有地址——无论是用户态还是内核态。还有一些称为UAI/LAM的可选硬件特性,它们在硬件中完成此操作,因此可以在地址上获得一定的空间且没有额外开销;不过这也意味着“带标签”的地址可能流入内核空间(某些代码可能依赖于所有内核地址的最高位都被置位,因此LAM不会释放最高位,从而只能使用6 位)。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章