Art*_*ent 5 linux security x86 linux-kernel
这是在参考CVE-2018-8897(其似乎与CVE-2018至1087年如下)中,所描述:
英特尔64和IA-32架构软件开发人员手册(SDM)的系统编程指南中的一些声明在部分或全部操作系统内核的开发中处理不当,导致MOV SS延迟的#DB异常出现意外行为或者POP SS,正如(例如)Windows,macOS,某些Xen配置或FreeBSD中的权限提升或Linux内核崩溃所证明的那样.MOV到SS和POP SS指令禁止中断(包括NMI),数据断点和单步陷阱异常,直到指令边界跟随下一条指令(SDM第3A卷;第6.8.3节).(禁止的数据断点是MOV到SS或POP到SS指令本身访问的存储器.)请注意,中断使能(EFLAGS.IF)系统标志不会禁止调试异常(SDM第3A卷;第2.3节) .如果MOV到SS或POP到SS指令之后的指令是SYSCALL,SYSENTER,INT 3等指令,它们在CPL <3时将控制权转移到操作系统,则在转移到CPL <3之后交付调试例外完成了.操作系统内核可能不期望这种事件顺序,因此可能会在发生事件时遇到意外行为.
在阅读与Linux内核相关的git提交时,我注意到提交消息指出:
x86/entry/64:不要将#ST条目用于#BP堆栈
#BP/int3没什么值得的.我们不允许kprobes在内核中少数几个在CPL0上运行且堆栈无效的地方,并且32位内核永远使用#BP的正常中断门.
此外,在内核模式下,我们不允许在具有usergs的地方使用kprobes,因此"偏执"也是不必要的.
鉴于漏洞,我试图理解提交消息中的最后一句/段落.据我所知,IST条目是指中断堆栈表中可用于处理中断的(据称)"已知良好"堆栈指针之一.我也理解#BP是指一个断点异常(相当于INT3),并且kprobes是声称只在内核中的一些地方以ring 0(CPL0)特权级别运行的调试机制.
但是我在下一部分完全迷失了,这可能是因为"usergs"是一个错字而我只是错过了预期的内容:
此外,在内核模式下,我们不允许在具有usergs的地方使用kprobes,因此"偏执"也是不必要的.
这句话是什么意思?
usergs 指的是x86-64 swapgs 指令,它gs与内核保存的内部 GS 值进行交换,以从系统调用入口点查找内核堆栈。交换还会交换缓存的 gsbase 段信息,而不是根据值gs本身从 GDT 重新加载。(wrgsbase可以独立于GDT/LDT更改GS基数)
AMD的设计是syscall不改变RSP指向内核堆栈,并且不读/写任何内存,因此syscall本身可以很快。但随后您进入内核,所有寄存器都保存其用户空间值。请参阅为什么 Windows64 使用与 x86-64 上的所有其他操作系统不同的调用约定?有关 2000 年左右内核开发人员和 AMD 架构师之间的邮件列表讨论的一些链接,调整设计syscall并swapgs使其在任何 AMD64 CPU 销售之前可用。
显然,跟踪 GS 当前是内核还是用户值对于错误处理来说很棘手:没有办法说“我现在想要 kernelgs”;您必须知道是否swapgs在任何错误处理路径中运行。唯一的指令是交换,而不是将其设置为一个或另一个。
阅读arch/x86/entry/entry_64.S例如https://github.com/torvalds/linux/blob/9fb71c2f230df44bdd237e9a4457849a3909017d/arch/x86/entry/entry_64.S#L1267(来自当前Linux)中的评论,其中提到了usergs,下一个评论块描述了swapgs之前执行的操作使用内核 gsbase 跳转到一些错误处理代码。
IIRC,Linux 内核[gs:0]在该线程的内核堆栈的最低地址保存一个线程信息块。该块包括内核堆栈指针(作为绝对地址,而不是相对于gs)。
rsp如果这个错误基本上是欺骗内核从用户控制的 gsbase 加载内核,或者以其他方式搞砸了航位推算,所以它在某些时候swapgs出现错误,我不会感到惊讶。gs
| 归档时间: |
|
| 查看次数: |
161 次 |
| 最近记录: |