Linux中國

關於 Linux 頁面表隔離補丁的神秘情況

本文勘誤與補充

長文預警: 這是一個目前嚴格限制的、禁止披露的安全 bug(LCTT 譯註:目前已經部分披露),它影響到目前幾乎所有實現虛擬內存的 CPU 架構,需要硬體的改變才能完全解決這個 bug。通過軟體來緩解這種影響的緊急開發工作正在進行中,並且最近在 Linux 內核中已經得以實現,並且,在 11 月份,在 NT 內核中也開始了一個類似的緊急開發。在最糟糕的情況下,軟體修復會導致一般工作負載出現巨大的減速(LCTT 譯註:外在表現為 CPU 性能下降)。這裡有一個提示,攻擊會影響虛擬化環境,包括 Amazon EC2 和 Google 計算引擎,以及另外的提示是,這種精確的攻擊可能涉及一個新的 Rowhammer 變種(LCTT 譯註:一個由 Google 安全團隊提出的 DRAM 的安全漏洞,在文章的後面部分會簡單介紹)。

我一般不太關心安全問題,但是,對於這個 bug 我有點好奇,而一般會去寫這個主題的人似乎都很忙,要麼就是知道這個主題細節的人會保持沉默。這讓我在新年的第一天(元旦那天)花了幾個小時深入去挖掘關於這個謎團的更多信息,並且我將這些信息片斷拼湊到了一起。

注意,這是一件相互之間高度相關的事件,因此,它的主要描述都是猜測,除非過一段時間,它的限制禁令被取消。我所看到的,包括涉及到的供應商、許多爭論和這種戲劇性場面,將在限制禁令取消的那一天出現。

LWN

這個事件的線索出現於 12 月 20 日 LWN 上的 內核頁面表的當前狀況:頁面隔離這篇文章。從文章語氣上明顯可以看到這項工作的緊急程度,內核的核心開發者緊急加入了 KAISER 補丁系列的開發——它由奧地利的 TU Graz 的一組研究人員首次發表於去年 10 月份。

這一系列的補丁的用途從概念上說很簡單:為了阻止運行在用戶空間的進程在進程頁面表中通過映射得到內核空間頁面的各種攻擊方式,它可以很好地阻止了從非特權的用戶空間代碼中識別到內核虛擬地址的攻擊企圖。

這個小組在描述 KAISER 的論文《KASLR 已死:KASLR 永存》摘要中特別指出,當用戶代碼在 CPU 上處於活動狀態的時候,在內存管理硬體中刪除所有內核地址空間的信息。

這個補丁集的魅力在於它觸及到了核心,內核的全部基柱(以及與用戶空間的介面),顯然,它應該被最優先考慮。遍觀 Linux 中內存管理方面的變化,通常某個變化的首次引入會發生在該改變被合併的很久之前,並且,通常會進行多次的評估、拒絕、以及因各種原因爆發爭論的一系列過程。

KAISER(就是現在的 KPTI)系列(從引入到)被合併還不足三個月。

ASLR 概述

從表面上看,這些補丁設計以確保 地址空間布局隨機化 Address Space Layout Randomization (ASLR)仍然有效:這是一個現代操作系統的安全特性,它試圖將更多的隨機位引入到公共映射對象的地址空間中。

例如,在引用 /usr/bin/python 時,動態鏈接將對系統的 C 庫、堆、線程棧、以及主要的可執行文件進行排布,去接受隨機分配的地址範圍:

$ bash -c 『grep heap /proc/$$/maps』
019de000-01acb000 rw-p 00000000 00:00 0                                  [heap]
$ bash -c 'grep heap /proc/$$/maps』
023ac000-02499000 rw-p 00000000 00:00 0                                  [heap]

注意兩次運行的 bash 進程的堆(heap)的開始和結束偏移量上的變化。

如果一個緩存區管理的 bug 將導致攻擊者可以去覆寫一些程序代碼指向的內存地址,而那個地址之後將在程序控制流中使用,這樣這種攻擊者就可以使控制流轉向到一個包含他們所選擇的內容的緩衝區上。而這個特性的作用是,對於攻擊者來說,使用機器代碼來填充緩衝區做他們想做的事情(例如,調用 system() C 庫函數)將更困難,因為那個函數的地址在不同的運行進程上不同的。

