1. 程式人生 > >Native Client: 用於行動式,不受信任的x86本機程式碼的沙箱(二)

Native Client: 用於行動式,不受信任的x86本機程式碼的沙箱(二)

Native Client: 用於行動式,不受信任的x86本機程式碼的沙箱(二)

Native Client: A Sandbox for Portable, Untrusted x86 Native Code
原文:https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/34913.pdf
注意!本文有刪節,見諒!

書接上文 :Native Client: 用於行動式,不受信任的x86本機程式碼的沙箱(一)

3 NC實現

3.1 沙盒

在本節中,我們將解釋NaCl如何實現軟體故障隔離。設計僅限於顯式控制流程,用機器程式碼中的呼叫和跳轉表示。其他型別的控制流(例如異常)在NaCl服務執行時中管理,在不可信程式碼外部,如下面的NaCl執行時實現所述。

我們的內部沙箱使用一組可靠的拆卸規則,一個遵守這些規則的修改後的編譯工具鏈,以及一個確認遵循規則的靜態分析器。這種設計允許一個小的可信程式碼庫(TCB)(PS:什麼是TCB?Trusted computer system evaluation criteria),TCB外部的編譯工具,以及一個小到足以允許徹底檢查和測試的驗證器。我們的驗證器實現需要少於600個C語句(分號),包括x86解碼器和cpuid解碼。這編譯成大約6000位元組的可執行程式碼(Linux優化構建),其中大約900位元組是cpuid實現,1700位元組是解碼器,3400位元組是驗證器邏輯。這個過程中驗證器必須解決四個子問題:

  • 資料完整性:資料沙箱外無負載或儲存
  • 可靠的拆卸
  • 沒有不安全的指令
  • 控制流程完整性

為了解決這些問題,NaCl建立在先前關於CISC故障隔離的工作之上。我們的系統將80386分段儲存器[14]與之前的CISC軟體故障隔離技術相結合[40]。我們使用80386段來約束對虛擬32位地址空間的連續子範圍的資料引用。這使我們能夠有效地實現資料沙箱,而無需載入載入和儲存指令的沙箱。 VX32 [20],[21]以類似的方式實現其資料沙箱。請注意,NaCl模組是32位x86可執行檔案。不支援更新的64位可執行模型。

NaCl二進位制執行檔案的約束

C1 一旦載入到記憶體中,二進位制檔案就不可寫,在執行期間由作業系統級保護機制強制執行。
C2 二進位制檔案在起始地址為零時靜態連結,文字的第一個位元組為64K。
C3 所有間接控制傳輸都使用nacljmp偽指令(在下面定義)。
C4 使用至少一個hlt指令(0xf4)將二進位制檔案填充到最近的頁面。
C5 二進位制不包含與32位元組邊界重疊的指令或偽指令。
C6 所有有效的指令地址都可以通過從載入(基址)地址開始的直通反彙編來到達。
C7 所有直接控制傳輸都針對有效指令。

上文列出了NC對不受信任的二進位制檔案的約束。約束C1和C6一起使拆卸可靠。通過可靠的拆卸作為工具,檢測不安全的指令非常簡單。 NC不允許的部分操作碼包括:

  • syscallint。不受信任的程式碼無法直接呼叫作業系統。
  • 所有修改x86段狀態的指令,包括lds,遠端呼叫等。
  • ret。使用沙盒se-實現返回
    以間接跳躍結束的quence。

