【问题标题】:Disable Linux vsyscall vdso vvar禁用 Linux vsyscall vdso vvar
【发布时间】:2016-08-24 04:11:38
【问题描述】:

我正在通过 seccomp 模式为自定义字节码解释器实现 Linux 安全沙箱。为了尽可能减少攻击面,我想在一个完全干净的虚拟地址空间中运行它。我只需要代码和数据段以及可用的堆栈,但我不需要 vsyscall、vdso 或 vvar。

有什么方法可以禁止给给定进程分配此页面?

【问题讨论】:

    标签: linux security memory


    【解决方案1】:

    基本上,不,如果您希望映射本身不可用,则必须全局禁用 vsyscall/vDSO。如果您只希望程序无法调用 vsyscall/vDSO 系统调用,那么 seccomp 将能够做到。不过有一些注意事项:

    https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt

    在 x86-64 上,默认启用 vsyscall 仿真。 (vsyscalls 是 vDSO 调用的旧变体。)目前,模拟的 vsyscall 将支持 seccomp,但有一些奇怪之处:

    • SECCOMP_RET_TRAP 的返回值将设置一个 si_call_addr 指向 给定调用的 vsyscall 条目,而不是之后的地址 “系统调用”指令。任何想要重新开始通话的代码 应该知道 (a) 一个 ret 指令已被模拟并且 (b) 尝试恢复系统调用将再次触发标准 vsyscall 仿真安全检查,主要是恢复系统调用 毫无意义。

    • SECCOMP_RET_TRACE 的返回值将像往常一样向跟踪器发出信号, 但系统调用可能不会使用 orig_rax 寄存器。它只能更改为 -1 顺序以跳过 当前模拟呼叫。任何其他更改都可能终止该过程。 跟踪器看到的 rip 值将是系统调用入口地址; 这与正常行为不同。跟踪器不得修改 rip或rsp。 (不要依赖终止进程的其他更改。 他们可能会工作。例如,在某些内核上,选择系统调用 仅存在于未来内核中的将被正确模拟(通过 返回 -ENOSYS)。

    要检测这种古怪的行为,请检查 addr & ~0x0C00 == 0xFFFFFFFFFF600000。 (对于 SECCOMP_RET_TRACE,使用 rip。对于 SECCOMP_RET_TRAP,使用 siginfo->si_call_addr。)不要检查任何其他 条件:未来的内核可能会改进 vsyscall 仿真和当前 vsyscall=native 模式下的内核会表现不同,但 0xF...F600{0,4,8,C}00 处的指令将不是这些系统调用 案例。

    请注意,现代系统根本不可能使用 vsyscall——它们 是一个遗留功能,它们比标准慢得多 系统调用。新代码将使用 vDSO 和 vDSO 发出的系统调用 与正常的系统调用没有区别。

    所以模拟的 vsyscall 可以被 seccomp 限制,而 vDSO 也同样被 seccomp 限制。如果禁用gettimeofday(),受限程序将无法通过模拟的 vsyscall、vDSO 或常规系统调用调用该系统调用。如果您使用 seccomp 以这种方式限制它们,则不必担心它们创建的攻击面。

    如果您担心攻击者会利用 vDSO 映射本身(这不需要调用系统调用),那么我认为没有办法在每个进程的基础上可靠地禁用它。您可以阻止它被链接,但很难阻止受损的字节码解释器分配内存并将其放回原处。您可以使用vdso=0 内核参数启动,这将在全局范围内禁用它,因此链接它不会有任何作用。

    【讨论】:

      猜你喜欢
      • 2013-11-25
      • 2012-01-06
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      相关资源
      最近更新 更多