6

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

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

4

3 回答 3

3

并非所有 malloc 实现都基于 sbrk(),例如GNU mmalloc如果需要自定义实现,此文档也可能很有用。

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

于 2012-07-13T20:47:50.237 回答
2

对于 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
  • 等等等等

有必要进行这些调用通常有充分的理由。例如,dietlibc 使用 ioctl 在从标准输入读取输入时检查标准输入是否为 tty,以便刷新标准输出。如果输出是行缓冲的,这是确保在读取交互式输入之前提示可见的标准行为。

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

于 2012-07-26T21:17:01.180 回答
1

seccompsandbox

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

Chromium 的 seccomp 沙盒有更多关于它如何工作的细节。

于 2012-07-13T22:24:59.407 回答