除了促進控制沙箱之外,如果在堆疊上檢查了返回地址,則排除 ret 還可以防止由於競爭條件而導致的漏洞。類似的論點要求我們在間接的jmpcall指令中禁止記憶體定址模式。 NC允許使用hlt指令。它永遠不應該由正確的指令流執行,並且會導致模組立即終止。作為一個安全問題,我們不允許所有其他特權/ring-0指令,因為在正確的使用者模式指令流中從不需要它們。我們還限制x86字首使用僅允許已知的有用指令。根據經驗,我們發現這消除了與CPU勘誤相關的某些拒絕服務漏洞。
第四個問題是控制流完整性,確保程式文字中的所有控制傳輸都針對在反彙編期間識別的指令。對於每個直接分支,我們靜態地計算目標並根據約束C6確認它是有效指令。我們的間接分支技術將80386分段儲存器與簡化的沙盒序列相結合。根據約束C2和C4,我們使用CS段將可執行文字約束到從零開始的地址範圍,大小為4K位元組的倍數。在文字範圍受分段儲存器約束的情況下,根據約束C3和C5,簡單的常量掩碼足以確保間接分支的目標與 mod 32 對齊:

and %eax, 0xffffffe0
jmp *%eax

我們將這個特殊的兩個指令序列稱為nacljmp。編碼為三位元組and以及兩位元組jmp,它與以前的CISC沙盒實現相比有利[40],[41],[56]。如果沒有分段儲存器或從零開始的文字,沙盒控制流通常需要兩個六位元組指令(一個and和一個or),總共十四個位元組。

NaCl驗證器的虛擬碼

// TextLimit = the upper text address limit
// Block(IP) = 32-byte block containing IP
// StartAddr = list of inst start addresses
// JumpTargets = set of valid jump targets
// Part 1: Build StartAddr and JumpTargets
IP = 0; icount = 0; JumpTargets = { }
while IP <= TextLimit:
  if inst_is_disallowed(IP):
    error "Disallowed instruction seen"
  StartAddr[icount++] = IP
  if inst_overlaps_block_size(IP):
    error "Block alignment failure"
  if inst_is_indirect_jump_or_call(IP):
    if !is_2_inst_nacl_jmp_idiom(IP) or
      icount < 2 or
      Block(StartAddr[icount-2]) != Block(IP):
      error "Bad indirect control transfer"
  else
    // Note that indirect jmps are inside
    // a pseudo-inst and bad jump targets
    JumpTargets = JumpTargets + { IP }
  // Proceed to the fall-through address
  IP += InstLength(IP)
// Part 2: Detect invalid direct transfers
for I = 0 to length(StartAddr)-1:
  IP = StartAddr[I]
  if inst_is_direct_jump_or_call(IP):
    T = direct_jump_target(IP)
    if not(T in [0:TextLimit))
       or not(T in JumpTargets):
      error "call/jmp to invalid address"

我們接下來斷言然後證明我們的設計對於控制流完整性的正確性。假設有問題的文字沒有錯誤驗證,讓S成為StartAddr列表中的指令集地址。

定理:S包含從S中具有地址的指令可以到達的所有地址。
證明:矛盾。假設在執行期間從S中具有地址的前驅指令A到達不在S中的地址IP。因為執行受到x86分段的約束,所以IP必須通常在[0:TextLimit中]。因此,IP只能通過三種方式之一達成。

情況1:通過從A落下來達到IP。這意味著IP是InstAddr(A)+ InstLength(A)。但是這個地址應該是在第1部分的S中。矛盾。

情況2:通過直接跳轉或從S中的指令A呼叫來到達IP。然後IP必須在JumpTargets中,這是由構造的第2部分檢查的條件。觀察JumpTargets是S的子集,來自構造的第1部分。因此,IP必須在S.矛盾中。

情況3:通過從S中的A指令的間接轉移到達IP。由於A處的指令是間接呼叫或跳轉,所以A的執行總是緊跟在執行a和。在和計算出的地址對齊0 mod 32.因為沒有指令可以跨越0 mod 32邊界,所以[0,TextLimit]中的每個0 mod 32地址必須在S中。因此IP在S.矛盾中。

因此,從S中的指令到達的任何指令也在S中。

