性能測試對于 Linux 發(fā)行版來說至關重要,Alibaba Cloud Linux 2 也是如此。(Alibaba Cloud Linux 2 是阿里巴巴操作系統(tǒng)團隊推出的一款開源且免費的 Linux 操作系統(tǒng)發(fā)行版,其深度集成與優(yōu)化阿里云基礎設施,旨在為阿里云 ECS 客戶提供豐富功能、高性能且穩(wěn)定的操作系統(tǒng)服務,歡迎大家使用。)
然而在測試過程中發(fā)現(xiàn)很多子系統(tǒng)例如網(wǎng)絡子系統(tǒng)的性能與 CPU 調度性能密切相關。系統(tǒng)的調度性能固然與內核中的調度算法相關,然而過去一段時間內現(xiàn)代 CPU 架構下不斷發(fā)現(xiàn)的硬件漏洞及其修復嚴重影響了系統(tǒng)的調度性能。因而了解這些 CPU 漏洞的原理及修復,對于系統(tǒng)性能測試具有重要意義。
本文嘗試對當前版本內核中存在的 CPU 漏洞及修復作一個簡單的介紹,本文亦可作為一個知識庫,在需要的時候快速索引瀏覽。由于作者水平以及文章篇幅所限,文中若存在錯誤,請大家共同交流學習 ^^ 。
2. 背景介紹
2018年一月,Google Project Zero 爆出現(xiàn)代處理器存在安全漏洞 Spectre 與 Meltdown。其實早在 2017 年Google Project Zero 就已經(jīng)發(fā)現(xiàn)了這些漏洞,而與此同時 Moritz Lipp、Paul Kocher 等安全研究人員也對此進行了研究。
攻擊者可以使用這些漏洞竊取高特權級的數(shù)據(jù),因而對系統(tǒng)安全存在嚴重威脅。同時這兩組漏洞幾乎涉及當今大部分主流的處理器(包括 Intel、AMD、ARM 等多種架構),因而一公開便引起了廣泛的討論。包括 Linux 在內的主流操作系統(tǒng)隨后都對漏洞進行了相應的修復。由于這些漏洞利用處理器硬件的投機執(zhí)行(speculative execution)以及亂序執(zhí)行(out-of-order execution)特性,而這些特性對于現(xiàn)代處理器的性能提升具有不可或缺的作用,因而其中的一些修復會帶來較大的性能回退。
由于這些漏洞源自現(xiàn)代處理器硬件的架構設計,軟件方面的修復通常只能緩解而不能根治問題,同時自 2018年一月 Spectre 與 Meltdown 漏洞首次公布以來,新變種以及新類型的漏洞不斷出現(xiàn),因而可以預見這些漏洞的存在在未來相當一段時間內會成為常態(tài)。
本文描述了當前 CPU 架構下存在的漏洞,對于各個漏洞現(xiàn)有的修復方案以及開啟方式。
/sys/devices/system/cpu/vulnerabilities/目錄下存在以下文件,分別描述對應的 CPU 漏洞:
meltdown
spectre_v1
spectre_v2
spec_store_bypass
l1tf
mds
這些文件的輸出格式為
“Not affected” 表示當前 CPU 不存在該漏洞
”Vulnerable” 表示當前 CPU 存在該漏洞,同時沒有采取任何緩解措施
“Mitigation: $M” 表示當前 CPU 存在該漏洞,同時采取了相應緩解措施
3. 漏洞詳解
3.1 Spectre Variant 1
本節(jié)描述的 spectre variant 1 特指 Bounds check bypass,SWAPGS 見下一節(jié)。
/sys/devices/system/cpu/vulnerabilities/spectre_v1 描述 Spectre variant 1 的修復情況。
早期版本中 Spectre Variant 1 只存在對于 array bounds check bypass 的修復,且這種修復無法關閉,此時 spectre_v1 文件的輸出只有一種顯示,即:
“Mitigation: __user pointer sanitization”
而在之后 spectre_v1 增加了對 swapgs 的修復,詳情見下一節(jié)。
3.1.1 Array bounds check bypass
Spectre variant 1 (CVE-2017-5753, Bounds check bypass) 的原理是利用處理器在執(zhí)行條件分支(conditional branch)時的投機執(zhí)行(speculative execution),使得處理器在投機執(zhí)行 false 分支的時候泄露相關的旁路信息,使得攻擊者通過旁路攻擊竊取數(shù)據(jù)。
Spectre variant 1 的攻擊方式多見于 array bounds / user pointer check bypass。內核對于該攻擊方式已經(jīng)存在相應修復:對于前者,在使用 array index 訪問內存之前,將 array index 執(zhí)行 mask 操作,從而確保 index 落在 [0, array_size] 的有效范圍內;而對于后者,在對 user pointer 執(zhí)行有效性檢查的時候,添加一條 lfence 指令,以防止檢查完成前投機執(zhí)行之后的指令。
以上這些修復的指令開銷很小,同時只有在 1) 執(zhí)行數(shù)組訪問,同時 array index 是用戶傳入的值,例如系統(tǒng)調用,或 2) 執(zhí)行 copy-from-user 的時候顯式調用對應的修復,而不是全局開啟,因而開銷較小;這些修復在 Upstream v4.16-rc2 版本合入。
3.1.2 開關
對于 array bounds check bypass 的修復目前無法關閉。
3.2 SWAPGS
SWAPGS 是 spectre variant 1 的另一個變種,此時 /sys/devices/system/cpu/vulnerabilities/spectre_v1 文件的輸出有:
“Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers”
表示開啟對 array bounds check bypass 的修復,關閉對 swapgs 的修復
“Mitigation: usercopy/swapgs barriers and __user pointer sanitization”
表示開啟所有 spectre variant 1 修復,包括對 array bounds check bypass 的修復,以及對 swapgs 的修復。
3.2.1 SWAPGS
Spectre variant 1 的原理是利用處理器執(zhí)行條件分支(conditional branch)時的投機執(zhí)行,因而其攻擊方式不局限于 array bounds / user pointer check bypass,另一種攻擊方式是在中斷或異常發(fā)生時,攻擊者可以訓練 branch predictor,使其錯誤地跳過或執(zhí)行 swapgs 指令,從而為旁路攻擊制造條件,這種攻擊方式也就被稱為 swapgs。
例如當由用戶態(tài)進入中斷或異常時,以下代碼中在條件分支判斷結束前,CPU 就可能會跳過 swapgs 而執(zhí)行之后的代碼,此時執(zhí)行 GS 寄存器的訪問操作時,由于跳過了 swapgs 操作,因而此時實際訪問的仍是用戶態(tài) GS 寄存器,此時攻擊者可以精心設計用戶態(tài) GS 寄存器的值,以獲取特定內存地址處內存的值。
if (coming from user space)
swapgs
mov %gs:《percpu_offset》, %reg1
對于該攻擊方式的修復也是在中斷或異常的入口,在條件分支之后添加 lfence 指令,該修復在 Upstream v5.3-rc4 合入主線。
3.2.2 開關
可以通過 nospectre_v1=off 或 mitigations=off 啟動參數(shù)關閉對 swapgs 的修復,注意這兩個參數(shù)均不能關閉之前對 array bounds check bypass 的修復。
3.3 Spectre Variant 2
/sys/devices/system/cpu/vulnerabilities/spectre_v2 描述 Spectre Variant 2 的修復情況,其輸出有如下情形:
“Vulnerable”,表示未開啟任何修復
“Mitigation: Full generic retpoline”,表示當前開啟 retpoline 修復
“Mitigation: Full AMD retpoline”,表示當前開啟 AMD 處理器專用的 retpoline 修復,只有 AMD 處理器可以開啟該修復
“Mitigation: Enhanced IBRS”,表示當前開啟 IBRS 修復
3.3.1 原理
Spectre variant 2 (CVE-2017-5715, Branch target injection) 實際是利用了處理器執(zhí)行間接跳轉指令時的投機執(zhí)行行為。
間接跳轉指令執(zhí)行過程中,當需要跳轉的絕對地址不在緩存中、而需要從內存讀取時,就會執(zhí)行分支預測功能。處理器硬件內部使用 BTB (Branch Target Buffer) 來緩存 (間接跳轉指令的原地址, 跳轉指令的目標地址) 這一對數(shù)據(jù),處理器硬件的分支預測即使用 BTB 來預測當前執(zhí)行的間接跳轉指令對應的目標跳轉地址。
然而該機制存在的一個問題是,同一個處理器上的不同應用程序會共用同一個 BTB,因而 spectre variant 2 的原理即是攻擊者通過用戶態(tài)程序執(zhí)行特定的間接跳轉指令來訓練當前處理器的 BTB,從而使同一處理器上運行的 Linux 內核運行間接跳轉指令時,分支預測功能就會被誤導跳轉到攻擊者設計的一個特定地址上,從而運行攻擊者設計的程序。
3.3.2 retpoline 修復
spectre variant 2 漏洞主要攻擊間接跳轉指令,Google 提出的一種軟件解決方案稱為 retpoline,其原理是使用 ret 指令來實現(xiàn)地址跳轉。由于 ret 指令使用的 RSB (Return Stack Buffer) 預測機制更為明確,因而不會受到攻擊者的惡意訓練。該修復在 Upstream v4.15-rc8 版本合入。
3.3.3 IBRS 修復
retpoline 的原理是使用 RSB ,從而規(guī)避用戶態(tài)程序對 BTB 的惡意訓練。然而對于 Skylake 及之后的機型,retpoline 并不能完全解決 Spectre variant 2。這是因為 Skylake 及之后的機型在調用深度較大而導致 RSB 用盡時,會“回退”使用 BTB,從而又重新遭受 Spectre 威脅。
Intel 提出的一種稱為 IBRS (Indirect Branch Restricted Speculation) 的解決方案,其原理是運行于高特權級(privilege level) 的程序,不能復用低特權級程序緩存的 BTB,即內核在使用 BTB 進行分支預測時,不能使用用戶態(tài)程序訓練的 BTB 項。該解決方案需要處理器的 microcode 更新支持。
該修復方案中處理器每次由低特權級切換到高特權級時,都需要軟件配置一次相應的寄存器,以 flush 掉之前低特權級程序訓練的 BTB,因而實際存在一定的性能損耗。IBRS 修復方案實際沒有合入 Upstream,因而也不存在與 Cloud Kernel。
3.3.4 EIBRS 修復
之前描述的 IBRS 修復需要處理器每次由低特權級切換到高特權級時,軟件都需要配置一次相應的寄存器,這給軟件設計帶來不便,同時存在一定的性能損耗。
EIBRS (Enhanced IBRS) 是一種改進的 IBRS,其原理與 IBRS 相同,唯一的區(qū)別是只需要在系統(tǒng)初始化時對寄存器進行一次設置,之后處理器由低特權級切換到高特權級時,處理器硬件都會自動地 flush 掉之前低特權級程序訓練的 BTB。該修復方案需要處理器硬件支持,目前只支持 “future CPUs”,在 Upstream v4.19-rc1 合入。
3.3.5 開關
可以使用 spectre_v2 啟動參數(shù)可以設置是否開啟 Spectre variant 2 修復,以及選擇哪一種修復方案,其格式為:
spectre_v2=[off|on|retpoline|retpoline,amd|retpoline,generic|auto]
“off”, 表示關閉 Spectre variant 2 修復;
“retpoline,generic”, 表示開啟 retpoline 修復;
“retpoline,amd”, 表示開啟 AMD 處理器特定的 retpoline 修復;
“retpoline”,表示開啟 retpoline 修復,但是會根據(jù)當前處理器的型號,自定選擇 “retpoline,generic” 或是 “retpoline,amd”;
“on” 與 “auto” 具有相同的效果,表示開啟 Spectre variant 2 修復,并自動選擇修復方案:若處理器支持 EIBRS ,則開啟 EIBRS 修復,否則開啟 retpoline 修復。
當未指定 spectre_v2 啟動參數(shù)時,默認為 spectre_v2=auto,即自動選擇 Spectre variant 2 的修復方案。
需要關閉 Spectre variant 2 修復時,可以通過 nospectre_v2 或 spectre_v2=off 啟動參數(shù)關閉
從 Upstream LTS v4.19.43 版本起,也可以使用 mitigations=off 啟動參數(shù)關閉包含 Spectre Variant 2 修復在內的所有修復。
3.4 Spectre Variant 4 (Speculative Store Bypass)
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass 描述 Speculative Store Bypass 的修復情況,其輸出有如下情形:
“Vulnerable”,表示不開啟任何 Speculative Store Bypass 修復
“Mitigation: Speculative Store Bypass disabled”,表示在處理器硬件層面全局關閉 store buffer bypass 特性,這會較大程度地影響處理器性能
“Mitigation: Speculative Store Bypass disabled via prctl”,表示用戶態(tài)程序可以通過 prctl 系統(tǒng)調用修復 Speculative Store Bypass
“Mitigation: Speculative Store Bypass disabled via prctl and seccomp”,表示用戶態(tài)程序可以通過 seccom 框架修復 Speculative Store Bypass
3.4.1 原理
Spectre variant 4 (CVE-2018-3639, Speculative Store Bypass) 利用 store buffer bypass 時泄漏的旁路信息。
現(xiàn)代處理器在對內存進行讀寫時,通常在處理器與內存之間維護一個高速緩存,稱為 load buffer 與 store buffer。當處理器對某個內存地址進行讀操作時,除了查詢 load buffer,還需要查詢 store buffer,以獲取處理器之前對該內存地址寫入的值。盡管 store buffer 相對于內存屬于高速緩存,然而其訪問速度相對于 CPU 來說仍然較慢。因而為了提升性能,在這種情況下現(xiàn)代處理器通常采用 Speculative Store Bypass 的優(yōu)化方式,即假設 store buffer 中不存在當前內存地址的更新值,就開始投機執(zhí)行之后的指令,若之后發(fā)現(xiàn) store buffer 中存在更新的值,就丟棄之前投機之行的結果。然而在該投機執(zhí)行的過程中,已經(jīng)泄露了相關的旁路信息。
3.4.2 Speculative Store Bypass Disable (SSBD) 修復
可以通過設置處理器的相關寄存器,全局關閉處理器的 Speculative Store Bypass 優(yōu)化。該修復方案需要 microcode 更新支持,Upstream v4.17-rc7 合入。
3.4.3 prctl 修復
Speculative Store Bypass 攻擊只能發(fā)生在相同特權級下,即用戶態(tài)無法攻擊內核態(tài),因而 Spectre variant 4 常見的一種攻擊場景是 sandbox。這種場景下同一個進程分別運行 sandbox 主體程序、以及運行在 sandbox 內部的 untrusted 程序這兩種程序,通過 Spectre variant 4 運行在 sandbox 內部的程序有可能竊取 sandbox 主體程序的數(shù)據(jù)。
同時之前所述全局關閉 Speculative Store Bypass 的方式代價過大,內核提供了一種 prctl 的修復方案。這種修復方案實際是以 per-thread 粒度關閉 Speculative Store Bypass 優(yōu)化。用戶態(tài)進程可以調用 prctl 系統(tǒng)調用(with PR_SET_SPECULATION_CTRL - PR_SPEC_DISABLE 參數(shù)),使得處理器只有在調度執(zhí)行當前進程的過程中,關閉 Speculative Store Bypass 優(yōu)化。該修復方案在 Upstream v4.17-rc7 合入。
3.4.4 seccomp 修復
與 prctl 修復方案類似,seccomp 修復也是以 per-thread 粒度關閉 Speculative Store Bypass 優(yōu)化,只是采用 seccomp 框架的進程會自動關閉該優(yōu)化,而不需要進程顯式調用 prctl 系統(tǒng)調用。該修復方案在 Upstream v4.17-rc7 合入。
3.4.5 開關
spec_store_bypass_disable 啟動參數(shù)用于設置是否開啟 Speculative Store Bypass 修復,以及采用何種修復方案,其格式為:
spec_store_bypass_disable=[off|on|auto|prctl|seccomp]
“off”,表示不開啟任何修復
“on”,表示全局關閉處理器的 Speculative Store Bypass 優(yōu)化
“prctl”,表示采用 prctl 修復方式
“seccomp”,表示采用 seccomp 修復方式
“auto”,表示自動選擇修復方式,若系統(tǒng)支持 seccomp 框架,則默認采用 seccomp 修復方式,否則采用 prctl 修復方式
當未指定 spec_store_bypass_disable 啟動參數(shù)時,若處理器支持 Speculative Store Bypass Disable,則默認采用spec_store_bypass_disable=auto,否則默認不開啟所有 Speculative Store Bypass 修復。
可以通過 spec_store_bypass_disable=off 或 nospec_store_bypass_disable 啟動參數(shù)關閉該修復。以上修復以及啟動參數(shù)都在 Upstream v4.17-rc7 版本合入。
從 Upstream LTS v4.19.43 版本起,也可以使用 mitigations=off 啟動參數(shù)關閉包含 Speculative Store Bypass 修復在內的所有修復。
3.5 Meltdown
/sys/devices/system/cpu/vulnerabilities/meltdown 描述 Meltdown 的修復情況,其輸出
“Vulnerable”,表示未開啟任何修復
“Mitigation: PTI”,表示采用 PTI 修復
3.5.1 原理
現(xiàn)代操作系統(tǒng)通常將內核態(tài)與用戶態(tài)的地址空間相分隔,用戶態(tài)程序沒有權限訪問內核態(tài)的地址空間,這一特性是系統(tǒng)安全的重要基石。
Meltdown (CVE-2017-5754) 攻擊則利用現(xiàn)代處理器的亂序執(zhí)行(out-of-order execution)特性,打破了用戶態(tài)、內核態(tài)地址空間之間的隔離,通過旁路攻擊,使得用戶態(tài)程序可以獲取內核態(tài)地址空間處內存的值。
movzx (%rcx), %rax
shl $12, %rax
movq (%rbx, %rax), %rbi
考慮以上示例代碼,假設 rcx 寄存器保存內核地址空間內需要探測的某一內存地址,指令 1 即 movzx 指令表示讀取該內存地址處內存的值,并保存到 rax 寄存器中。在該指令執(zhí)行過程中檢測到進程不具備該內存地址的訪問權限,因而會觸發(fā)異常,而導致 rax 寄存器中的值被丟棄。
以上過程都符合處理器的設計,然而實際上處理器硬件自身存在指令亂序執(zhí)行的優(yōu)化,在執(zhí)行 movzx 指令尚未結束的情況下,之后的指令 2、3 實際已經(jīng)開始運行。在指令 1 (權限檢查)結束之前,指令 2、3 已經(jīng)可以訪問 rax 寄存器的值。雖然之后指令 1 結束時,指令 2、3 之行過程中寄存器的狀態(tài)都被丟棄,但是 cache 的狀態(tài)變化得以保留。攻擊程序通過 cache 旁路攻擊就可以獲取泄露的內核地址空間中內存的值。
3.5.2 PTI 修復
以上 Meltdown 攻擊實現(xiàn)的另外一個重要條件是,Linux 內核在實現(xiàn)時出于性能考慮,用戶態(tài)進程使用的 page table 實際包含內核態(tài)地址空間的映射,因而在以上攻擊方式中,攻擊者可以在用戶態(tài)進程中獲取內核態(tài)地址空間的內存數(shù)據(jù)。
KPTI (Kernel Page Table Isolation) 則恰好可以縮減用戶態(tài)進程使用的 page table 中內核地址空間的映射,其原理是進程運行在用戶態(tài)時,將內核映射中除 exception entry 之外的其他映射都設置為無效,這樣再發(fā)生 meltdown 攻擊時,由于對應的映射無效,因而攻擊者已經(jīng)無法再讀取對應內核地址空間中的數(shù)據(jù)。當進程通過系統(tǒng)調用或異常由用戶態(tài)進入內核態(tài)時,會將用戶進程的 page table 中的內核映射切換為有效的映射;當調用結束進程從內核態(tài)回到用戶態(tài)時,再次切換進程的內核映射,使其變?yōu)闊o效。
KPTI 其實早在 Meltdown 漏洞爆發(fā)之前就已經(jīng)出現(xiàn),因為恰好可以緩解 Meltdown 攻擊而被廣泛使用,其于 Upstream v4.15 合入。
KPTI 修復對于系統(tǒng)性能存在較大影響,可以參考 Brendan Gregg 的分析。
3.5.3 開關
pti 啟動參數(shù)(Upstream v4.15-rc6 合入)用于設置是否開啟 KPTI 修復,其格式為
pti=[off|on|auto]
“off”,表示不開啟 KPTI 修復
“on”,表示開啟 KPTI 修復
“auto”,表示只有當前處理器存在 Meltdown 漏洞時才開啟 KPTI 修復
當未指定 pti 啟動參數(shù)時,默認使用 “pti=autoi” 配置
可以通過 pti=off 或 nopti (Upstream v4.15-rc6 合入)啟動參數(shù)關閉 KPTI 修復。
從 Upstream LTS v4.19.43 版本起,也可以使用 mitigations=off 啟動參數(shù)關閉包含 KPTI 修復在內的所有修復。
3.6 L1TF
/sys/devices/system/cpu/vulnerabilities/l1tf 描述 L1TF 的修復情況,其輸出有如下格式:
Mitigation: PTE Inversion;[VMX: ][, SMT: ]
“Mitigation: PTE Inversion”,表示使用 PTE inversion 修復
VMX 字段描述是否開啟 L1D flush 修復
“vulnerable”,表示不開啟 L1D flush 修復
“conditional cache flushes”,表示開啟 conditional L1D flush 修復
“cache flushes”,表示開啟 unconditional L1D flush 修復,
SMT 字段描述是否開啟 SMT
“vulnerable”,表示開啟 SMT
“disabled”,表示關閉 SMT
3.6.1 原理
L1TF (CVE-2018-3615, L1 data Terminal Fault) 同樣是利用處理器的投機執(zhí)行來獲取一個 physical page 的內容。
Linux 中使用 page table entry (PTE) 來實現(xiàn)虛擬地址到物理地址之間的轉換,x86 PTE 的格式如上圖所示,其中 PFN (Page Frame Number) 字段描述對應 page frame 的物理地址,P (Present) 字段描述當前虛擬地址是否存在對應的物理地址,即是否為該虛擬地址分配了對應的 physical page frame。進程在使用虛擬地址訪問內存時,會首先找到該虛擬地址對應的 PTE,若 P 字段為 0,則會發(fā)生 page fault;若 P 字段為 1,根據(jù) PFN 字段的值在 L1 data cache 中尋找是否存在緩存。
Intel 處理器在判斷 P 標志位是否為 1 的時候,在判斷尚未結束之前會投機之行之后的代碼,即根據(jù) PFN 字段的值在 L1 data cache 中尋找是否存在緩存。若緩存命中,那么通過 cache 旁路攻擊,攻擊者就可以獲取某一物理地址處的內存數(shù)據(jù)。
3.6.2 PTE inversion 修復
當不涉及虛擬化時,L1TF 的危害其實相對有限,因為攻擊者不太容易構造 PFN 字段具有特定值的 PTE,這樣攻擊者就不能通過 L1TF 獲取特定物理地址處的內存值。
即使攻擊方式不太容易實現(xiàn),數(shù)據(jù)泄露的風險是確實存在的。同時考慮到以上攻擊方式成功的重要條件是 PFN 構成的物理地址在 L1 cache 中緩存命中,因而 PTE inversion 可以用于修復。其原理是當開啟 PTE inversion 時,逆序存儲 non-Present 的 PTE 中的所有 bit,這樣以上攻擊方式中,使用 PFN 字段逆序之后的值在 L1 cache 中就會發(fā)生 cache miss。
PTE inversion 總是開啟。
3.6.3 L1D flush 修復
注意:該修復只適用于 host kernel
L1TF 攻擊也可以發(fā)生在 guest VM 中,此時若攻擊者可以自由更換 guest kernel,那么攻擊者就可以自由地構造 PTE 使得 non-Present PTE 的 PFN 字段具有特定值,從而讀取任意物理地址處的內存值,使得 guest VM 獲取 host kernel 甚至其他 guest VM 的數(shù)據(jù)。
guest kernel 使用 PTE inversion 只能防止用戶態(tài)進程竊取 guest kernel 的數(shù)據(jù),而為了防止 guest VM 獲取 host 乃至其他 guest VM 的數(shù)據(jù),host kernel 可以采用 L1D flush 的修復方式。其原理是,考慮到 L1TF 攻擊方式的重要條件是對應的物理地址在 L1 data cache 中存在緩存,那么 host kernel 每次在進入 guest 之前,都執(zhí)行 flush L1 data cache 操作。
當 VMEXIT/VMENTER 的頻率較大時,該修復方式會對系統(tǒng)帶來較大的性能回退。因而 L1D flush 實際提供兩種工作模式:
conditional flush
unconditional flush
unconditional flush 是指每次 VMENTER 都執(zhí)行 flush L1 data cache 操作,性能開銷大,但是相對更安全;
conditional flush 是指當 VMEXIT 與 VMENTER 之間執(zhí)行的都是不重要的代碼路徑時,就不執(zhí)行 flush L1 data cache 操作,這減小了性能開銷,但是會泄露 hypervisor 的內存布局。
3.6.3 SMT Disabling 修復
注意:該修復只適用于 host kernel
以上 L1D flush 修復可以防止 guest VM 對 host kernel 的 L1TF 攻擊,但是在開啟 SMT (Symmetric Multi-Threading, or Hyperthreads) 的情況下,一個 logical CPU 執(zhí)行 L1D flush 操作后,同一個 Core 上的另一個 logical CPU 實際可以重新生成 L1D cache。
因而為了讓 L1D flush 修復真正生效,有時還需要配合關閉 SMT 特性。
3.6.4 開關
l1tf 啟動參數(shù)用于設置是否開啟 L1TF 修復,以及采用何種修復方案,其格式為:
l1tf=[off|flush,nowarn|flush|flush,nosmt|full|full,force]
“off”,表示不開啟任何 L1TF 修復
“flush”,表示開啟 conditional L1D flush 修復,關閉SMT Disabling 修復
“flush,nowarn”,與 “flush” 一樣,開啟L1D flush 修復,關閉SMT Disabling 修復,只是 “flush” 在第一臺 VM 啟動時會發(fā)出 warning 警告(因為 SMT Disabling 修復沒有開啟而可能存在潛在的威脅),而 ”flush,nowarn” 則不會
“flush,nosmt”,表示開啟 conditional L1D flush 修復,開啟 SMT Disabling 修復
“full”,表示開啟 unconditional L1D flush 修復,開啟 SMT Disabling 修復
“full,force”,與 “full” 一樣,只是 ”full” 配置下還可以通過 sysfs 接口在運行時動態(tài)開啟或關閉 L1D flush 修復或 SMT Disabling 修復,而 ”full,force” 配置下則不行
可以通過 l1tf=off ( v4.19-rc1 合入)關閉 L1TF 修復。
從 Upstream LTS v4.19.43 版本起,也可以使用 mitigations=off 啟動參數(shù)關閉包含 L1TF 修復在內的所有修復。
3.7 MDS
/sys/devices/system/cpu/vulnerabilities/mds ( v4.19.43 合入)描述 MDS 的修復情況
“Vulnerable”,表示不開啟 MDS 修復
“Vulnerable: Clear CPU buffers attempted, no microcode”,表示開啟 CPU buffer clear 修復,但是當前處理器沒有 microcode 支持,因而當前修復基于 best effort 原則
“Mitigation: Clear CPU buffers”,表示開啟 CPU buffer clear 修復
3.7.1 原理
MDS (Microarchitectural Data Sampling) 是利用處理器的投機執(zhí)行,通過旁路攻擊獲取 store buffer、fill buffer、load port 中數(shù)據(jù)的攻擊方式。
通過 MDS 攻擊,低特權級程序可以獲取高特權級的數(shù)據(jù),即用戶態(tài)程序可以獲取內核數(shù)據(jù),guest kernel 可以獲取 host 數(shù)據(jù),但是由于攻擊程序無法構造特定的內存地址以獲取特定地址處的內存數(shù)據(jù),因而只能通過“采樣”的方式獲取某一內存地址處對應的數(shù)據(jù),同時由于這些緩存單次泄漏的數(shù)據(jù)量相對較小,攻擊者需要收集大量數(shù)據(jù)才有可能推測敏感數(shù)據(jù),因而其危害相對有限。
針對 MDS 的修復主要是由內核態(tài)切換到用戶態(tài),或由 hypervisor 切換到 guest 時,對 store buffer、fill buffer、load port 等緩存執(zhí)行 flush 操作,該修復需要 microcode 更新支持。當處理器支持 SMT 時,該修復還需要配合關閉 SMT,以防止同一個 physical core 上的另一個 logical CPU 重新填充這些緩存。
3.7.2 開關
可以通過 mds=[off|full|full,nosmt] (v4.19.43 合入) 啟動參數(shù)控制知否開啟 MDS 修復
“off”,表示不開啟 MDS 修復
“full”,表示開啟 CPU buffer clear 修復,但是不會關閉 SMT
“full,nosmt”,表示開啟 CPU buffer clear 修復,同時關閉 SMT
可以使用 mds=off (v4.19.43 合入) 啟動參數(shù)關閉 MDS 修復。
從 Upstream LTS v4.19.43 版本起,也可以使用 mitigations=off 啟動參數(shù)關閉包含 MDS 修復在內的所有修復。
4. 外部鏈接
Spectre Attacks: Exploiting Speculative Execution
Meltdown: Reading Kernel Memory from User Space
Spectre Side Channels
Deep Dive: Indirect Branch Restricted Speculation
Speculative-Execution-Side-Channel-Mitigations
Retpoline: A Branch Target Injection Mitigation
Speculative Store Bypass
Speculative Store Bypass explained: what it is, how it works
Meltdown strikes back: the L1 terminal fault vulnerability
L1TF - L1 Terminal Fault
Meltdown strikes back: the L1 terminal fault vulnerability
MDS - Microarchitectural Data Sampling
Deep Dive: Intel Analysis of Microarchitectural Data Sampling
責任編輯:haq
-
處理器
+關注
關注
68文章
19100瀏覽量
228817 -
cpu
+關注
關注
68文章
10805瀏覽量
210847 -
漏洞
+關注
關注
0文章
203瀏覽量
15352
原文標題:CPU漏洞詳解
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論