這是一個簡單的示例,ASLR 被設計用於去保護類似這樣的許多場景,包括阻止攻擊者了解有可能被用來修改控制流的程序數據的地址或者實現一個攻擊。

KASLR 是應用到內核本身的一個 「簡化的」 ASLR:在每個重新引導的系統上,屬於內核的地址範圍是隨機的,這樣就使得,雖然被攻擊者操控的控制流運行在內核模式上,但是,他們不能猜測到為實現他們的攻擊目的所需要的函數和結構的地址,比如,定位當前進程的數據段,將活動的 UID 從一個非特權用戶提升到 root 用戶,等等。

壞消息:緩減這種攻擊的軟體運行成本過於貴重

之前的方式,Linux 將內核的內存映射到用戶內存的同一個頁面表中的主要原因是,當用戶的代碼觸發一個系統調用、故障、或者產生中斷時,就不需要改變正在運行的進程的虛擬內存布局。

因為它不需要去改變虛擬內存布局,進而也就不需要去清洗掉(flush)依賴於該布局的與 CPU 性能高度相關的緩存(LCTT 譯註:意即如果清掉這些高速緩存,CPU 性能就會下降),而主要是通過 轉換查找緩衝器 Translation Lookaside Buffer (TLB)(LCTT 譯註:TLB ,將虛擬地址轉換為物理地址)。

隨著頁面表分割補丁的合併,內核每次開始運行時,需要將內核的緩存清掉,並且,每次用戶代碼恢復運行時都會這樣。對於大多數工作負載,在每個系統調用中,TLB 的實際總損失將導致明顯的變慢:@grsecurity 測量的一個簡單的案例,在一個最新的 AMD CPU 上,Linux du -s 命令變慢了 50%。

34C3

在今年的 CCC 大會上,你可以找到 TU Graz 的另外一位研究人員,《描述了一個純 Javascript 的 ASLR 攻擊》,通過仔細地掌握 CPU 內存管理單元的操作時機,遍歷了描述虛擬內存布局的頁面表,來實現 ASLR 攻擊。它通過高度精確的時間掌握和選擇性回收的 CPU 緩存行的組合方式來實現這種結果,一個運行在 web 瀏覽器的 Javascript 程序可以找回一個 Javascript 對象的虛擬地址,使得可以利用瀏覽器內存管理 bug 進行接下來的攻擊。(LCTT 譯註:本文作者勘誤說,上述鏈接 CCC 的講演與 KAISER 補丁完全無關,是作者弄錯了)

因此,從表面上看,我們有一組 KAISER 補丁,也展示了解除 ASLR 化地址的技術,並且,這個展示使用的是 Javascript,它很快就可以在一個操作系統內核上進行重新部署。

虛擬內存概述

在通常情況下,當一些機器碼嘗試去載入、存儲、或者跳轉到一個內存地址時,現代的 CPU 必須首先去轉換這個 虛擬地址 到一個 物理地址 ,這是通過遍歷一系列操作系統託管的數組(被稱為頁面表)的方式進行的,這些數組描述了虛擬地址和安裝在這台機器上的物理內存之間的映射。

在現代操作系統中,虛擬內存可能是最重要的強大特性:它可以避免什麼發生呢?例如,一個瀕臨死亡的進程崩潰了操作系統、一個 web 瀏覽器 bug 崩潰了你的桌面環境、或者一個運行在 Amazon EC2 中的虛擬機的變化影響了同一台主機上的另一個虛擬機。

這種攻擊的原理是,利用 CPU 上維護的大量的緩存,通過仔細地操縱這些緩存的內容,它可以去推測內存管理單元的地址,以去訪問頁面表的不同層級,因為一個未緩存的訪問將比一個緩存的訪問花費更長的時間(以實時而言)。通過檢測頁面表上可訪問的元素,它可能能夠恢復在 MMU(LCTT 譯註:存儲器管理單元)忙於解決的虛擬地址中的大部分比特(bits)。

這種動機的證據,但是不用恐慌