請注意,此分析僅涵蓋顯式的同步控制流程。第3.2節討論了例外情況。
如果驗證器過於緩慢,可能會阻止人們使用該系統。我們發現我們的驗證器能夠以大約30MB /秒的速度檢查程式碼(在1.2秒內為35.7 MB,在帶有MacOS 10.5的MacBook Pro,2.4GHz Core 2 Duo CPU,常溫檔案系統快取上測量)。在此速度下,與下載時間相比,驗證的計算時間通常非常小,因此不是效能問題。
我們相信這個內部沙箱需要非常強大。我們已經使用隨機指令生成以及有效x86指令的詳盡列舉來測試它以解碼缺陷。我們還使用“模糊測試”來隨機修改測試可執行檔案。最初這些測試暴露了關鍵的實現缺陷,儘管測試仍在繼續,但最近沒有發現任何缺陷。我們還測試了各種x86微處理器實現,擔心處理器勘誤可能導致可利用的缺陷[31],[38]。我們確實發現CPU缺陷的證據導致系統“掛起”,需要電源迴圈來恢復機器。這發生在早期版本的驗證器允許相對不受限制地使用x86字首位元組,並且由於將其限制為僅允許已知的有用字首,我們無法再現這些問題。

3.2 異常處理

不允許出現硬體異常(segmentation faults, floating point exceptions)和外部中斷,部分原因是Linux,MacOS和Windows中的異常和不相容的異常模型。 Linux和Windows都通過%esp依賴x86堆疊來傳遞這些事件。遺憾的是,由於NaCl修改了%ss段暫存器,因此堆疊似乎對作業系統無效,因此它無法傳遞事件並且相應的程序立即終止。將x86分段用於資料沙箱有效地阻止了從這些型別的異常中恢復。因此,NaCl不可信模組將故障安全策略應用於異常。每個NaCl模組都在其自己的OS過程中執行,以實現異常隔離。 NaCl模組不能使用異常處理來從硬體異常中恢復,並且必須對於此類錯誤條件或突然終止的風險是正確的。在某種程度上,這很方便,因為在將這些事件安全地傳遞給不受信任的程式碼時存在非常具有挑戰性的安全問題。
雖然我們目前無法支援硬體異常,但NC確實支援C++異常[57]。由於這些是同步的並且可以完全在使用者級實現,因此沒有實現問題。 Windows結構化異常處理[44]需要非行動式操作支援,因此不受支援。

服務執行時是由NPAPI外掛呼叫的本機可執行檔案,該外掛還支援服務執行時和瀏覽器之間的互動。它支援Windows,MacOS和Linux上的各種Web瀏覽器。它實現了動態實施,維護內部沙箱的完整性,並提供資源抽象,以將NaCl應用程式與主機資源和作業系統介面隔離開來。它包含可信程式碼和資料,這些程式碼和資料在與包含的NaCl模組共享程序時,只能通過受控介面訪問。服務執行時通過x86記憶體段和頁面保護的組合來防止不受信任的程式碼進行不適當的記憶體訪問。

載入NaCl模組時,將其置於服務執行時地址空間內的分段隔離256MB區域中。 NaCl模組的第一個64 KB的地址空間(NaCl“使用者”地址空間)保留用於服務執行時的初始化。前4 KB是讀防寫的,用於檢測NULL指標。剩餘的60 KB包含可信程式碼,用於實現我們的“蹦床”呼叫門和“跳板”返回門。在此64 KB區域之後立即載入不受信任的NaCl模組文字。 %cs段設定為約束從零基礎到NaCl模組文字末尾的控制轉移。其他段暫存器設定為限制對256 MB NaCl模組地址空間的資料訪問。
因為它源自受信​​任的服務執行時並由受信任的服務執行時安裝,所以允許trampoline和跳板程式碼包含在不受信任的可執行文字中禁止其他地方的指令。該程式碼在執行時作為NaCl模組載入過程的一部分進行修補,使用段暫存器操作指令和far call指令來啟用不可信使用者程式碼和可信服務執行時程式碼之間的控制傳輸。由於NaCl使用者空間的前64 KB中的每個0 mod 32地址都是潛在的計算控制流目標,因此這些是我們的系統呼叫"蹦床"表的入口點。其中一個入口點被hlt指令阻塞,因此剩餘空間可用於只能從服務執行時呼叫的程式碼。這為跳板返回門提供了空間。

