王碩,鄭曉東,張強
(齊齊哈爾大學 計算機與控制工程學院,黑龍江 齊齊哈爾 161006)
在線代碼評測系統(tǒng)是一種在程序設計競賽中用于檢測源代碼正確性的在線系統(tǒng)。在評測系統(tǒng)中,用戶提交惡意代碼導致的服務器文件系統(tǒng)損壞、數據泄漏等計算機安全類問題經常出現。穩(wěn)定運行的在線代碼評測系統(tǒng)可以為用戶帶來良好的使用體驗,操作系統(tǒng)環(huán)境對評測系統(tǒng)運行的穩(wěn)定性有重要的影響。以往的在線代碼評測系統(tǒng)(Online Judge, OJ)多數運行于Windows 系統(tǒng)中,Linux 生產環(huán)境相較于Windows有著成本更低、穩(wěn)定性更強、安全性更可靠,讀、寫、執(zhí)行等權限管理更嚴格等優(yōu)勢。因此本文結合Linux 操作系統(tǒng)的優(yōu)良特性和其內核提供的相關虛擬化技術、系統(tǒng)調用攔截等技術,綜合實現了用于編譯用戶上傳的源代碼、執(zhí)行生成的二進制文件、并對結果做出判定的沙箱評測系統(tǒng)內核。沙箱評測系統(tǒng)內核即在線評測系統(tǒng)的核心功能模塊。
在Windows 操作系統(tǒng)中開發(fā)者多數采用應用程序接口攔截技術(API Hook)甄別進程中是否存在危險的系統(tǒng)調用;在Linux 操作系統(tǒng)中開發(fā)者多數使用容器技術或系統(tǒng)調用攔截技術,實現對進程中存在的惡意行為的監(jiān)控與阻斷。Linux 下的系統(tǒng)調用攔截技術有進程追蹤(Process Trace, Ptrace)和帶有過濾器的安全計算模式(Secure Computing Mode-BSD Packet Filter, Seccomp-BPF)。Linux文件權限分配機制可以限制軟件的一部分讀、寫、執(zhí)行功能;改變根目錄(Change Root, Chroot)可以設定進程可見的文件系統(tǒng)根目錄。單純使用文件權限分配機制和改變根目錄的方法構建的評測系統(tǒng)內核可能發(fā)生運行時權限泄露的問題。
目前一些優(yōu)秀的開源在線代碼評測系統(tǒng)通常采用比較原始的架構方式,使用逐級應用調用的方法,在配置運行參數后,直接將評測系統(tǒng)軟件置于主流的容器中運行。若運行由用戶提交的代碼編譯生成的軟件破壞了容器內的環(huán)境,評測系統(tǒng)監(jiān)控軟件需要使用較長的時間恢復和重啟容器及容器內的評測系統(tǒng)。如果這類評測系統(tǒng)在高并發(fā)的生產環(huán)境中運行,很可能發(fā)生操作系統(tǒng)內存溢出、CPU 過載等問題。在評測一段安全性未知的代碼時,為了保障操作系統(tǒng)的安全,提高評測效率,設計一種由組合權限控制技術與沙箱技術構成的、有著高效的任務調度策略的沙箱評測系統(tǒng)內核,具有廣泛的適用性和極高的應用價值。
沙箱評測系統(tǒng)內核在安全防御上組合使用了控制組(Control Groups, Cgroups)、命名空間(Name Space)和帶有過濾器的安全計算模式等Linux 提供的技術。控制組按資源限制級別構建不同分組,并將系統(tǒng)任務及其子任務隔離到相應的分組中,修改或更新組內的資源限制文件即可控制任務的內存占用、CPU 消耗等;命名空間主要用于隔離進程間通信、主機名等;帶有過濾器的安全計算模式指定系統(tǒng)調用攔截規(guī)則名單,并將規(guī)則名單交由Linux 內核處理,從而快速準確地限制進程的系統(tǒng)調用,達到阻斷用戶程序的危險行為的目的。使用以上技術組合而成的具有安全防御功能的沙箱評測系統(tǒng)內核,可以有效地阻止用戶代碼執(zhí)行非法的寫入、修改、刪除文件,以及連接網絡、在進程間傳遞信息等惡意行為的發(fā)生,避免用戶進程導致的操作系統(tǒng)及數據安全的問題出現。
如圖1所示,沙箱評測系統(tǒng)內核在監(jiān)控用戶進程執(zhí)行狀態(tài)時使用了Linux 內核層和系統(tǒng)調用層的接口。其利用命名空間對網絡連接、用戶ID、進程ID、進程間通信、文件系統(tǒng)、主機名稱進行統(tǒng)一的隔離;通過修改控制組內的虛擬資源限制文件,控制進程的內存消耗、磁盤消耗、CPU 占用等;使用進程資源限制函數對進程資源的使用進行嚴格的把控;選取系統(tǒng)級別的帶有過濾器的安全計算模式,攔截系統(tǒng)調用。該內核在啟動時會從配置文件中獲取系統(tǒng)調用規(guī)則名單,并交由Linux 系統(tǒng)預處理。在沙箱評測系統(tǒng)內核執(zhí)行用戶進程的分支時,操作系統(tǒng)內核會判斷用戶進程的某個系統(tǒng)調用是否在規(guī)則名單中,從而杜絕用戶進程中惡意行為的發(fā)生。

