(現在假設)情況是我的系統的用戶將被賦予一大塊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