(现在假设)情况是我的系统的用户将被赋予一大块C代码,并且需要我的系统在一个chroot沙箱中编译和运行它,这个沙箱是在运行中生成的,我想要求尽可能少的文件在框中。我只愿意使用编译器和链接器设置(例如静态链接,我期望能够找到的所有内容),并对代码可以使用的内容(例如,它们不能使用任意库)进行适度限制。在Linux上加载程序需要多少文件?
问题是我可以如何获得沙盒。很明显,我需要可执行文件,但ELF加载程序和系统调用的.so如何?我可以倾倒他们中的任何一个,还有其他我需要的东西吗?
(现在假设)情况是我的系统的用户将被赋予一大块C代码,并且需要我的系统在一个chroot沙箱中编译和运行它,这个沙箱是在运行中生成的,我想要求尽可能少的文件在框中。我只愿意使用编译器和链接器设置(例如静态链接,我期望能够找到的所有内容),并对代码可以使用的内容(例如,它们不能使用任意库)进行适度限制。在Linux上加载程序需要多少文件?
问题是我可以如何获得沙盒。很明显,我需要可执行文件,但ELF加载程序和系统调用的.so如何?我可以倾倒他们中的任何一个,还有其他我需要的东西吗?
你不需要任何东西,除了可执行文件运行一个静态链接的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下运行它。当然,你必须首先信任该程序。
不需要任何ELF加载器。检查你需要做什么动态库ldd <executable>
。如果您设法静态编译所有内容,则不需要任何.so
。除此之外,它只是关于你的程序可能需要的数据和目录结构。
但是,所有这一切只有当您使用/usr/bin/chroot
命令;如果您在确保所有动态库加载完毕后让自己的程序本身调用int chroot(const char *path);
本身,则它们在目录沙箱上不需要任何东西。甚至没有可执行文件本身。
编辑:不同的想法:使用TCC(或更确切地说,libtcc编译,链接,加载和运行给定的C块运行一个“外部”的chroot监狱内的整个过程中,下降到一个“内” (空),在执行之前(当然,在fork()中执行,否则你将无法跳出'内部'监狱到'外部'监狱),你也可以利用libtcc的约束的检查执行。
非常好的答案!我想知道如何规范跨系统使用的内容:只有普遍可访问的功能才能访问。 – BCS 2010-05-07 15:28:42