圖1 評測過程中的Linux 接口調用圖
沙箱評測系統(tǒng)內核的主要功能是評測用戶上傳的代碼,對執(zhí)行結果做出判定,并阻斷用戶代碼執(zhí)行過程中存在的危險行為,保障操作系統(tǒng)的安全。該內核可以被單點或多點部署,它通過網絡接口數據傳輸的方式進行任務的分發(fā)和結果的回傳。
沙箱評測系統(tǒng)內核使用了改進后的管道并發(fā)模型,實現了多用戶的并發(fā)評測。評測系統(tǒng)內核任務調度,在宏觀的流程中以串行的方式進行,并將任務拆分為編譯、運行、評測、反饋等子任務,每個子任務都由相應的子模塊進行調度。子模塊在調度子任務過程中采用并行或并發(fā)的處理方式,每一個子任務的執(zhí)行結果都會被異步的回傳給沙箱評測系統(tǒng)內核的調用者,由調用者進行數據的統(tǒng)一處理。
沙箱評測系統(tǒng)內核運行于Linux 環(huán)境中,其主要功能架構圖及評測流程如圖2所示。

圖2 沙箱評測系統(tǒng)內核主要功能架構圖
系統(tǒng)評測流程具體為:
(1)評測API 模塊接收用戶提交的代碼,將其封裝成結構化的評測任務,并將評測任務發(fā)送至等待隊列準備接受校驗。調度過程如圖3所示。

圖3 評測API 模塊的任務調度過程
(2)代碼校驗模塊并發(fā)的從等待隊列中取出封裝好的評測任務,進行代碼結構完整性等內容校驗。若校驗成功,則將當前評測任務發(fā)送至編譯隊列等待編譯。調度過程如圖4所示。

圖4 代碼校驗模塊的任務調度過程
(3)代碼編譯模塊并發(fā)的從編譯隊列中取出評測任務,在配置信息指定的編譯時長內對評測任務中的代碼進行編譯。若編譯成功,則將編譯評測代碼所生成的二進制文件的路徑寫入當前的評測任務中,并將該任務發(fā)送至執(zhí)行隊列,等待執(zhí)行;同時代碼編譯模塊會向評測信息拉取模塊發(fā)送拉取遠端評測數據的請求。評測信息拉取模塊獲得遠端的評測數據并存儲在本地的緩存中以待使用。調度過程如圖5所示。

