2014-08-20 53 views
15

強烈建議在創建64位內核(用於x86_64平臺)時指示編譯器不要使用用戶空間ABI執行的128字節紅色區域。 (對於GCC,編譯器標誌是-mno-red-zone)。爲什麼內核代碼不能使用紅色區域

如果內核被啓用,內核將不會中斷。

但是爲什麼呢?

+1

相關:http://stackoverflow.com/questions/38042188/where-exactly-is-the-red-zone-on-x86-64和http://stackoverflow.com/questions/37941779/why-do -we-need-stack-allocation-when-we-have-a-red-zone has answers answers that the red zone is about about for the code that can use it。 – 2016-06-26 22:24:01

回答

11

從AMD64 ABI引用:

128字節的區域以外的位置所指向的%RSP被認爲是保留的,不受信號或中斷處理程序進行修改。因此,函數可能會將此區域用於跨函數調用不需要的臨時數據。特別是,葉函數可以在整個堆棧框架中使用這個區域,而不是在序言和尾聲中調整堆棧指針。這個區域被稱爲紅色區域。

從本質上講,這是一個優化 - 用戶級編譯器知道到底有多少紅色區域在任何給定時間使用(在最簡單的實現,局部變量的整體尺寸),並可以在調用之前調整相應的%rsp一個子功能。

特別是在葉函數中,這可以產生一些性能優勢,不需要調整%rsp,因爲我們可以確定沒有不熟悉的代碼在函數中運行。 (POSIX信號處理程序可能被視爲一種協同程序的形式,但您可以指示編譯器在使用信號處理程序中的堆棧變量之前調整寄存器)。

在內核空間中,一旦開始考慮中斷,如果這些中斷對%rsp做出任何假設,那麼它們可能是不正確的 - 關於紅區的使用方面沒有把握。所以,你要麼假定它全部是髒的,並且不必要地浪費了堆棧空間(在每個函數中有效地運行一個128字節的保證局部變量),或者,你保證中斷不會對%rsp做出假設 - 這很棘手。

在用戶空間中,上下文切換+128字節的堆棧分配處理爲您處理。

+5

這不僅節省空間。實際上不可能安全地實現正常的128字節的紅區,因爲在中斷處理程序的任何代碼運行之前,中斷總是會破壞'%rsp'下面的16個字節。 – 2016-06-26 21:51:36

+0

@qdot,你能解釋一下128字節的分配過程是什麼意思嗎?這意味着如果amd64 ABI沒有「紅區」的概念,最低的地址堆棧可能會增長128個字節? – 2016-09-19 05:09:19

8

在內核空間中,您正在使用中斷使用的相同堆棧。發生中斷時,the CPU pushes a return address and RFLAGS。這個破壞者低於rsp 16個字節。即使你想寫一箇中斷處理程序,假設128個字節的紅色區域是有價值的,那也是不可能的。


也許你可以有一個內核內部ABI認爲有一個紅色的小區從rsp-16rsp-48什麼的。 (因爲內核堆棧很小,而且大多數函數不需要非常多的紅區)。

中斷處理程序在推送任何寄存器之前必須先執行sub rsp, 32。 (並在iret之前將其恢復)。

運行sub rsp, 32之前,或者它的iret之前恢復rsp後,這種想法是行不通的如果中斷處理程序本身可以被中斷。在有價值的數據爲rsp .. rsp-16時,會有一個漏洞窗口。


該方案的另一個實際問題是AFAIK gcc沒有可配置的紅區參數。它可以打開或關閉。所以如果你想利用它的話,你必須添加對紅色區域的內核風格的支持到gcc/clang。

即使嵌套中斷是安全的,好處是相當小的。證明在內核中安全的困難可能會使其不值得。 (正如我所說的,我不能肯定它可以安全地實現,因爲我覺得嵌套中斷是可能的。)


(順便說一句,請參閱鏈接到ABI的標籤維基記錄了紅區,和其他的東西。)

1

有可能使用紅色區內核型環境。 IDTentry可以指定一個0..7的堆棧索引(ist),其中0有點特殊。 TSS包含這些堆棧的表格。 1..7被加載,並且用於由異常/中斷保存的初始寄存器,並且不嵌套。如果按優先級劃分各種異常條目(例如,NMI最高並且可以隨時發生)並將這些堆棧視爲蹦牀,則可以安全地在內核類型上下文中處理紅色區域。也就是說,在啓用可能導致異常的中斷或代碼之前,您可以從保存的堆棧指針中減去128來獲取可用的內核堆棧。

零指數堆疊相當於以更常規的方式,推入堆棧,國旗,PC,錯誤現有棧上時,有沒有特權的過渡。

蹦牀中的代碼必須小心(duh,它是一個內核),它不會在生成其他異常的同時消除機器狀態,而是提供一個很好的安全位置來檢測病毒內核嵌套,堆棧損壞等... [抱歉,這麼晚迴應,注意到這一點,同時尋找別的東西]。

相關問題