我正在通过seccomp模式为自定义字节码解释器实现Linux安全沙箱。为了尽可能减少攻击表面,我想在一个完全干净的虚拟地址空间中运行它。我只需要代码和数据段加上可用的堆栈,但我不需要vsyscall、vdso或vvar。
是否有任何方式禁用此页为给定进程的分配?
发布于 2016-12-16 05:57:43
基本上,如果您希望映射本身不可用,则必须全局禁用vsyscall/vDSO。如果您只希望程序无法调用vsyscall/vDSO syscalls,则seccomp将能够这样做。不过,也有一些警告:
请参阅filter.txt
在x86-64上,默认启用vsyscall仿真。(vsyscalls是vDSO调用的遗留变量。)目前,模拟的vsyscalls将授予seccomp荣誉,并有一些奇怪之处:
要检测这种奇怪的行为,请检查addr & ~0x0C00 == 0xFFFFFFFF600000。(对于SECCOMP_RET_TRACE,请使用rip。对于SECCOMP_RET_TRAP,使用siginfo->si_call.)不要检查任何其他条件:未来的内核可能会改进vsyscall仿真,vsyscall=native模式下的当前内核的行为将有所不同,但在这些情况下,0xF...F600{0,4,8,C}00上的指令将不是系统调用。
请注意,现代系统根本不可能使用vsyscalls --它们是一个遗留特性,并且比标准的syscalls慢得多。新代码将使用vDSO,并且vDSO发出的系统调用与正常的系统调用是无法区分的。
因此,模拟的vsyscalls可以被seccomp限制,vDSO也同样受到seccomp的限制。如果禁用gettimeofday(),受限程序将无法通过模拟vsyscall、vDSO或常规syscall调用syscall。如果你用seccomp来限制他们,你不应该担心他们造成的攻击表面。
如果您担心攻击者利用vDSO映射本身(这不需要调用syscall),那么我认为没有办法可靠地在每个进程基础上禁用它。您可以防止它被链接,但是很难阻止受损的字节码解释器分配内存并将其放回。您可以使用vdso=0内核参数进行引导,这将在全局范围内禁用它,因此将其链接到其中不会有任何效果。
https://stackoverflow.com/questions/39114292
复制相似问题