呼叫trampoline將控制從不可信程式碼轉移到可信程式碼。 trampoline序列重置%ds然後使用far call重置%cs段暫存器並將控制轉移到可信服務處理程式,重新建立服務執行時程式碼所期望的傳統平面定址模型。一旦超出NaCl使用者地址空間,它將重置其他段暫存器,如%fs%gs%ss,以重新建立本機程式碼執行緒環境,完全禁用此執行緒的內部沙箱,並載入堆疊暫存器%esp,包含可信堆疊的位置,供服務執行時使用。請注意,每執行緒可信堆疊位於不受信任的地址空間之外,以防止其受到不受信任的NaCl模組中其他執行緒的攻擊。
就像"蹦床"允許從不信任程式碼到可信程式碼一樣,"跳板"允許在另一個方向上交叉。"跳板"由可信執行時使用

  • 將控制權轉移到任意不受信任的地址,
  • 啟動一個新的POSIX風格的執行緒,和
  • 啟動主執行緒。

對齊確保不能通過不受信任的程式碼直接呼叫跳板。跳轉到任意不受信任的地址的能力用於從服務呼叫返回。從trampoline呼叫返回需要從堆疊頂部彈出未使用的trampoline返回地址,恢復段暫存器,最後對齊並跳轉到NaCl模組中的返回地址。

在這裡插入圖片描述

上圖顯示了“null”系統呼叫的開銷。 156ns的Linux開銷略高於Linux 2.6 getpid系統呼叫時間,在相同的硬體上,為138 ns(通過vsyscall表並使用sysenter指令實現)。我們注意到使用者/核心傳輸在x86架構的整個生命週期中不斷髮展。相比之下,NaCl蹦床使用的段暫存器操作和“遠端呼叫”稍微不那麼常見,並且可能對x86架構的歷史記錄的考慮較少。

3.4 通訊IMC

在這裡插入圖片描述

IMC是進出NaCl模組的通訊基礎。該實現圍繞一個NaCl套接字構建,提供類似於Unix域套接字的雙向,可靠,有序資料報服務[37]。不可信的NaCl模組在建立時接收其第一個NaCl插槽,可通過用於建立它的Document-Object Model物件從JavaScript訪問。 JavaScript使用套接字將訊息傳送到NaCl模組,也可以與其他NaCl模組共享。 JavaScript還可以通過開啟和共享NaCl套接字作為NaCl描述符來選擇將模組連線到其可用的其他服務。 NaCl描述符也可用於建立共享記憶體段。

在這裡插入圖片描述

使用NaCl訊息,NC的SRPC抽象完全在不受信任的程式碼中實現。 SRPC提供了一種方便的語法,用於宣告JavaScript和NaCl模組之間或兩個NaCl模組之間的過程介面,支援一些基本型別(int,float,char)以及除NaCl描述符之外的陣列。不支援更復雜的型別和指標。諸如XDR [18]或協議緩衝器[26]之類的外部資料表示策略可以很容易地在NaCl訊息或SRPC之上分層。
我們的NPAPI實現也在IMC之上分層,並支援公共NPAPI介面的子集。形成當前實現的特定要求是能夠讀取,修改和呼叫瀏覽器中指令碼物件的屬性和方法,支援簡單的光柵圖形,提供 createArray()方法以及開啟和使用URL等功能檔案描述符。選擇當前實施的NPAPI子集主要是為了方便,但我們可能會進一步限制和擴充套件它,因為我們會提高對相關安全考慮因素和應用程式要求的理解。

3.5 開發者工具

3.5.1 建立NaCl模組

