使用gcc/g++时抑制系统调用

7
我在大学局域网上有一个门户网站,人们可以在其中上传C/C++编程谜题的代码。我希望使门户网站更加安全,防止人们通过所提交的代码进行系统调用。可能会有几种解决方法,但我想知道是否可以通过设置一些聪明的gcc标志来简单地完成这个任务。libc默认包含,这似乎是声明系统调用的基本文件。是否有一种方法可以告诉gcc/g++在编译时“忽略”这个文件,以便无法访问unistd.h中声明的任何函数?

2
使用类似 http://www.citi.umich.edu/u/provos/systrace/ 这样的东西怎么样? - GWW
我目前正在做类似于systrace的事情 - 只是想知道是否更容易绕过那些在man页面描述中与常规库代码明显不同的东西。 - kyun
3个回答

3

限制访问头文件并不能阻止您访问libc函数:如果链接了libc,它们仍然可用 - 只是您没有原型(和宏)可以使用;但您可以自己复制它们。

而不链接libc也无济于事:系统调用可以直接通过内联汇编(甚至涉及跳转到数据的技巧)进行。

总体而言,我认为这不是一个好方法。在完全独立的虚拟沙盒中运行上传的代码(例如通过QEMU或类似工具)可能是更好的选择。


确实如此-我没有想到那个。我猜沙盒技术应该是解决的方法,但对于这样一个简单(通常不恶意)的环境来说,看起来需要很多开销。 - kyun

3

为什么chroot("/var/jail/empty"); setuid(65534);不够好(假设65534有合理的限制)?

是否有特殊原因呢?


这是类似于为运行上传的代码创建/模拟不同用户的东西吗?我见过其他人使用这种方法 - 总是想知道如何实现。 - kyun
1
将其与-static链接,将二进制文件写入jail并运行。由于jail中没有其他内容,因此他们几乎无法做任何事情。 - Joshua
啊!这个技巧真不错!就像你自己的小沙盒一样!我觉得这比抑制系统调用要简单得多。现在,我已经从沙盒的想法转变为沙盒的实现。谢谢! - kyun
有一件很蠢的小事,你仍然必须确保它们无法打开网络连接。简单的方法是:将socket()系统调用修补为if (uid ==某个值) return -EPERM。 - Joshua

2

-D 可以覆盖单个函数名称。例如:

gcc file.c -Dchown -Dchdir

或者您可以自己设置包含保护:

gcc file.c -D_UNISTD_H

然而,聪明的提交者可以通过使用#undef轻松地撤消它们的影响。

我明白你的意思 - 我认为正如Matthew Slattery指出的那样,最好的做法是建立一个沙盒环境。 - kyun

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