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

时间:2012-04-03 21:32:28

标签: linux system-calls

我目前正致力于类似ACM的公共节目竞赛系统的后端工作。在这样的系统中,任何用户都可以提交代码源,该代码源将被自动编译和运行(这意味着,没有执行人眼预先审核)以尝试解决一些计算问题。

后端是GNU / Linux专用机器,其中将为每个参赛者创建用户,所有这些用户都是用户组的一部分。任何特定用户发送的源将存储在用户的主目录中,然后进行编译和执行以针对各种测试用例进行验证。

我想要的是禁止对源使用Linux系统调用。这是因为问题需要独立于平台的解决方案,而为不安全的源启用系统调用则是潜在的安全漏洞。这些源可以成功地放在FS中,甚至可以编译,但从不运行。我还希望每当发送包含系统调用的源时都会收到通知。

到目前为止,我看到可以放置此类检查器的地方:

  • 前端/预编译分析 - 已在系统中检查过源,但尚未编译。针对系统调用名称的简单文本检查器。依赖于平台,与编译器无关,依赖于语言的解决方案。
  • 编译器补丁 - 遇到系统调用时,崩溃GCC(或工具链中包含的任何其他编译器)。依赖于平台,依赖于编译器,与语言无关的解决方案(如果我们将检查器“放得足够远”)。兼容性也可能会丢失。事实上,我最不喜欢这种选择。
  • 运行时检查程序 - 只要从进程调用系统调用,就会终止此进程并报告。这个解决方案是编译器和语言无关的,但取决于平台 - 我没关系,因为我将在短期和中期的类似平台上部署后端。

所以问题是:GNU / Linux是否为管理员提供了禁止用户组,用户或特定进程使用系统调用的机会?它可能是安全策略或轻量级GNU实用程序。

我试过谷歌,但谷歌今天不喜欢我。

2 个答案:

答案 0 :(得分:9)

模式1 seccomp允许进程将自己限制为四个系统调用:readwritesigreturn_exit。这可以用于严格沙盒代码,如seccomp-nurse所做的那样。

mode 2 seccomp(在撰写本文时,在Ubuntu 12.04中找到或修补您自己的内核)为​​过滤系统调用提供了更大的灵活性。例如,您可以先设置过滤器,然后exec测试中的程序。适当使用chrootunshare可以用来阻止它重新exec其他任何“有趣的”。

答案 1 :(得分: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或类似的东西)。