我們修改了標準GNU工具鏈,使用gcc編譯器[22],[29]和binutils [2.1] 2.18版本的4.2.2版生成符合NaCl標準的二進位制檔案。我們使用生成的工具鏈從newlib2構建了一個引用二進位制檔案,重新託管使用NaCl蹦床來實現系統服務(例如,read()brk()gettimeofday()imc sendmsg())。 NC支援不安全的“除錯”模式,該模式允許額外的檔案系統互動,否則不允許安全程式碼。
我們通過將函式條目(-falign-functions)的對齊方式更改為32個位元組並將目標分支(-falign-jumps)的對齊方式更改為32個位元組來修改本機客戶端的gcc。我們還改變了gcc以使用nacljmp進行間接控制傳輸,包括間接呼叫和所有返回。我們對彙編程式進行了更重要的更改,以實現NC的塊對齊要求。為了實現返回,彙編程式確保呼叫指令始終出現在32位元組塊的最後位元組中。我們還修改了彙編程式,通過將nacljmp偽指令擴充套件為正確對齊的連續位元組塊來實現間接控制傳輸序列。為了便於測試,我們增加了對使用更長的nacljmp序列的支援,對齊文字庫,並使用和或使用重定位作為掩碼。這允許通過在命令列上執行它們來測試應用程式,並且已經用於執行整個gcc C/C++ 測試套件。我們還更改了連結器以根據NaCl載入程式(今天為64K)的要求設定影象的基址。
除了直接使用之外,工具鏈還用於通過示例記錄如何修改現有工具鏈以生成NaCl模組。這些更改是通過在gcc和binutils中修補不到1000行來實現的,這證明了將編譯器移植到 NC 的簡單性。

3.5.2 分析和除錯

NC 的開源版本包括一個簡單的分析框架,用於以最小的效能開銷捕獲完整的呼叫跟蹤。這種支援基於gcc的-finstrument-functions程式碼生成選項與rdtsc時序指令相結合。此分析器是可移植的,完全以不受信任的程式碼實現。根據我們的經驗,在此框架中分析的優化構建的效能介於-O0和-O2之間。可選地,應用程式設計師可以使用類似於printf的方法來註釋探查器輸出,其中輸出出現在跟蹤而不是stdout中。

NC 目前不支援NaCl二進位制模組的互動式除錯。通常我們通過使用標準工具和將所有介面匯出到NaCl服務執行時的庫來除錯NaCl模組原始碼,允許我們從相同的源構建除錯和NaCl模組。隨著時間的推移,我們希望改進對釋放NaCl二進位制檔案的互動式除錯的支援。

此處有刪節

6.相關工作

安全執行第三方程式碼的技術通常分為三類:系統請求稽核,故障隔離(包括虛擬化)和信任與身份驗證。

6.1 系統請求稽核

基於核心的機制,如基於使用者ID的訪問控制,systrace [50]和ptrace [60],是類Unix系統中常見的工具。許多以前的專案已探索使用這些機制來包含不受信任的程式碼[24],[33],[34],[36],[52],最近的Android [9],[27]來自Google和Xax [17]來自Microsoft調研。 Android使用沙箱執行第三方應用程式。每個Android應用程式作為不同的Linux使用者執行,並且包含系統將系統呼叫活動劃分為許可權組,例如“網路通訊”和“您的個人資訊”。在安裝第三方應用程式之前,需要使用者確認所需的許可權。使用者分離固有地否認了潛在有用的相互通訊。為了提供相互通訊,Android在Binder程序間通訊機制,Intent sytem和ContentProvider資料訪問模型之上形成了一個許可權模型。 [9]
Xax可能是目標方面與NC最相似的工作,儘管它們的實現方法完全不同,使用基於Linux上的ptrace和Windows上的核心裝置驅動程式的系統呼叫攔截。我們在工作的早期就​​考慮過這種基於核心的方法,但由於擔心可支援性而將其視為不切實際。特別要注意的是,Xax Windows實現需要一個核心模式裝置驅動程式,必須針對每個支援的Windows版本進行更新,即使作業系統供應商自己實現,我們也會想到這個計劃。在xtra沒有解決的ptrace包含6中存在已知缺陷。雖然Xax的作者確實在他們的論文中認識到了這樣一個問題,但是在Mitre的常見漏洞和暴露網站7中進行簡單搜尋可以記錄41個與ptrace相關的不同問題。由於其純粹的使用者空間內部沙箱,NC不易受到這些困難的核心問題的影響。 Xax還容易受到基於x86勘誤表的拒絕服務攻擊,這種攻擊可能導致計算機掛起或重啟[31],[38]。因為NC檢查每個指令並拒絕模組,並且發現它發現可疑的指令,所以它顯著減少了無效指令的攻擊面,並且還包括相關機制,以便在發現它們時防禦新攻擊。
由於Xax沙箱在程序邊界處起作用,因此當作業系統非自願地注入共享應用程式元件(如DLL)時,它無法隔離不受信任的程式碼,這是安全性和不可信程式碼的可移植性的問題。相反,NC內部沙箱在本機作業系統程序中建立安全子域。除了這些安全性差異之外,我們注意到Xax不支援執行緒,考慮到多核CPU的趨勢,我們認為這是必不可少的。
Linux seccomp8工具還限制系統呼叫介面上的Linux程序,允許程序進入只允許exit()read()write()系統呼叫的模式。

