SECCOMP:如何模拟malloc,realloc和free?

我想在我的服务器上执行任意(潜在危险)的二进制文件。 因此,我使用objcopy将“main”符号重命名为“other_main”,这样我就可以链接到我自己的小主函数中,为SECCOMP设置适当的值,并在调用other_main之前切换SECCOMP标志。 到目前为止,我对这个解决scheme非常满意。

现在的问题是,第三方程序代码可能包含一些对malloc的调用,可能会立即终止程序(sbrk不被允许)。 因此我想在设置malloc / realloc / calloc / free应该使用的SECCOMP之前预分配一些合理大小的数组(例如20MB)。 不幸的是,我不知道如何归档最后一步。 我是否必须自己执行所有这4个function? 我怎样才能注入我自己的函数到stdlib(例如,当printf在内部调用malloc时会发生什么?)。

并不是所有的malloc实现都基于sbrk(),例如GNU mmalloc 。 如果需要自定义实现, 这个文档也可能是有用的。

+ 这里有两个简单的malloc实现

对于malloc和free,你的程序只需要定义它自己的版本。 我见过的大多数libc实现(包括glibc,klibc和dietlibc)都会很高兴地使用你的内存分配器例程。 因此,在进入seccomp模式之前,使用mmap或sbrk分配一大块内存,然后从这个块中分配你的malloc / free。 memmgr是一个简单的堆分配器,可以很容易地从固定的缓冲区中进行分配。

seccomp的真正问题是它所允许的系统调用(读,写,退出和sigreturn)的集合根本不足以运行与或多或少的任何 libc链接的程序。 例如:

  • 在glibc中,exit和_exit调用exit_group
  • 在glibc中,printf可以调用mmap
  • 在dietlibc中,scanf可以调用ioctl
  • 等等

通常有很好的理由为什么这些电话是必要的。 例如,当从stdin读取输入时,dietlibc使用ioctl来检查stdin是否为tty,以便刷新stdout。 这是标准的行为,以确保在读取交互式输入之前提示是可见的,如果输出是行缓冲的。

所以,我得出结论,原来的seccomp模式或多或少是无用的。 然而,模式2(又名“过滤器模式”)更有用,因为它允许您将特定的系统调用列入白名单。 我在我的github页面上有一个概念验证,在seccomp模式下运行程序2,但是允许他们使用printf和scanf,以及使用malloc / free分配内存。

seccompsandbox :

  • 在一个线程中启用seccomp,该线程在同一进程中执行RPC(通过在预分配的socketpair对上read / write )到另一个(非seccomp)线程,该线程能够执行特权操作,例如mmap
  • 修补诸如malloc (在内存中,在运行时)的函数来重定向到seccomp-safe包装器

Chromium的seccomp沙箱有一些关于如何工作的更多细节。