x86_64上的影子堆栈实现

时间:2018-03-22 03:49:06

标签: linux assembly x86-64 system-calls control-flow

Control Flow Integrity中,通过LDT使用x86段实现受保护的影子堆栈。但是在x86_64中,分段被禁用。是否有任何其他机制可用于在x86_64上实现受保护的堆栈?

修改

找到了最近的paper,其中介绍了几种替代方案。

1 个答案:

答案 0 :(得分:2)

我认为32位CFI的想法是设置DS / ES / SS的限制,并将阴影堆栈放在之外,因此它只能被带有{的指令损坏{1}}段覆盖前缀。

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

FS和GS即使在长模式下也可以具有非零基数,但即使您可以对这些段设置限制,它也与您需要的相反。 (这样可以保护常规内存不受带有gs:前缀的指令的影响,而不是反过来。)有趣的事实:@MichaelPetch says大多数CPU都不支持长模式下这些段的限制。< / p>

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

这导致a lot of wasted address-size prefixes,但这意味着当前gcc为x32编译的代码肯定会截断指向32位的指针,即使存在UB,也使得编译器生成的代码无法在外部加载/存储低4GiB的地址空间。

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

目前,还有其他一些技术可用于执行/检查控制流程。 Intel's CET(控制流执行技术)为各种内容提供硬件支持,包括影子堆栈。 Grsecurity published a review / critique of it。他们的结论始于“总之,英特尔的CET主要是​​微软弱CFI实现的硬件实现,增加了一个影子堆栈。”如果此评论准确,则为IDK。 Grsecurity确实产生了一种竞争产品(他们承认),因此可能存在一些偏见。我确信CET总比没有好。

另请参阅https://github.com/huku-/research/wiki/Intel-CPU-security-features以获取有助于一般安全性(如MPX边界检查)的x86(或特别是Intel)CPU功能的列表,而不仅仅是控制流。

相关问题