6.2 故障隔離

NC應用了研究文獻中廣泛討論的軟體故障隔離和攜帶證明程式碼的概念。我們的資料完整性方案是英特爾80386 [14]中實現的分段儲存器的簡單應用。我們目前的控制流完整性技術建立在Wahbe,Lucco,Anderson和Graham [62]的開創性工作之上。與Wahbe等人一樣,NC直接在本機機器指令中表達沙盒約束,而不是使用虛擬機器或其他ISA行動式表示。 NC利用McCamant和Morrisett [40]首先描述的幾種技術,利用特定機制擴充套件了之前的工作,以實現x86 [4],[14],[32] ring-3指令集架構(ISA)的安全性。NC使用靜態驗證器而不是可信編譯器,類似於為其他系統描述的驗證器[19],[40],[41],[49],應用了攜帶證明程式碼的概念[46]。
在Wahbe等人推廣軟體故障隔離概念之後,研究人員描述了互補和替代系統。一些[1],[19],[40],[41],

[49],[56]直接使用x86機器程式碼。其他基於中間程式表示,如型別安全語言[28],[45],[47],[59],抽象虛擬機器[3],[20],[21],[39],或編譯器中間表示[53]。它們使用行動式表示,允許ISA可移植性,但通過直接使用機器程式碼來建立我們避免的效能障礙。在機器程式碼中直接表示沙盒的另一個優點是它不需要可信賴的編譯器。這大大減小了可信計算庫的大小[61],並且不需要來自編譯器的加密簽名。除了簡化安全實現之外,NC還可以將系統開啟到第三方工具鏈。
與NC相比,CFI [1]提供了更細粒度的控制流完整性。雖然我們的系統僅保證間接控制流將針對文字段中的對齊地址,但CFI可以將特定控制轉移限制為相當任意的已知目標子集。雖然這種更精確的控制在某些情況下可能是有用的,例如確保從高階語言翻譯的完整性,但它對NC沒有用,因為我們打算允許相當任意的控制流,甚至是手工編碼的彙編程式,如執行仍然在已知文字中並且目標是對齊的。與此同時,CFI開銷平均高出三倍(在SPEC2000上為15%對比5%),這並不奇怪,因為它的儀器序列比NC的長度要長得多,無論是在尺寸還是指令數量方面。 XFI [19]將資料沙箱新增到CFI控制流檢查中,並增加了額外的開銷。相比之下,NC可以從x86段免費獲取資料完整性。
最近的其他系統已經探索了通過測量信任來實現安全副作用的機制。 NaCl資源描述符類似於EROS等系統中的能力[55]。奇點渠道[30]起著類似的作用。 DTrace [11],Systemtap [49]和XFI [19]都有相關的機制。
許多專案已經探索過隔離不受信任的核心擴充套件。 SPIN和VINO採用不同的方法來實現安全性。 SPIN選擇了一種型別安全的語言Modula-3 [47]和一個可信賴的編譯器工具鏈來實現擴充套件。與NC和Wahbe等人的原創作品一樣,VINO使用基於機器指令沙箱的軟體故障隔離。與NC一樣,VINO使用修改後的編譯工具鏈將沙盒指令新增到x86機器程式碼中,使用C ++實現擴充套件。與NC不同,VINO沒有二進位制驗證器,依賴於可信賴的編譯器。我們注意到VINO的驗證器比NC更難,因為它的驗證器必須強制執行資料引用完整性,在具有80386段的NC中實現。
Nooks系統[58]通過使用稱為Nooks Isolation Manager(NIM)的透明OS層將可信核心程式碼與不可信裝置驅動程式模組隔離,從而增強了作業系統核心的可靠性。與NC一樣,NIM使用記憶體保護來隔離不受信任的模組。由於NIM在核心中執行,因此x86段不可用。 NIM使用每個擴充套件模組的專用頁表。要更改保護域,NIM會更新x86頁表基址,該操作具有重新整理x86轉換後備緩衝區(TLB)的副作用。通過這種方式,NIM使用頁表提示了NC使用的段保護的替代方法。雖然對這兩種方法的效能分析可能會暴露出有趣的差異,但這種比較在x86上沒有實際意義,因為一種機制只能在核心中使用,而另一種機制只能在核心之外使用。 Nooks和NC之間的一個重要區別是Nooks的設計只是為了防止意外錯誤,而不是濫用。相比之下,NC必須能夠抵制未經嘗試的故意濫用,強制要求我們的機制進行可靠的x86反彙編和控制流完整性。這些機制在Nooks中沒有模擬。
有許多基於虛擬機器架構的環境提供安全執行和一些本機效能[3],[6],[7],[20],[28],[39],[53],[ 63]。雖然我們認識到這些系統提供了出色的故障隔離功能,但我們在NC中對虛擬化進行了深思熟慮的選擇,因為它通常與我們的作業系統中立性,瀏覽器中立性和最高本機效能目標不一致或無關。
最近,核心擴充套件已用於作業系統監視。 DTrace [11]將一個VM直譯器整合到Solaris核心中以便安全執行,並提供了一組核心檢測點和輸出設施,類似於NC的安全副作用。 Systemtap [49]提供與DTrace類似的功能,但使用x86本機程式碼進行擴充套件而不是VM中的解釋語言。

