天天看點

RPL的故事 ——《x86彙編語言:從實模式到保護模式》讀書筆記311. 通路資料段時的特權級檢查2. 為什麼要引入RPL3. RPL的值是怎麼來的4. ARPL指令5. 火眼金睛的作業系統

關于RPL(請求特權級),網上的資料不少,不過我認為都沒有說明白。希望我可以把這個問題講清楚,如有纰缪,還請您不吝賜教。

要了解RPL,首先要明白通路資料段時的特權級檢查規則。

1. 通路資料段時的特權級檢查

為了通路資料段,資料段的選擇子必須被加載進段寄存器(

DS,ES,FS,GS,SS

)。在把一個段選擇子加載進段寄存器之前,處理器會進行特權級檢查(如下圖所示)。

RPL的故事 ——《x86彙編語言:從實模式到保護模式》讀書筆記311. 通路資料段時的特權級檢查2. 為什麼要引入RPL3. RPL的值是怎麼來的4. ARPL指令5. 火眼金睛的作業系統

在數值上必須滿足以下兩點:

1. CPL<=資料段描述符的DPL

2. RPL<=資料段描述符的DPL

否則,會産生一個一般保護異常,且不加載段選擇子。

2. 為什麼要引入RPL

2.1 概述

當低特權級的應用程式使用

call far

指令通過調用門将控制轉移到較高特權級的非一緻代碼段(例如作業系統提供的例程,假設其代碼段的DPL=0)時,會改變目前的特權級,而在目标代碼段的特權級上執行,對于本例來說CPL的數值就會變成作業系統例程段的DPL的數值,即0。如果沒有RPL,那麼此時CPL權限是最高的,也就可以去通路任何資料,這就不安全了。是以引入RPL,讓它代表通路權限,是以在檢查CPL的同時,也會檢查RPL(正如上文第一節提到的規則)。一般來說如果RPL的數值比CPL大(權限比CPL的低),那麼RPL會起決定性作用。

2.2 狡猾的應用程式開發者

舉個例子,比如作業系統提供了一個調用門(這個門對應的目标代碼段的DPL為0),其功能是讀取硬碟的一個扇區到指定的記憶體位置。這個調用門有3個參數(通過棧來傳遞),分别是邏輯扇區号、資料段選擇子和段内的偏移。

假設有個應用程式(運作在特權級3)的開發者,通過苦心鑽研知道了作業系統資料段的選擇子(其指向的資料段的特權級為0),為了搞破壞,他把這個選擇子作為參數傳給了調用門。如果沒有RPL,那麼通路資料段的檢查規則就是“CPL<=資料段描述符的DPL”。當通過調用門轉移後,CPL從3變成了目标代碼段的特權級0,正好符合檢查規則,于是他的陰謀得逞了。

2.3 善變的CPL

仔細分析這個問題,根源在于CPL變了,搖身一變變成目标代碼段的特權級了。是以引入RPL,讓RPL代表“真實”的CPL,并且再加上一條規則“RPL<=資料段描述符的DPL”,因為RPL=3,是以檢查不會通過。

3. RPL的值是怎麼來的

你可能會問,那RPL的值是怎麼得來的?難道CPU可以智能識别出CPL變身了,然後自動把CPL變身前的值傳遞給RPL?

不不不,CPU可沒有這麼厲害。關于這個問題,我先告訴你一個好消息:RPL的值可以由目前程序随便寫。就是上文圖中的那個黃色字段,你愛填多少填多少。

這下你樂了吧:)既然随便寫,那我寫0好了。這樣一來,“RPL<=資料段描述符的DPL”總是成立的。

但是别高興,我還要宣布一條壞消息:作業系統會檢查RPL的值,如果你填寫的RPL在數值上小于CPL(調用者的特權級,而非目标代碼段的特權級),那麼作業系統會把RPL打回原形,強制它等于CPL。

4. ARPL指令

為了友善作業系統得到正确的RPL值,處理器提供了

ARPL

指令。該指令的作用是調整選擇子中RPL字段的值(Adjust RPL Field of Segment Selector),其格式為

該指令比較兩個選擇子的RPL字段。

目的操作數可以是一個通用寄存器(内容是16位的段選擇子)或者一個指向16位單元的記憶體位址(該16位單元存放的是段選擇子);

源操作數隻能是一個通用寄存器(内容是16位的段選擇子)。

該指令執行時,處理器檢查目的操作數的RPL字段,如果它在數值上小于源操作數的RPL字段,則設定ZF标志,并修正目的操作數的RPL字段,使其等于源操作數的RPL字段值;否則,僅僅把ZF标志清零,其他什麼也不做。

ARPL是典型的作業系統指令,通常用于調整應用程式傳遞給作業系統的段選擇子,使其RPL字段的值和應用程式的特權級相比對。

5. 火眼金睛的作業系統

結合上文2.2節的那個例子,配合下圖來說明。

為了防止惡意的資料通路,作業系統應該從目前棧中取得使用者程式的代碼段選擇子(調用者代碼段寄存器CS的内容,也就是下圖中的“原CS”)作為源操作數,并且把作為參數傳遞進來的資料段選擇子(下圖中的“參數2”)作為目的操作數,來執行

ARPL

指令,把資料段選擇子的RPL恢複到調用者的特權級别上。

RPL的故事 ——《x86彙編語言:從實模式到保護模式》讀書筆記311. 通路資料段時的特權級檢查2. 為什麼要引入RPL3. RPL的值是怎麼來的4. ARPL指令5. 火眼金睛的作業系統

一旦調整了請求特權級,那麼目前特權級CPL=0,RPL=3,資料段描述符的DPL=0,雖然符合“CPL<=資料段描述符的DPL”,但是不符合“RPL<=資料段描述符的DPL”,是以會禁止通路,并引發異常。這樣一來,狡猾的應用程式開發者的陰謀就不會得逞了。

繼續閱讀