4

此设置中的每个 PTE(页表条目)都有一个 G 位(G = Global),它控制此条目映射的物理页的范围。

如果设置了 G 位,则该条目对所有进程都是全局的,并且它们都可以访问它映射的物理页面,但受其他访问权限的限制。如果 G 位为零,则该条目不是全局的,而是进程私有的。[内核为其页面设置 G 位,但通过禁用其页面上的 U 位(U = 用户模式)来防止用户模式访问。]

如果在用户模式 ​​PTE 上设置 G 位 - 设置了 U 位的那个 - 这不是安全漏洞,因为系统上的每个进程现在都可以访问 PTE 映射的页面吗?

我错过了什么吗?有没有办法在用户模式 ​​PTE 上设置 G 位,但仅在一组受信任进程而不是系统上的所有进程中使其成为全局?我们可以在 PTE 中同时设置 G 和 U 位吗?

4

1 回答 1

2

是的,在 x86 上,G 位仅在存在某种其他类型的控制(例如将其限制为 Ring 0,这是内核使用的)或在不受保护的操作系统上1时才有用。

将 G 位视为系统调用的优化:内核将其页面映射为全局,因此不需要发生 TLB 刷新。您仍然需要在进程之间的上下文切换上刷新 TLB,但这些通常比内核<->用户模式切换少几个数量级。

可以想象G 页对用户进程(例如共享内存)有用的场景:如果在两个进程之间切换,则不需要使共享内存的 TLB 条目无效,如果他们知道这一点并G==1为两个进程使用映射。尽管现在 TLB 重新填充实际上并没有那么糟糕,因为现代 x86 缓存了很多表条目,甚至超出了 TLB 以允许快速重新填充。

我不认为设置 G 和 U 位是不允许的,但内核实际上不会以这种方式设置它。

最后一点,您实际上可以想象只读全局映射对于vdso机制之类的东西很有用。所有进程都会映射该页面,但不能修改它,内核会根据需要对其进行更新。当然,我看不出如何真正做到这一点,因为内核需要写访问权限,而且似乎没有办法在页表。也许内核可以为此页面使用另一个映射,但我不确定这是否合法:拥有一个覆盖“G”映射的映射(因为如果 G 映射在 TLB 中,CPU 可能永远不会看到覆盖映射)。


1从技术上讲,它在所有用户模式进程都具有相同权限的单用户操作系统上可能很有用,但内核仍然受到用户模式的保护,但 AFAIK 该模型在当代操作系统中并不真正存在。

于 2017-02-01T18:44:41.240 回答