【问题标题】:How to prohibit system calls, GNU/Linux如何禁止系统调用,GNU/Linux
【发布时间】:2012-04-17 14:33:36
【问题描述】:

我目前正在开发类似 ACM 的公共编程竞赛系统的后端。在这样的系统中,任何用户都可以提交一个代码源,该源代码将被自动编译并运行(即不进行人眼预审核),试图解决一些计算问题。

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

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

到目前为止,我看到了可以放置此类检查器的以下位置:

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

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

我尝试使用 Google,但今天 Google 不喜欢我。

【问题讨论】:

  • 前端/预编译分析 ← 预处理器技巧可以轻松规避这一点。 seccomp 是一种进程只能读取/写入预先打开的管道的模式。它通过prctl() 调用启用。 SO上有类似的问题:google.com/…
  • @ninjalj 试过了,但没有找到。介意分享链接吗?
  • 刚刚添加了我之前评论的链接。
  • 如果您实际上禁止了所有系统调用,则进程无法事件退出或提供任何输出。 seccomp 允许最小集合。
  • 这是所有安全配置的东西,没有编码。 Unix.se 将是一个理想的询问场所,SF 也不错。

标签: linux system-calls


【解决方案1】:

我认为您需要更好地定义系统调用。我的意思是,

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 或类似的东西)。

【讨论】:

    【解决方案2】:

    模式 1 seccomp 允许进程将自身限制为恰好四个系统调用:readwritesigreturn_exit。这可用于严格沙箱代码,就像 seccomp-nurse 所做的那样。

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

    【讨论】:

    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 2017-12-12
    • 2013-12-18
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多