我可以發布討論串嗎?
是,Sandbox2 支援執行緒。
所有執行緒都必須經過沙箱處理
由於 Linux 的運作方式,seccomp-bpf 政策只會套用至目前的執行緒,也就是說,這項政策不會套用至其他現有執行緒,但日後的執行緒會沿用這項政策:
- 如果您在第一種模式中使用 Sandbox2,也就是在
execve()
之前啟用沙箱,所有執行緒都會沿用政策,因此不會有問題。這是建議使用的沙箱模式。 - 如果您使用第二種模式,也就是執行器具有
set_enable_sandbox_before_exec(false)
,且 Sandboxee 會在需要透過SandboxMeHere()
進行沙箱化時通知執行器,請務必將篩選器套用至所有執行緒。否則,惡意程式碼可能會從沙箱執行緒遷移至非沙箱執行緒,導致沙箱逸出。
如何編譯 Sandboxee?
相較於靜態連結的可執行檔,將 sandboxee 編譯為動態連結的可執行檔,會導致需要加入允許清單的系統呼叫大幅增加 (例如 open
/openat
、mmap
等)。由於執行階段會叫用動態連結器來載入共用程式庫,因此需要所有這些額外的系統呼叫。
不過,如果查看靜態連結的沙箱,雖然需要加入許可清單的系統呼叫較少,但也會有安全性影響;ASLR 堆積熵會減少 (從 30 位元減少至 8 位元),這會讓攻擊更容易得逞。
這個兩難問題基本上可以簡化為:
- 動態:堆積 ASLR 良好,可能較難取得初始程式碼執行權,但代價是沙箱政策較不有效,可能較容易突破。
- 靜態:堆積 ASLR 不良,可能較容易取得初始程式碼執行權,但沙盒政策更有效,可能較難突破。
從歷史來看,靜態連結的二進位檔不支援與位置無關的程式碼 (pie
)。此外,Bazel 預設會新增 pie
。如要定義嚴格的系統呼叫篩選器,您必須覆寫 Bazel 的預設值。
編譯器經過多年改良,現在支援 static-pie
選項。
這個選項會指示編譯器產生與位置無關的程式碼,但與 pie
相比,現在也包含所有靜態連結的程式庫。從安全性的角度來看,static-pie
仍會降低 ASLR 熵 (從 30 位元降至 14 位元),但相較於沒有 pie
的情況,這已有所改善。
由於 Bazel 預設會新增 pie
,而靜態與其不相容,請考慮使用連結器選項標記,將 -static-pie
連結器標記傳遞至 cc_binary 規則,並覆寫預設值:
linkstatic = 1,
linkopts=["-static-pie"],
如需這些選項的範例,請參閱靜態範例的
BUILD:
static_bin.cc 會與 static-pie
靜態連結,因此可以採用非常嚴格的系統呼叫政策。這也適用於第三方二進位檔的沙箱。
我可以將 32 位元 x86 二進位檔放入沙箱嗎?
Sandbox2 只能將編譯時的相同架構設為沙箱。
此外,Sandbox2 也已停止支援 32 位元 x86。如果您嘗試使用 64 位元 x86 執行器將 32 位元 x86 二進位檔放入沙箱,或是使用 64 位元 x86 二進位檔發出 32 位元系統呼叫 (透過 int 0x80),兩者都會產生沙箱違規行為,可透過架構標籤 [X86-32] 識別。
這種行為背後的原因是,系統呼叫號碼在架構之間有所不同,而且系統呼叫政策是以執行器的架構編寫,因此允許 Sandboxee 使用不同架構會很危險。事實上,這可能會導致允許看似無害的系統呼叫,但實際上,這表示另一個更有害的系統呼叫可能會開啟沙箱,讓使用者逃脫。
執行器程序可要求的沙箱數量是否有限制?
針對每個 Sandboxee 例項 (從 forkserver 衍生出的新程序),系統會建立新的執行緒,這就是限制所在。
執行者可以要求建立多個沙箱嗎?
否。執行器執行個體會儲存 Sandboxee 的 PID,並管理 Sandbox 執行個體的 Comms 執行個體等,兩者之間為 1:1 的關係。
為什麼 forkserver.cc 內會顯示「Function not implemented」?
Sandbox2 僅支援在較新的核心上執行。目前我們支援的最低核心版本為 3.19,但日後可能會有所變更。這是因為我們使用相對較新的核心功能,包括使用者命名空間和具有 TSYNC 標記的 seccomp。
如果您在正式版上執行,這應該不是問題,因為幾乎整個機群都執行了夠新的核心。如有任何問題,請與我們聯絡。
如果您使用 Debian 或 Ubuntu,更新核心非常簡單,只要執行下列指令即可:
sudo apt-get install linux-image-<RECENT_VERSION>