我們找到了動機,但是到目前為止,我們並沒有看到這項工作引進任何恐慌。總的來說,ASLR 並不能完全緩減這種風險,並且也是一道最後的防線:僅在這 6 個月的周期內,即便是一個沒有安全意識的人也能看到一些關於解除(unmasking) ASLR 化的指針的新聞,並且,實際上這種事從 ASLR 出現時就有了。

單獨的修復 ASLR 並不足於去描述這項工作高優先順序背後的動機。

它是硬體安全 bug 的證據

通過閱讀這一系列補丁,可以明確許多事情。

第一,正如 @grsecurity 指出 的,代碼中的一些注釋已經被編輯掉了(redacted),並且,描述這項工作的附加的主文檔文件已經在 Linux 源代碼樹中看不到了。

通過檢查該代碼,這些補丁以運行時補丁的方式構建而成,在系統引導時僅當內核檢測到該系統是受影響的系統時,這些補丁才會被應用。這裡採用了和對著名的 Pentium F00F bug 的緩解措施完全相同的機制:

更多的線索:Microsoft 也已經實現了頁面表的分割

通過對 FreeBSD 源代碼的一個簡單挖掘可以看出,目前,其它的自由操作系統沒有實現頁面表分割,但是,通過 Alex Ioniscu 在 Twitter 上的提示,這項工作已經不局限於 Linux 了:從 11 月起,公開的 NT 內核也已經實現了同樣的技術

猜測:Rowhammer

對 TU Graz 研究人員的工作的進一步挖掘,我們找到這篇 《當 rowhammer 僅敲一次》,這是 12 月 4 日通告的一個 新的 Rowhammer 攻擊的變種

在這篇論文中,我們提出了新的 Rowhammer 攻擊和漏洞的原始利用方式,表明即便是組合了所有防禦也沒有效果。我們的新攻擊技術,對一個位置的反覆 「敲打」(hammering),打破了以前假定的觸發 Rowhammer bug 的前提條件。

快速回顧一下,Rowhammer 是多數(全部?)種類的商業 DRAM 的一類根本性問題,比如,在普通的計算機中的內存上。通過精確操作內存中的一個區域,這可能會導致內存該區域存儲的相關(但是邏輯上是獨立的)內容被毀壞。效果是,Rowhammer 可能被用於去反轉內存中的比特(bits),使未經授權的用戶代碼可以訪問到,比如,這個比特位描述了系統中的其它代碼的訪問許可權。

我發現在 Rowhammer 上,這項工作很有意思,尤其是它反轉的位接近頁面表分割補丁時,但是,因為 Rowhammer 攻擊要求一個目標:你必須知道你嘗試去反轉的比特在內存中的物理地址,並且,第一步是得到的物理地址可能是一個虛擬地址,就像在 KASLR 中的解除(unmasking)工作。

猜測:它影響主要的雲供應商

在我能看到的內核郵件列表中,除了該子系統維護者的名字之外,e-mail 地址屬於 Intel、Amazon 和 Google 的僱員,這表示這兩個大的雲計算供應商對此特別感興趣,這為我們提供了一個強大的線索,這項工作很大的可能是受虛擬化安全驅動的。

它可能會導致產生更多的猜測:虛擬機 RAM 和由這些虛擬機所使用的虛擬內存地址,最終表示為在主機上大量的相鄰的數組,那些數組,尤其是在一個主機上只有兩個租戶的情況下,在 Xen 和 Linux 內核中是通過內存分配來確定的,這樣可能會有(準確性)非常高的可預測行為。

最喜歡的猜測:這是一個提升特權的攻擊

把這些綜合到一起,我並不難預測,可能是我們在 2018 年會使用的這些存在提升特權的 bug 的發行版,或者類似的系統推動了如此緊急的進展,並且在補丁集的抄送列表中出現如此多的感興趣者的名字。

最後的一個趣聞,雖然我在閱讀補丁集的時候沒有找到我要的東西,但是,在一些代碼中標記,paravirtual 或者 HVM Xen 是不受此影響的。

吃瓜群眾表示 2018 將很有趣

這些猜想是完全有可能的,它離實現很近,但是可以肯定的是,當這些事情被公開後,那將是一個非常令人激動的幾個星期。

via: http://pythonsweetness.tumblr.com/post/169166980422/the-mysterious-case-of-the-linux-page-table

作者:python sweetness 譯者:qhwdw 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國