操作系統(tǒng)/虛擬化安全知識域:內(nèi)存保護和地址空間
內(nèi)存保護和地址空間
僅當(dāng)安全域彼此隔離時,訪問控制才有意義。為此,我們需要根據(jù)訪問權(quán)限和能夠授予或撤銷此類訪問權(quán)限的特權(quán)實體分離安全域的數(shù)據(jù)。我們將首先查看隔離,稍后在引入保護環(huán)時討論特權(quán)。
一個進程通常不應(yīng)該能夠在不經(jīng)過適當(dāng)?shù)脑L問控制檢查的情況下讀取另一個進程的數(shù)據(jù)。Multics和幾乎所有隨后的操作系統(tǒng)(如UNIX和Windows)通過為每個進程提供信息來隔離進程中的信息
(一)它自己的處理器狀態(tài)(寄存器、程序計數(shù)器等)以及(b)它自己的內(nèi)存子集。每當(dāng)操作系統(tǒng)決定以犧牲當(dāng)前正在運行的進程P1(所謂的上下文切換)為代價來執(zhí)行進程P2時,它首先停止P1和將其所有處理器狀態(tài)保存在內(nèi)存中其他進程無法訪問的區(qū)域。接下來,它將P2的處理器狀態(tài)從內(nèi)存加載到CPU中,調(diào)整確定物理內(nèi)存的哪些部分可訪問的簿記,并開始在程序計數(shù)器指示的地址執(zhí)行P2,它剛剛作為處理器狀態(tài)的一部分加載。由于用戶進程不能直接操作簿記本身,因此P2無法以非中介形式訪問P1的任何數(shù)據(jù)。
大多數(shù)現(xiàn)代操作系統(tǒng)通過頁表跟蹤內(nèi)存簿記,如圖所示。2.對于每個進程,它們維護一組頁表(通常包含組織為有向無環(huán)圖6的多個級別),并將指向頂級頁表的指針存儲在寄存器中,該寄存器是處理器狀態(tài)的一部分,必須在上下文切換上保存和恢復(fù)。
頁表結(jié)構(gòu)的主要用途是為每個進程提供自己的虛擬地址空間,范圍從地址0到某個最大地址(例如,248),即使物理內(nèi)存量可能要少得多。由于兩個進程都可以在地址0x10000存儲數(shù)據(jù),但不應(yīng)該允許訪問彼此的數(shù)據(jù),因此必須有一個來自虛擬的映射。每個進程使用的地址到硬件使用的物理地址。這就像一場籃球比賽,每方可能有一個數(shù)字為23的球員,但這個數(shù)字被映射到每個球員的不同身體球員身上。團隊。
這就是頁表的用武之地。我們將每個虛擬地址空間劃分為固定大小的頁面,并使用頁表結(jié)構(gòu)將虛擬頁面的第一個字節(jié)的地址映射到物理地址。處理器通常使用多個級別的轉(zhuǎn)換。在圖例中。2、它使用虛擬地址的前九位作為頂層頁表中的索引(由作為處理器狀態(tài)一部分的控制寄存器指示)來查找包含下一級頁表物理地址的條目,該條目由接下來的九位索引,依此類推,直到我們到達(dá)最后一級頁表,其中包含包含虛擬地址的物理頁面的物理地址。虛擬地址的最后12位只是此頁面中的偏移量,并指向數(shù)據(jù)。
分頁允許進程的虛擬地址空間的(總)大小遠(yuǎn)大于系統(tǒng)中可用的物理內(nèi)存。首先,進程通常不會使用其所有可能的巨大地址空間,只有實際使用的虛擬頁面需要物理頁面的支持。其次,如果一個進程需要更多的內(nèi)存來存儲一些數(shù)據(jù),并且此時沒有可用的物理頁面(例如,因為它們已經(jīng)被其他進程使用,或者他們正在支持此過程的其他一些虛擬頁面),操作系統(tǒng)可能會將這些頁面的內(nèi)容交換到磁盤,然后重新使用物理頁面來存儲新數(shù)據(jù)。
圖2:現(xiàn)代處理器中的地址轉(zhuǎn)換。MMU“遍歷”頁表以查找頁面的物理地址。僅當(dāng)頁面“映射”在進程的頁表上時,進程才能解決它,假設(shè)它存在并且進程具有適當(dāng)?shù)脑L問權(quán)限權(quán)利。具體而言,用戶進程無法訪問在頁表條目中為其設(shè)置了主管(S)位的頁。
這種組織的一個關(guān)鍵結(jié)果是,如果進程的頁表中存在映射,則進程只能訪問內(nèi)存中的數(shù)據(jù)。是否是這種情況,由操作系統(tǒng)控制,因此,操作系統(tǒng)能夠準(zhǔn)確決定哪些內(nèi)存應(yīng)該是私有的,哪些內(nèi)存應(yīng)該共享,并且和誰在一起。保護本身由稱為內(nèi)存管理單元(MMU7)的專用硬件實施。如果特定地址的虛擬到物理的映射不在稱為事務(wù)后備緩沖區(qū)(TLB)的小型但非常快速的緩存中,則MMU將通過遍歷頁表來查找它,然后在包含地址的頁面未映射時觸發(fā)中斷。
如果頁面當(dāng)前不在內(nèi)存中(交換到磁盤),或者與安全性更相關(guān)的用戶沒有訪問此內(nèi)存所需的權(quán)限,MMU也會觸發(fā)中斷。具體來說,頁表條目(PTE)的最后12位包含一組標(biāo)志和其中一個標(biāo)志,即圖中的S位。2,指示這是主管代碼(例如,以最高權(quán)限運行的操作系統(tǒng))還是普通用戶進程的頁面。我們稍后會詳細(xì)介紹特權(quán)。
頁表是現(xiàn)代操作系統(tǒng)控制內(nèi)存訪問的主要方式。但是,一些(主要是較舊的)操作系統(tǒng)還使用另一個技巧:分段。毫不奇怪,最早同時使用分段和分頁的操作系統(tǒng)之一是Multics。與頁面不同,段具有任意長度,并從任意地址開始。但是,兩者都取決于硬件支持:MMU。例如,英特爾的32位x86等處理器具有一組稱為段選擇器的專用寄存器:一個用于代碼,一個用于數(shù)據(jù)等。每個段都有特定的權(quán)限,例如讀取、寫入或執(zhí)行。給定一個虛擬地址,MMU使用相應(yīng)段選擇器中的當(dāng)前值作為所謂的描述符表中的索引。描述符表中的條目包含段的起始地址和長度,以及保護位,以防止代碼沒有必需訪問它的權(quán)限級別。如果只有分段而沒有分頁,則生成的地址是添加到分段開頭的原始虛擬地址,這將是物理地址,我們就完成了。但是,用于Multics的GE-645大型計算機和更現(xiàn)代的x86-32都允許將分段和分頁結(jié)合起來。在這種情況下,首先使用段描述符表將虛擬地址轉(zhuǎn)換為所謂的線性地址,然后該線性地址使用頁表結(jié)構(gòu)轉(zhuǎn)換為物理地址。
這聽起來很復(fù)雜;沒有一個流行的現(xiàn)代操作系統(tǒng)仍然使用分段。使用分段的操作系統(tǒng)最著名的例子是OS/2(微軟和IBM之間命運多舛的合作,始于1980年代中期,從未流行過)和IBM的AS/400(也是在1980年代推出的8,今天仍然在您附近的大型機上愉快地運行)。Xen虛擬機管理程序也在32位x86上使用分段,但在64位系統(tǒng)上不再可能。實際上,英特爾x64的66位版本甚至不再支持完全分段,盡管其功能仍然存在一些痕跡。另一方面,復(fù)雜的多級地址轉(zhuǎn)換在虛擬化環(huán)境中仍然很常見。在這里,虛擬機管理程序試圖給虛擬機一種錯覺,即它們都在真實硬件上自行運行,因此MMU首先將虛擬地址轉(zhuǎn)換為稱為來賓物理地址(使用頁表)。但是,這還不是一個真正的物理地址,因為許多虛擬機可能具有使用物理地址0x10000的相同想法。因此,MMU使用第二個轉(zhuǎn)換階段(使用Intel所說的擴展頁表,由虛擬機管理程序維護)將來賓物理地址轉(zhuǎn)換為主機物理地址(“機器地址”)。