圖5 編譯模塊的任務調度過程
(4)代碼執(zhí)行模塊并發(fā)的從執(zhí)行隊列中取出評測任務,在定制的具有安全防御功能的沙箱環(huán)境中安全無害的執(zhí)行當前評測任務中指定路徑下的二進制文件。目標程序在執(zhí)行過程中,代碼執(zhí)行模塊通過標準輸入將緩存中的評測數據寫入目標進程,并從標準輸出、標準錯誤中收集目標程序的輸出信息與錯誤信息,并將其與該評測數據中的正確答案一同寫入評測任務,并發(fā)送至結果采集隊列。調度過程如圖6所示。

圖6 執(zhí)行模塊的任務調度過程
(5)評測模塊并發(fā)的從結果采集隊列中收集相應目標程序的單次執(zhí)行結果,首先判定代碼執(zhí)行時間是否在規(guī)定范圍內,其次通過外部比較器,對執(zhí)行結果與標準答案進行逐字節(jié)對比,判定該評測任務是否通過。調度過程如圖7所示。

圖7 評測模塊的任務調度過程
(6)每一個小模塊執(zhí)行過后,都會向數據回傳模塊發(fā)送執(zhí)行狀態(tài),數據回傳模塊會向沙箱評測系統(tǒng)內核的上游服務反饋執(zhí)行結果。數據傳遞如圖8所示。

圖8 數據回傳
以下分別對沙箱評測系統(tǒng)內核的安全防御功能和軟件的主要功能進行測試。
如圖9所示,在root 用戶下,向沙箱評測系統(tǒng)內核發(fā)送執(zhí)行init 0 命令的指令,init 0 命令為Linux 操作系統(tǒng)關機命令,關機對于Linux 操作系統(tǒng)中的服務來講是危害非常嚴重的系統(tǒng)調用。經測試發(fā)現,沙箱評測系統(tǒng)內核已經成功攔截init 0 的系統(tǒng)調用,且在控制臺中打印出了日志信息,該信息也會被記錄在日志文件中。如發(fā)生以上行為,沙箱評測系統(tǒng)內核會通過郵件提醒其維護者“某用戶提交了危害操作系統(tǒng)的代碼或指令”。

圖9 評測內核安全防御測試
啟動沙箱評測系統(tǒng)內核后,通過接口測試工具向評測系統(tǒng)內核提交數據,得到如圖10 所示的反饋,由圖中的日志信息可見,沙箱評測系統(tǒng)內核的編譯、運行、評測等模塊是串行執(zhí)行的;在評測模塊中,如果同一份代碼有多個評測點,那么采用并發(fā)的評測方式。

圖10 沙箱評測 系統(tǒng)內核服務執(zhí)行效果圖
經多次測試,該沙箱評測系統(tǒng)內核能夠攔截用戶進程中不利于操作系統(tǒng)和數據安全的操作,準確的完成代碼評測任務。沙箱評測系統(tǒng)內核的系統(tǒng)調用規(guī)則名單取決于特定的編程語言,對于算法競賽來說,每種編程語言可以放行的系統(tǒng)調用的數量有限。該沙箱評測系統(tǒng)內核采用帶有過濾器的安全計算模式的白名單機制,嚴格地控制進程的系統(tǒng)調用,為操作系統(tǒng)安全,數據安全帶來了保障。相較于使用主流容器技術的評測系統(tǒng)核心,該沙箱評測系統(tǒng)內核原生的采用了Linux 提供的技術,使用了改進后的管道并發(fā)模型,降低了第三方軟件調用的成本,突破了任務調度上的瓶頸,提升了軟件整體性能。
通過Linux 內核提供的虛擬化技術和系統(tǒng)調用攔截技術及大量的防御性編程工作,構建起的沙箱評測系統(tǒng)內核,可以嚴格地控制進程的系統(tǒng)調用,準確地限制CPU 時間占用、內存資源占用、網絡連接。該沙箱評測系統(tǒng)內核憑借執(zhí)行效率高、資源占用率低、并發(fā)量大等優(yōu)勢,為在線代碼評測系統(tǒng)的魯棒性、執(zhí)行效率帶來了可靠的保障。