6.3 信任身份驗證

也許在Web內容中使用本機程式碼的最流行的例子是Microsoft的ActiveX [15]。 ActiveX控制元件依賴於信任模型來提供安全性,控制元件使用Microsoft專有的Authenticode系統進行加密簽名[43],並且只有在使用者表明他們信任釋出者時才允許執行。通常利用這種對做出謹慎信任決策的使用者的依賴。 ActiveX不能保證可信控制是安全的,即使控制元件本身不是惡意的,控制中的缺陷也可以被利用,通常允許執行任意程式碼。為了緩解這個問題,微軟維護了一個被認為不安全的黑名單[42]。相比之下,NC旨在防止此類攻擊,即使對於有缺陷的NaCl模組也是如此。

7 結論

本文介紹了NC,這是一個將不受信任的x86本機程式碼合併到Web瀏覽器中執行的應用程式的系統。除了建立防止不良副作用的屏障外,NaCl模組還可跨作業系統和Web瀏覽器移植,並支援面向效能的功能,如執行緒和向量化指令。我們相信NaCl內沙箱非常堅固;無論我們提供額外的冗餘機制來提供縱深防禦。
根據我們的經驗,我們發現將現有的 Linux/gcc 程式碼移植到NC非常簡單,並且沙箱的效能損失很小,特別是在系統設計的計算限制方案中。
通過在這裡描述NC並將其作為開源提供,我們希望鼓勵社群審查和貢獻。我們相信這些反饋以及我們的持續努力將使我們能夠建立一個比以前的原生程式碼網路技術實現更高安全性的系統。

此處有刪節

玩~