保護模式下的特權級檢查 (轉)

worldblog發表於2007-12-14
保護模式下的特權級檢查 (轉)[@more@]

下面是一些關於特權級轉換的說明,其中重點介紹特權級轉換時的檢查,類似於變換特權時的堆疊切換,任務切換過程和任務的巢狀等未加說明,可參閱有關專著.段內轉移和實下一樣,不涉及特權級的轉換和任務間的切換,所以重點說一說任務內段間的轉移和任務間的轉移.

任務內相同特權級的轉移:
段間直接轉移和段間直接:
 1.檢查目標地址指標內的選擇子指示的描述符是否為空,目的碼段描述符不能為空描述符,即該選擇子的高14位不能為0
 2.由選擇子內的TI位(第2位)決定是從GDT還是從LDT中讀出目的碼段的描述符
 3.檢查描述符型別是否正確
 4.普通程式碼段,要求CPL=DPL,RPL<=DPL;一致程式碼段,要求CPL>=CPL
 5.目的碼段描述符中的P位必須為1
 6.把目的碼段描述符中的段基址、段限、屬性裝入CS的高速緩衝暫存器中
 7.檢查目標地址的偏移是否越過目的碼段的段界限,這也是不允許的,即目標地址的偏移不允許越過該程式碼段
 8.裝入指令指標暫存器EIP,並把CPL裝入CS內的RPL欄位
 
  任務內相同特權級的轉移途徑: 任務內相同特權級的轉移可用段間直接或間接轉移指令JMP和段間直接或間接呼叫指令CALL、段間返回指令RET、中斷指令INT、中斷返回指令IRET.其中利用段間接轉移指令JMP和段間呼叫指令CALL的任務內相同特權級的轉移是指用到了呼叫門.

任務內不同特權級的轉移:
任務內不同特權級的轉移分為向內層轉移和向外層轉移
透過呼叫門(下面的都是指間接轉移):
一.向內層轉移:
 1.首先要檢查呼叫門,必須符合CPL<=DPL,RPL<=DPL
 2.檢查目標地址指標內的選擇子指示的描述符是否為空,目的碼段描述符不能為空描述符,即該選擇子的高14位不能為0
 3.由選擇子內的TI位(第2位)決定是從GDT還是從LDT中讀出目的碼段的描述符
 4.檢查描述符型別是否正確,調整RPL=0
 5.這裡的檢查類似於任務內相同特權級的轉移中的第4步,但這裡的DPL不是呼叫門的DPL,而是呼叫門內選擇子所指向的目的碼段描述符的DPL,因為對於段間轉移指令JMP和段間呼叫指令CALL所做的檢查不一致,所以分別加以描述:
1) 對於使用呼叫門的段間轉移指令JMP : 相同與上面的段間直接轉移和段間直接呼叫的檢查,由於RPL=0(經調整後為0),所以總是認為RPL<=DPL;所以對於普通程式碼段,CPL=DPL時,為相同特權級的轉移,對於一致程式碼段,CPL>=DPL也發生相同特權級的轉移.所以說不能用JMP指令實現任務內不同特權級的轉移.
2) 對於使用呼叫門的段間呼叫指令CALL: 同樣,由於RPL=0(經調整後為0),所以總是認為RPL<=DPL;對於一致程式碼段,當CPL>=DPL時發生相同特權級的轉移;對於普通程式碼段,當CPL=DPL時同樣是相同特權級的轉移;這兩種情況都是把原CS和EIP儲存到當前堆疊;只有當CPL>DPL時,才發生向內層的轉移,同時使CPL=DPL(很重要的一步),要切換堆疊.原CS和EIP的內容儲存在內層堆疊
 6.目的碼段描述符中的P位必須為1
 7.把目的碼段描述符中的段基址、段限、屬性裝入CS的高速緩衝暫存器中
 8.檢查目標地址的偏移是否越過目的碼段的段界限,這也是不允許的,即目標地址的偏移不允許越過該程式碼段
 9.分別裝入CS段暫存器和指令指標暫存器EIP,並把CPL裝入CS內的RPL欄位
二.向外層轉移:
 1.從堆疊中彈出返回地址,如果返回的目標地址的選擇子的RPL>CPL,即向外層轉移.
 2.越過內層堆疊中的引數從堆疊中彈出外層堆疊的指標,裝入SS和ESP.從此恢復外層堆疊
 3.調整ESP,跳過呼叫之前壓入的引數.
 4.檢查資料段暫存器DS、ES、FS和GS,保證定址的段在外層是可訪問的,否則裝入一個空選擇子.
 5.返回繼續
  如果是相同特權級的轉移,只有第1、5步;如果RET指令不帶立即數,只有第1、4、5步
 
  任務內不同特權級的轉移途徑:段間呼叫指令CALL透過呼叫門實現從外層到內層的轉移,段間返回指令RET實現內層到外層的轉移.

  致此,任務內轉移就結束了,下面是任務間的轉移.

任務切換:
  實際上任務的切換是比較麻煩的,但慶幸的是對於它的特權級檢查卻比較簡單:
一.直接用TSS進行任務切換
  採用訪問資料段相同的特權級檢查規則:訪問TSS段描述符的CPL必須小於等於TSS段描述符的DPL,並且指示TSS段描述符的選擇子的RPL必須小於等於TSS段描述符的DPL.
二.用任務門進行任務切換
  也是採用訪問資料段相同的特權級規則:訪問任務門的CPL必須小於等於任務門的DPL,並且指示任務門的選擇子的RPL必須小於等於任務門的DPL,同時還要求任務門內的選擇子必須指示GDT中的可用TSS段描述符(任務門的偏移丟棄不要).

訪問資料段時的檢查:

1.選擇子不能為空

2.選擇子指示的描述符只能是資料段描述符和可讀可執行的程式碼段或一致程式碼段的描述符

3.對於資料段描述符和可讀可執行的程式碼段描述符,需檢查CPL<=DPL,RPL<=DPL

4.選擇子所指示的段必須存在

訪問堆疊段時的檢查:

1.選擇子不能為空

2.選擇子所指示的描述符必須是可讀可寫的資料段描述符

3.在此要求RPL=CPL=DPL,即每一個特權級下都有自己獨立的堆疊段,以實現隔離保護

4.選擇子所指示的段必須存在


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993092/,如需轉載,請註明出處,否則將追究法律責任。

相關文章