關於CPL、RPL、DPL

保護模式中最重要的一個思想就是通過分級把代碼隔離了起來,不同的代碼在不同的級別 ,使大多數情況下都只和同級代碼發生關係。 Intel的80286以上的cpu可以識別4個特權級(或特權層),0級到3級。數值越大特權越小。一般用把系統內核放在0級,系統的其他服務程序位於1、2級,3級則是應用軟件。一般情況下代碼都在自己的級別下做自己的工作,同一級別之間可以相互訪問,而一般是不允許不同級別的代碼間隨意訪問的。但有時候不同級別的程序之間一定要訪問,比如系統的接口函數等,必須能夠使得應用程序能夠隨意調用。於是Intel將代碼分爲:

1.非一致碼:受到隔離的代碼,只能在同一級別間相互訪問

2.一致碼:不受到隔離的就是,允許被同等級或低等級代碼調用

 

至於這部分我們下回再詳細說,這裏主要搞清楚RPL、DPL、CPL之間的關係。

 

 

Intel設置DPL、RPL、CPL以實現分級和權限檢查。

 

DPL:描述符特權(Descriptor Privilege Level)

存儲在描述符中的權限位,用於描述代碼的所屬的特權等級,也就是代碼本身真正的特權級。一個程序可以使用多個段(Data,Code,Stack)也可以只用一個code段等。正常的情況下,當程序的環境建立好後,段描述符都不需要改變——當然DPL也不需要改變,因此每個段的DPL值是固定。

 

 

RPL:請求特權級RPL(Request Privilege Level)

RPL保存在選擇子的最低兩位。 RPL說明的是進程對段訪問的請求權限,意思是當前進程想要的請求權限。RPL的值由程序員自己來自由的設置,並不一定RPL>=CPL,但是當RPL<CPL時,實際起作用的就是CPL了,因爲訪問時的特權檢查是判斷:EPL=max(RPL,CPL)<=DPL是否成立,所以RPL可以看成是每次訪問時的附加限制,RPL=0時附加限制最小,RPL=3時附加限制最大。所以你不要想通過來隨便設置一個rpl來訪問一個比cpl更內層的段。

 

因爲你不可能得到比自己更高的權限,你申請的權限一定要比你實際權限低才能通過CPU的審查,才能對你放行。所以實際上RPL的作用是程序員可以把自己的程序降級運行——有些時候爲了更好的安全性,程序可以在適當的時機把自身降低權限(RPL設成更大的值)。

 

網上許多人都說在問rpl的作用,我也很暈。Intel的手冊中對RPL的作用只是這樣做的簡短解釋的:

TheRPL can be used to insure that privileged code does not access asegment on behalf of an application program unless the program itselfhas access privileges for that segment.

 

後來找到了一些資料對這段話進行了擴充和舉例,我才明白一些:

對於特權級高的進程RPL是作用是防止自己不小心訪問到一些資料段。比方說,如果進程A的CPL=0,它知道它的委託進程B的DPL=3,也知道數據段C的DPL=2,而這數據段是不能讓CPL>2的進程訪問的。

 

那麼如果你是進程A的程序員根本不需要RPL的幫助,也不會試圖讓進程A訪問數據段C的數據,因爲這樣做只會浪費時間。當然如果你一定要訪問數據段C的數據然後把數據傳給委託進程B,這就是你的選擇,你真的可以這樣做,但後果自負。只是有時候要訪問的數據段我們不知道它的DPL是怎麼,也不知道能不能讓進程B訪問,其中的一個解決方法就是把委託進程B的DPL以RPL的方法告訴數據段C讓它決定接受或不接受。(我想應該是通過程序把B的DPL裝入到A的選擇子中,然後再由A去訪問數據段C)

CPL:當前任務特權(Current Privilege Level)

表示當前正在執行的代碼所處的特權級。CPL保存在CS中的最低兩位,是針對CS而言的。當選擇子成功裝入CS寄存器後,相應的選擇子中的RPL就變成了CPL。因爲它的位置變了,已經被裝入到CS寄存器中了,所表達的意思也發生了變——原來的要求等級已經得到了滿足,就是當前自己的等級。

 

選擇子可以有許多個,因此RPL也就有許多個。而CPL就不同了,正在執行的代碼在某一時刻就只有這個值唯一的代表程序的CPL.

 

另外特別要求CS與SS的特權級必須保持一致。對於裝入DS、ES、FS、GS的選擇子INTEL沒有給它們起什麼特殊的名稱,我也不知道應該叫它們什麼,也許可以仍然稱它爲RPL。

 

 

 

應用RPL實現數據段的特權級保護的實例

 

計算機軟件一般由操作系統程序和應用程序組成。爲了組建高可靠性的軟件系統,要求操作系統的數據不允許被應用程序改變,否則,應用程序會影響系統的安全運行,嚴重時導致系統崩潰瓦解。一個由操作系統程序與應用程序組成的軟件如圖1所示。在操作系統程序中有一MOVE過程把一個數據段中的數據塊寫到另一個數據段中,MOVE過程是通過參數傳入被調用的,即 MOVE(destination,source,count)。其中:source源數據塊的邏輯地址;destination 目標數據塊的邏輯地址;count 傳送的字節數

 

 
 

 
 


 

