Linux x86_64上的卷影堆栈实现

Linux x86_64上的卷影堆栈实现,linux,assembly,x86-64,system-calls,control-flow,Linux,Assembly,X86 64,System Calls,Control Flow,在中,通过LDT使用x86段实现受保护的阴影堆栈。但在x86_中,64分段被禁用。是否有其他机制可用于在x86_64上实现受保护的堆栈 编辑 发现了一个最近的描述了几种替代方案的方法。我认为32位CFI的想法是对DS/ES/SS设置一个限制,并将阴影堆栈置于该限制之外,因此它只能被带有gs:段覆盖前缀的指令损坏 这仅适用于x86-64上的兼容模式(32位用户空间),因为当CPU处于长模式时,CS/DS/ES/SS具有固定的base=0且没有限制 FS和GS即使在长模式下也可以有一个非零基,但即使

在中,通过LDT使用x86段实现受保护的阴影堆栈。但在x86_中,64分段被禁用。是否有其他机制可用于在x86_64上实现受保护的堆栈

编辑


发现了一个最近的描述了几种替代方案的方法。

我认为32位CFI的想法是对DS/ES/SS设置一个限制,并将阴影堆栈置于该限制之外,因此它只能被带有
gs:
段覆盖前缀的指令损坏

这仅适用于x86-64上的兼容模式(32位用户空间),因为当CPU处于长模式时,CS/DS/ES/SS具有固定的base=0且没有限制

FS和GS即使在长模式下也可以有一个非零基,但即使您可以对这些段设置限制,这与您需要的正好相反。(这将保护常规内存不受带有
gs
前缀的指令的影响,而不是相反。)有趣的事实:大多数CPU在长模式下都不支持对这些段的限制


对于(长模式下的32位指针),您可以将阴影堆栈置于低4GiB虚拟地址空间之外。普通编译器生成的代码总是注意将指针截断为32位。当前默认的代码生成策略(
-maddress mode=short
)是在具有内存操作数的每条指令上使用地址大小前缀,除了假定始终为零扩展的rsp

这会导致错误,但这意味着当前gcc为x32编译的代码肯定会将指针截断为32位,即使存在UB,这使得编译器生成的代码无法加载/存储在低4GiB地址空间之外


我不认为长模式有任何通用的方法可以使虚拟地址空间区域仅通过某种特殊指令(前缀或其他指令)访问。因此,如果您要防御使用64位操作数大小的普通代码,则没有任何选项可以用基线x86-64替换段技巧。您必须映射/取消映射阴影堆栈,这将非常缓慢

现在还有其他几种技术用于强制执行/检查控制流。(控制流强制技术)为各种内容提供硬件支持,包括阴影堆栈。他们的结论以“总之,英特尔的CET主要是微软的弱CFI实现的硬件实现,并添加了一个影子堆栈”开头。如果这篇评论是准确的,IDK。Grsecurity确实生产了一种竞争产品(他们承认这一点),因此可能存在一些偏见。我相信CET总比什么都没有好


另请参阅x86(或可能特别是Intel)CPU功能列表,这些功能通常有助于安全性(如MPX边界检查),而不仅仅是控制流。

我认为32位CFI的想法是对DS/ES/SS设置一个限制,并将阴影堆栈置于该限制之外,因此,它只能被带有
gs:
段覆盖前缀的指令损坏

这仅适用于x86-64上的兼容模式(32位用户空间),因为当CPU处于长模式时,CS/DS/ES/SS具有固定的base=0且没有限制

FS和GS即使在长模式下也可以有一个非零基,但即使您可以对这些段设置限制,这与您需要的正好相反。(这将保护常规内存不受带有
gs
前缀的指令的影响,而不是相反。)有趣的事实:大多数CPU在长模式下都不支持对这些段的限制


对于(长模式下的32位指针),您可以将阴影堆栈置于低4GiB虚拟地址空间之外。普通编译器生成的代码总是注意将指针截断为32位。当前默认的代码生成策略(
-maddress mode=short
)是在具有内存操作数的每条指令上使用地址大小前缀,除了假定始终为零扩展的rsp

这会导致错误,但这意味着当前gcc为x32编译的代码肯定会将指针截断为32位,即使存在UB,这使得编译器生成的代码无法加载/存储在低4GiB地址空间之外


我不认为长模式有任何通用的方法可以使虚拟地址空间区域仅通过某种特殊指令(前缀或其他指令)访问。因此,如果您要防御使用64位操作数大小的普通代码,则没有任何选项可以用基线x86-64替换段技巧。您必须映射/取消映射阴影堆栈,这将非常缓慢

现在还有其他几种技术用于强制执行/检查控制流。(控制流强制技术)为各种内容提供硬件支持,包括阴影堆栈。他们的结论以“总之,英特尔的CET主要是微软的弱CFI实现的硬件实现,并添加了一个影子堆栈”开头。如果这篇评论是准确的,IDK。Grsecurity确实生产了一种竞争产品(他们承认这一点),因此可能存在一些偏见。我相信CET总比什么都没有好


另请参阅x86(或可能特别是Intel)CPU功能的列表,这些功能通常有助于安全性(如MPX边界检查),而不仅仅是控制流。

从技术上讲,在长模式下仍有段。FS和GS仍然可用。你可以为这些段设置一个基础,但你不能设置一个限制(在大多数处理器上),但我相信它不会提供内存隔离,因为它也可以通过DS访问。我不是说你可以使用它来实现这一目的,只是指出,即使在长模式下,分段也不会完全消失。对。所采取的观点:)从技术上讲,在长模式中仍然存在片段。FS和GS仍然可用。您可以为这些段设置基础,但不能设置限制(在大多数处理器上),但我相信它不会提供内存