Linux從頭學(xué)12:讀完這篇【特權(quán)級】文章,你就比別人更“精通”操作系統(tǒng)!
作 者:道哥,10 年的嵌入式開發(fā)老兵,專注于:C/C 、嵌入式、Linux。目錄關(guān)注下方公眾號,回復(fù)【書籍】,獲取 Linux、嵌入式領(lǐng)域經(jīng)典書籍;回復(fù)【PDF】,獲取所有原創(chuàng)文章( PDF 格式)。
-
CPL:當(dāng)前特權(quán)級
-
DPL:描述符特權(quán)級
-
RPL:請求者特權(quán)級
-
特權(quán)級檢查規(guī)則
-
代碼段的檢查規(guī)則
-
數(shù)據(jù)段的檢查規(guī)則
-
棧段的檢查規(guī)則
-
理解了這3個特權(quán)級的保護規(guī)則,就理解了操作系統(tǒng)保護系統(tǒng)的終極密碼!
- CPL: Current Privilege Level 當(dāng)前特權(quán)級;
- DPL: Descriptor Privilege Level 描述符特權(quán)級;
- RPL: Requestor Privilege Level 請求特權(quán)級;
CPL:當(dāng)前特權(quán)級
當(dāng)前特權(quán)級,是指當(dāng)前正在執(zhí)行的代碼的特權(quán)級別,它由當(dāng)前正在執(zhí)行的代碼段寄存器cs中的bit[1 ~ 0]來決定:
當(dāng)處理器進行一系列權(quán)限檢查之后,允許進入這段代碼中去執(zhí)行,那么就設(shè)置cs = 0x0007。
- RPL: bit[1 ~ 0] = 11B,十進制就是 3,就表示這個選擇子的請求特權(quán)級別是 3;
- TI: bit[2] = 1B,表示到 LDT 中查找段描述符;
- 索引號:bit[15 ~ 3] 的索引值為 0,表示到 LDT 中偏移量為 0 (0 = 0 * 4, 每個描述符占據(jù) 4 個字節(jié)) 的位置獲取段描述符;
DPL:描述符特權(quán)級
DPL指的是一個段描述符中,用來指定這個描述符所代表的段,具有什么樣的特權(quán)級別。
具體的比較規(guī)則,下文有描述。
RPL:請求者特權(quán)級
剛才的CPL內(nèi)容中,已經(jīng)描述了RPL是什么東西,它倆是密切相關(guān)的。
索引號:1;也就是說:當(dāng)操作系統(tǒng)接受用戶程序的請求之后,開始執(zhí)行系統(tǒng)函數(shù)時,此時的CPL是操作系統(tǒng)的特權(quán)級別0。TI: 使用 LDT;
RPL: 3;
其實這里有一個隱患:
- 用戶程序的數(shù)據(jù)段 DPL 一定是 3,這是由操作系統(tǒng)在加載程序之初就決定好的;
- 根據(jù)下文的特權(quán)級檢查規(guī)則,這樣的訪問是允許的;
索引號:2(假設(shè)通過其它途徑,知道操作系統(tǒng)的某個數(shù)據(jù)段位于 GDT 的第 2 個表項);此時,如果操作系統(tǒng)很無腦的就原樣接收了用戶程序的調(diào)用請求,就會通過GDT找到屬于操作系統(tǒng)的數(shù)據(jù)段進行破壞性操作。TI: 使用 GDT;
RPL: 0;
特權(quán)級檢查規(guī)則
代碼段的特權(quán)級檢查
一般情況下,只允許兩個特權(quán)級相同的代碼段進行轉(zhuǎn)移。
但是處理器也提供了一些特殊途徑,讓低特權(quán)級的代碼可以轉(zhuǎn)移到高特權(quán)級的代碼中去執(zhí)行:
- 從用戶程序的一個代碼段(CPL = 3),跳轉(zhuǎn)到另一個 DPL = 3 的代碼段;
- 從操作系統(tǒng)的一個代碼段(CPL = 0),跳轉(zhuǎn)到另一個 DPL = 0 的代碼段;
這里主要描述第一種情況,也就是當(dāng)目標(biāo)代碼段描述符的TYPE字段中C = 1,也就是所謂的依從代碼,或者一致性代碼。
- 如果在高特權(quán)級代碼段描述中的 TYPE 字段中,C = 1,就允許低特權(quán)級的代碼轉(zhuǎn)移進來;
- 通過調(diào)用門,低特權(quán)級代碼也可以轉(zhuǎn)移到高特權(quán)級的代碼段;
CPL >= DPL例如:操作系統(tǒng)中有2個代碼段,它們的描述符中的C標(biāo)志位不同:RPL >= DPL
CPL == DPL最后還有一點需要記?。?span>高特權(quán)級的代碼,永遠都不能轉(zhuǎn)移到低特權(quán)級的代碼。就好比:市長永遠都不會以村長的身份去辦事。RPL == DPL
數(shù)據(jù)段的特權(quán)級檢查
數(shù)據(jù)段的特權(quán)級檢查規(guī)則比較簡單:高特權(quán)級的程序,可以訪問低特權(quán)級的數(shù)據(jù),反之不可以。
CPL <= DPLRPL <= DPL
棧段的特權(quán)級檢查
棧段的特權(quán)級檢查規(guī)則,也比較簡單,x86處理器要求當(dāng)前特權(quán)級 CPL 必須與目標(biāo)棧段的 DPL 相同。
CPL == DPL為了滿足這個要求,當(dāng)從用戶程序(CPL = 3)轉(zhuǎn)移到操作系統(tǒng)(DPL = 0)時,如果是通過依存(一致性)代碼段轉(zhuǎn)移進去,當(dāng)前特權(quán)級是不變的,此時使用的棧仍然是用戶程序的??臻g。RPL == DPL
------ End ------
這篇文章主要從特權(quán)級的角度,來理解操作系統(tǒng)對系統(tǒng)的保護。