數據塊的邏輯地址由數據段選擇字對應的數據段描述符和數據塊偏移量所描述。

 


MOVE過程是操作系統的程序,它可以合法地被操作系統中的其它過程調用,完成操作系統數據段中的數據塊移動和操作系統數據段與應用程序數據段中的數據塊移動。但是,若MOVE過程被應用程序調用,操作系統數據段的數據有可能失去保護作用。設應用程序的典型調用情形爲:

 

①MOVE(數據塊A,數據塊1,count)

②MOVE(數據塊B,數據塊A,count)

③MOVE(數據塊2,數據塊1,count)

④MOVE(數據塊1,數據塊A,count)

 

情形①:應用程序通過MOVE過程得到操作系統數據塊的信息;

情形②:應用程序利用MOVE過程完成應用程序數據塊之間的數據移動;

 

①、②這二種情形是合法的要求。

 

情形③:應用程序控制了操作系統的工作,沒有按操作系統的工作步驟,強行改變了數據塊2的內容;

情形④:應用程序將應用程序數據塊A的內容移動到操作系統數據塊1中,自行改變了數據塊1的內容;

 

在③、④這二種情形使操作系統的數據得不到核心保護,操作系統的數據受到了應用程序的侵犯。

 

 

針對上述的侵權示例,如何防止應用程序改變操作系統的數據,即情形①和②;並且,應用程序能通過調用操作系統程序中的MOVE過程合法地使用,即情形③和④;這是操作系統軟件設計中必須考慮的問題。

 

設調用MOVE過程的程序段Proc爲:

 

……

 

LDS EAX,source ;DS:EAX=source源數據塊的邏輯地址

 

PUSH DS ;壓入source源數據塊的選擇字

 

PUSH EAX ;壓入source源數據塊的偏移量

 

LDS EAX,destination ;DS:EAX=destination目標數據塊的邏輯地址

 

PUSH DS ;壓入destination目標數據塊的選擇字

 

PUSH EAX ;壓入destination目標數據塊的偏移量

 

MOV ECX,count ;ECX=傳送的字節數count

 

PUSH ECX ;壓入傳送的字節數count

 

CALL MOVE ;調用MOVE過程,MOVE由調用門描述

 

……

 

如果Proc在操作系統程序中,無論source源數據塊和destination目標數據塊屬於操作系統或應用程序,都能合法的運作。

 

如果Proc在應用程序中,有可能產生情形③和④。例如,應用程序傳入的目標數據塊選擇字的RPL=0,就意味着應用程序要對操作系統的數據段進行非法寫入。爲此,必須在MOVE過程中加以判斷,避免情形③和④的產生。

 


在MOVE過程中採用的處理方法是:目標數據塊選擇子的RPL應以主調程序的CPL爲準。即採用ARPL指令改目標數據塊選擇子的RPL爲主調程序的CPL(關於ARPL指令的使用說明見最後)。依據應用程序調用MOVE過程的堆棧,如圖2所示,在MOVE過程始部(開始)加入的指令爲:

 

MOV AX,SS:[ESP+4] ;AX=CS主調程序的代碼段選擇字

 

;其RPL字段爲主調程序的CPL

 

ARPL SS:[ESP+10],AX ;改目標數據塊選擇子的RPL爲主調程序的CPL

 

MOV ES,SS:[ESP+10] ;ES=目標數據塊選擇子(其RPL字段爲主調程序 ;的CPL)

 

……

 

進行了上述處理以後,如果應用程序傳入的目標數據塊選擇字的RPL=0,ARPL把它修改爲RPL=3,再傳送到ES段寄存器中,顯然不能滿足選擇字的裝載要求,即MAX(CPL,RPL)≤DPL,其中,MOVE過程的CPL=0;目標數據塊選擇字對應的數據段描述符中的DPL=0。CPU內部立即產生通用保護異常中斷進行處理。處理的結果通常爲:終止當前的MOVE過程操作,返回應用程序;或終止應用程序的運行,返回操作系統。從而達到了保護目的。而情形①、②,應用程序完全可以合法實現。

 

 

 

[關於ARPL指令的使用說明]

 

調整申請特權級指令: ARPL OPRD1,OPRD2

其中,操作數OPRD1可以是16位通用寄存器或存儲單元,操作數OPRD2是16位通用寄存器。該指令把操作數OPRD1和OPRD2視爲兩個選擇子,用OPRD2的RPL去檢查OPRD1的RPL。(選擇子OPRD1和OPRD2的RPL分別由它們的最低2個位規定。)

如果OPRD1的RPL值小於OPRD2的RPL值(OPRD1的特權級高於OPRD2),那麼零標誌ZF被置1,並把OPRD2的RPL值賦予OPRD1的RPL(使兩個操作數的最低2位相等);否則,零標誌ZF被清0。OPRD1和OPRD2都可爲空選擇子。該指令隻影響ZF標誌。

發佈了287 篇原創文章 · 獲贊 216 · 訪問量 175萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章