2010-05-07 45 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