解释Linux提交消息,修补保护POP SS后跟#BP中断(INT3)

解释Linux提交消息,修补保护POP SS后跟#BP中断(INT3),第1张

概述这是参考 CVE-2018-8897(与 CVE-2018-1087有关),描述如下: A statement in the System Programming Guide of the Intel 64 and IA-32 Architectures Software Developer’s Manual (SDM) was mishandled in the development of s 这是参考 CVE-2018-8897(与 CVE-2018-1087有关),描述如下:

A statement in the System Programming GuIDe of the Intel 64 and IA-32 Architectures Software Developer’s Manual (SDM) was mishandled in the development of some or all operating-system kernels,resulting in unexpected behavior for #DB exceptions that are deferred by MOV SS or POP SS,as demonstrated by (for example) privilege escalation in windows,macOS,some Xen configurations,or FreeBSD,or a linux kernel crash. The MOV to SS and POP SS instructions inhibit interrupts (including NMIs),data breakpoints,and single step trap exceptions until the instruction boundary following the next instruction (SDM Vol. 3A; section 6.8.3). (The inhibited data breakpoints are those on memory accessed by the MOV to SS or POP to SS instruction itself.) Note that deBUG exceptions are not inhibited by the interrupt enable (EFLAGS.IF) system flag (SDM Vol. 3A; section 2.3). If the instruction following the MOV to SS or POP to SS instruction is an instruction like SYSCALL,SYSENTER,INT 3,etc. that transfers control to the operating system at CPL < 3,the deBUG exception is delivered after the transfer to CPL < 3 is complete. OS kernels may not expect this order of events and may therefore experIEnce unexpected behavior when it occurs.

在阅读this related git commit to the Linux kernel时,我注意到提交消息指出:

x86/entry/64: Don’t use IST entry for #BP stack

There’s nothing IST-worthy about #BP/int3. We don’t allow kprobes
in the small handful of places in the kernel that run at CPL0 with
an invalID stack,and 32-bit kernels have used normal interrupt
gates for #BP forever.

Furthermore,we don’t allow kprobes in places that have usergs while
in kernel mode,so “paranoID” is also unnecessary.

鉴于漏洞,我试图理解提交消息中的最后一句/段落.据我所知,IST条目是指中断堆栈表中可用于处理中断的(据称)“已知良好”堆栈指针之一.我也理解#BP是指一个断点异常(相当于INT3),而kprobes是一种调试机制,声称它只在内核中的一些地方以ring 0(CPL0)特权级别运行.

但是我在下一部分完全迷失了,这可能是因为“usergs”是一个错字而我只是错过了预期的内容:

Furthermore,so “paranoID” is also unnecessary.

这句话是什么意思?

解决方法 usergs指的是 x86-64 swapgs instruction,它与内部保存的GS值交换gs,以便内核从系统调用入口点查找内核堆栈.交换还交换缓存的gsbase段信息,而不是基于gs值本身从GDT重新加载. ( wrgsbase可以独立于GDT / LDT改变GS基础)

AMD的设计是,系统调用不会将RSP更改为指向内核堆栈,也不会读取/写入任何内存,因此系统调用本身可以很快.但随后您进入内核,所有寄存器都保存其用户空间值.有关内核开发人员和AMD架构师之间在2000年之间进行邮件列表讨论的一些链接,请参阅Why does Windows64 use a different calling convention from all other OSes on x86-64?,调整syscall和swapgs的设计,使其在任何AMD64 cpu出售之前都可用.

显然,跟踪GS当前是内核还是用户值对于错误处理来说很棘手:没有办法说“我现在想要内核”;您必须知道是否在任何错误处理路径中运行swapgs.唯一的指令是交换,而不是将其设置为一个与另一个.

阅读arch / x86 / entry / entry_64.S中的注释. https://github.com/torvalds/linux/blob/9fb71c2f230df44bdd237e9a4457849a3909017d/arch/x86/entry/entry_64.S#L1267(来自当前的linux)提到了usergs,下一个注释块描述了在使用内核gsbase跳转到一些错误处理代码之前做一个swapgs.

IIRC,linux内核[gs:0]在该线程的内核堆栈的最低地址处保存一个线程信息块.该块包括内核堆栈指针(作为绝对地址,而不是相对于gs).

如果这个BUG基本上是欺骗内核从用户控制的gsbase加载内核rsp,或者搞砸了swapgs的死算,那么我不会感到惊讶,所以它在某些时候有错误的gs.

总结

以上是内存溢出为你收集整理的解释Linux提交消息,修补/保护POP SS后跟#BP中断(INT3)全部内容,希望文章能够帮你解决解释Linux提交消息,修补/保护POP SS后跟#BP中断(INT3)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1029709.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存