如何禁止系统调用,GNU/Linux

7
我目前正在开发一个类似ACM的公共编程竞赛系统的后端。在这样的系统中,任何用户都可以提交代码源文件,该文件将自动编译和运行(这意味着不进行人工审核),以尝试解决某些计算问题。
后端是一个专用的GNU/Linux机器,在其中为每个参赛者创建一个用户,所有这些用户都是用户组的一部分。由特定用户发送的源文件将存储在该用户的主目录中,然后进行编译和执行,以便根据各种测试用例进行验证。
我想禁止使用Linux系统调用功能来处理源文件。原因是问题需要平台无关的解决方案,而启用不安全源文件的系统调用可能会导致潜在的安全漏洞。这样的源文件可能会成功地放置在文件系统中,甚至编译,但永远不会运行。我还希望在发送包含系统调用的源文件时得到通知。
到目前为止,我看到了以下几个检查程序可能放置的位置:
- 前端/预编译分析-已经在系统中检查了源文件,但尚未编译。对系统调用名称进行简单的文本检查器。平台相关,与编译器无关,与语言有关的解决方案。 - 编译器补丁-每当遇到系统调用时,崩溃GCC(或任何其他包含在工具链中的编译器)。平台相关,与编译器相关,与语言无关的解决方案(如果我们将检查器放置“足够远”)。也可能失去兼容性。实际上,我最不喜欢这个选择。 - 运行时检查器-每当从进程中调用系统调用时,终止此进程并报告。此解决方案与编译器和语言无关,但取决于平台-我对此感到满意,因为我将在短期和中期内在类似的平台上部署后端。
所以问题是:GNU/Linux是否提供了管理员禁止用户组、用户或特定进程使用系统调用的机会?这可能是一种安全策略或轻量级GNU实用程序。
我试图搜索谷歌,但今天谷歌不喜欢我。

前端/预编译分析 ← 预处理器技巧可以轻松规避这个问题。还有seccomp,它是一种模式,其中进程只能读/写预先打开的管道。通过prctl()调用启用。在stackoverflow.com上有类似的问题:http://www.google.com/search?q=seccomp+site%3Astackoverflow.com&btnG=Buscar&oe=utf-8 - ninjalj
@ninjalj尝试了,但没有找到。能分享一个链接吗? - iehrlich
刚刚在我的先前评论中添加了一个链接。 - ninjalj
2
如果您实际上禁止了所有系统调用,该进程将无法退出或提供任何输出。seccomp允许最小的一组系统调用。 - mark4o
这意味着我必须在任何代码源的开头包含prctl调用吗? - iehrlich
1
这些都是安全配置方面的内容,没有编码。Unix.se可能是一个理想的提问地点,SF也不错。 - Ben Voigt
2个回答

9

第一种模式seccomp仅允许进程使用四个系统调用:readwritesigreturn_exit。这可以被用于严格限制代码的沙盒,就像seccomp-nurse那样操作。

第二种模式seccomp(目前在Ubuntu 12.04已经找到或者您可以自行打补丁)提供了更多过滤系统调用的灵活性。例如,您可以首先设置过滤器,然后exec测试程序。适当地使用chrootunshare可以防止它重新exec任何其他“有趣”的东西。


1
@suddnely_me 我突然想到另一种选择,如果seccomp不起作用的话:一个基于NaCL的沙盒,比如ZeroVM - ephemient

3
我认为您需要更好地定义系统调用。我的意思是:
cat <<EOF > hello.c
#include <stdio.h>
int main(int argc,char** argv) {
  fprintf(stdout,"Hello world!\n");
  return 0;
}
EOF
gcc hello.c
strace -q ./a.out

这表明即使是一个表面上微不足道的程序也会产生约27个系统调用。您(我猜)想允许对“标准C库”的调用,但这些调用又会以系统调用的方式实现。我的意思是,使用strace或类似工具进行运行时检查比您想象的要困难得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接