2010-05-07 42 views
3

(现在假设)情况是我的系统的用户将被赋予一大块C代码,并且需要我的系统在一个chroot沙箱中编译和运行它,这个沙箱是在运行中生成的,我想要求尽可能少的文件在框中。我只愿意使用编译器和链接器设置(例如静态链接,我期望能够找到的所有内容),并对代码可以使用的内容(例如,它们不能使用任意库)进行适度限制。在Linux上加载程序需要多少文件?

问题是我可以如何获得沙盒。很明显,我需要可执行文件,但ELF加载程序和系统调用的.so如何?我可以倾倒他们中的任何一个,还有其他我需要的东西吗?

回答

3

你不需要任何东西,除了可执行文件运行一个静态链接的hello world。你会的,当然,需要很多编译它。

你可以很容易测试这一点,我有以下的琐碎的C代码这样做:

#include <stdio.h> 
int main() { 
    puts("Hello, world\n"); 
    return 0; 
} 

用gcc -static编译它。然后创建一个新目录(我称之为“chroot-dir”),将输出(“hello”)移入它。所以chroot中唯一的文件现在是可执行文件。然后运行chroot chroot-dir ./hello,你会得到你好,世界

请注意,有些东西无法静态编译。例如,如果您的程序进行身份验证(通过PAM),则PAM模块始终会动态加载。另外请注意,某些调用需要/ etc中的各种文件;任何getpw *和getgr *函数,域名解析函数等将需要nsswitch.conf(以及一些共享对象,可能还有更多配置文件,有时甚至更多的可执行文件,具体取决于配置的查找方法。)/etc/hosts,/etc/services ,并且/etc/protocols可能对任何网络都非常有用。

找出程序使用什么文件的一个简单方法是在strace下运行它。当然,你必须首先信任该程序。

+0

非常好的答案!我想知道如何规范跨系统使用的内容:只有普遍可访问的功能才能访问。 – BCS 2010-05-07 15:28:42

0

不需要任何ELF加载器。检查你需要做什么动态库ldd <executable>。如果您设法静态编译所有内容,则不需要任何.so。除此之外,它只是关于你的程序可能需要的数据和目录结构。

但是,所有这一切只有当您使用/usr/bin/chroot命令;如果您在确保所有动态库加载完毕后让自己的程序本身调用int chroot(const char *path);本身,则它们在目录沙箱上不需要任何东西。甚至没有可执行文件本身。

编辑:不同的想法:使用TCC(或更确切地说,libtcc编译,链接,加载和运行给定的C块运行一个“外部”的chroot监狱内的整个过程中,下降到一个“内” (空),在执行之前(当然,在fork()中执行,否则你将无法跳出'内部'监狱到'外部'监狱),你也可以利用libtcc的约束的检查执行。

+1

您**不得**在非可信的可执行文件上运行ldd! ldd实际上*运行可执行文件*。 – derobert 2010-05-07 02:33:55

+0

好吧,它不是一个可执行文件,它是自己编译的C源代码。当然,它并没有让那个信任;但他可以插入chroot()调用并静态编译。任何行为良好的资料来源都应该在监狱中没有任何东西;如果它还需要别的东西,我不会称它为乖巧。 – Javier 2010-05-07 05:57:01

+0

我正在考虑让程序在chroot后加载。 – BCS 2010-05-07 15:25:25