提问人:user3051390 提问时间:2/2/2017 更新时间:3/24/2022 访问量:3365
x86-64 页表全局位
x86-64 page table Global bit
问:
此设置中的每个 PTE(页表条目)都有一个 G 位(G = 全局), 它控制此条目映射的物理页面的范围。
如果设置了 G 位,则该条目对所有进程都是全局的,并且它们可以 所有人都可以访问它映射的物理页面,但受其他访问权限的约束。 如果 G 位为零,则该条目不是全局条目,而是进程专用条目。 [内核为其页面设置 G 位,但阻止用户模式访问 通过禁用其页面上的 U 位(U = 用户模式)。
如果 G 位是在用户模式 PTE 上设置的 - 设置了 U 位的 PTE - 它不是 安全漏洞,因为系统上的每个进程现在都可以访问该页面 PTE地图?
我错过了什么吗?有没有办法在用户模式 PTE 上设置 G 位 但仅在一组受信任的进程中使其全局化,而不是全部 系统上的进程?我们可以在 PTE 中同时设置 G 和 U 位吗?
答:
是的,在 x86 上,G 位仅在存在其他类型的控件(例如将其限制为环 0,这是内核使用的控件)或未受保护的操作系统1 时才有用。
将 G-bit 视为系统调用的优化:内核将其页面映射为全局页面,因此不需要发生 TLB 刷新。您仍然需要在进程之间的上下文切换上进行 TLB 刷新,但这些刷新通常比内核<->用户模式切换少几个数量级。
您可以想象一个场景,其中 G 页面对用户进程很有用,例如共享内存:如果内核意识到这一点并对两个进程都使用映射,则在两个进程之间切换不需要使共享内存的 TLB 条目失效。不过,如今 TLB 笔芯实际上并没有那么糟糕,因为现代 x86 缓存了大量表条目,甚至超出了 TLB 以允许快速笔芯。G==1
我不认为设置 G 和 U 位是不允许的,但内核实际上不会以这种方式设置它。
最后一点,你实际上可以想象一个只读的全局映射是有用的,比如 vdso 机制。所有进程都会映射该页面,但无法修改它,内核会根据需要更新它。当然,我看不出如何实际做到这一点,因为内核需要写入访问权限,而且似乎没有办法在页表中表示“ring 3 readonly,ring 0 r/w”。也许内核可以为此页面使用另一个映射,但我不确定这是否合法:有一个覆盖“G”映射的映射(因为如果 G 映射在 TLB 中,CPU 可能永远不会看到覆盖映射)。
1 从技术上讲,它可能在单个用户操作系统上很有用,因为所有用户模式进程都具有相同的权限,但内核仍然受到用户模式的保护,但 AFAIK 该模型在当代操作系统中并不存在。
评论