熔斷漏洞原理與解決方案


原理:  

        在現代處理器上,內核和用戶進程之間的隔離通常由處理器的一個監督位來實現,該監督位定義是否可以訪問內核的內存頁面。其基本思想是只有在進入內核代碼時才能設置該位,切換到用戶進程時該位被清除。

  亂序執行:現在的CPU幾乎都是亂序執行的。比如前后並不關聯的指令,它是可以亂序執行的,因為前面的指令可能需要等待讀取內存,這是需要很多指令周期的。CPU為了不浪費指令周期它可以先執行后面不相關的指令(因此有些地方要使用內存屏障)。

       按理來說攻擊者是沒辦法在用戶態讀取到其他進程或是內核的內存,因為用戶態的進程是隔離的(當然,如果攻擊者能把攻擊代碼寫在內核模塊中,那么它可以為所欲為了)。 比如攻擊者可以寫一段jsp代碼放在瀏覽器的沙盒中執行。

1 raise_exception();
2 // the line below is never reached
3 access(probe_array[data * 4096]);

      以上代碼中執行過程中出現異常,因為CPU是亂序執行的,它認為這兩句代碼沒什么關聯,所以它接下來的代碼將有可能能得到部分的執行。要命的是intel處理器在進入特權狀態后訪問內存的時候居然不進行指令的權限檢測。 上面的異常導致CPU進入特權狀態,但下面的代碼的指令的權限是用戶態的。 所以導致內存從cache中泄露(這部分可見幽靈漏洞中解釋)。

     內核內存空間是線性映射的。

解決方法:

首先,這並不是一個軟件的漏洞,而是硬件的問題。我們來討論幾種方案:

1. 完全禁止亂序執行: 這不太可行,這對性能是毀滅性的打擊。

2. 序列化的權限檢測:就是每次取內存的時候都檢查一下權限,但是這樣性能消耗也非常大,也不太可行。

3. 通過物理內存隔離來實現:這可以通過現代內核使用CPU控制寄存器(例如CR4)中的新的硬分離位來啟用。如果hardsplit位被設置,內核必須駐留在地址空間的上半部分,用戶空間必須駐留在地址空間的下半部分。通過這種硬分割,內存提取可以立即識別目標的這種提取是否會違反安全邊界。 現在的物理內核中用戶態和內核態並非隔離的,而是雜亂的排在一起。 棄用硬隔離后兩者的物理地址空間直接隔離,那么檢測是否有違反安全邊界就很簡單了。

新的內核采用第三種方案,也就是KAISER,在Linux正式版本中叫做KPTI。 可能是將用戶態進程的內核棧從內核的線性映射改為非線性映射,類似於用戶態。 但是用戶態和內核態的棧必須隔離,安全起見。 所以還需要一些工作就是防止CR4切換帶來的cache失效。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM