x86-64页表全局位

x86-64页表全局位,x86,x86-64,page-tables,X86,X86 64,Page Tables,此设置中的每个PTE(页表条目)都有一个G位(G=全局), 它控制此条目映射的物理页的范围 如果设置了G位,则该条目对所有进程都是全局的,它们可以 所有用户都可以访问其映射的物理页面,但需遵守其他访问权限。 如果G位为零,则该项不是全局的,而是进程的私有项。 [内核为其页面设置G位,但阻止用户模式访问 通过在其页面上禁用U位(U=用户模式)。] 如果G位是在用户模式PTE上设置的,即设置了U位的PTE,那么它不是 安全漏洞,因为系统上的每个进程现在都可以访问页面 PTE地图 我错过什么了吗?有没

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

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

如果G位是在用户模式PTE上设置的,即设置了U位的PTE,那么它不是 安全漏洞,因为系统上的每个进程现在都可以访问页面 PTE地图

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

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

将G位看作是系统调用的优化:内核将其页面映射为全局页面,因此不需要进行TLB刷新。进程之间的上下文切换仍然需要TLB刷新,但这些刷新通常比kernelusermode切换少几个数量级

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

我不认为设置G和U位是不允许的,但是内核不会这样设置

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



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

内核可以将VDSO页面数据映射到内核空间,并将其指向与映射到用户空间的页面相同的物理内存。两者都有不同的限制,允许内核对数据进行读/写权限,并将其限制为usermode的只读数据。哦,是的,当然,内核只是使用不同的虚拟地址来访问它,一切都很好。无论如何,VDSO用例可能不是一个超级有趣的用例,因为每个进程只有一页@Michaelpetch我想一个有趣的问题是:在Linux中,在同一个用户下运行的进程可以读取彼此的内存空间吗?如果不能,是否反对安全模型,如果可以的话?如果可以,那么您可以想象一个优化,其中G页面用于用户空间进程,当上下文切换到同一用户的另一个进程时,不必清除这些页面。我想它对一些使用大量不同工作进程和共享内存的应用程序可能很有用……在CR4.PCIDE=1时代之前,G位只是一种防止移动到CR3时刷新某些TLB条目的方法。进程可以访问映射的每个页面(如果它有权限):全局或非全局。没有安全漏洞。即使在CR4.PCIDE=1的情况下,PCID也被用作软件控制的方式来管理TLB缓存,它们只是间接地与进程隔离相关:它更像是一种防止操作系统刷新每个上下文开关上的TLB的功能。因此,G位与缓存的关系比与安全性的关系更大。它只需要TLB中的任何映射就可以破坏一个操作系统,不管是全局的还是非全局的。我认为BeeOnRope说的“即使没有映射,进程也可以访问这样的页面”是正确的。勾选“英特尔64和IA-32体系结构…第3卷”中的“4.10.3.2使用分页结构缓存转换线性地址”,它会显示“如果处理器找到一个TLB条目,该条目用于线性地址的页码,并且与当前PCID(或全局)相关联”,它可能使用该条目中的物理地址、访问权限和其他属性。”这可能是对物理页的内存访问,而当前PCID的地址转换结构中未引用该物理页。