日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Spectre CPU漏洞借着BPF春风卷土重来

發(fā)布時(shí)間:2024/4/11 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spectre CPU漏洞借着BPF春风卷土重来 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


By Jonathan Corbet

翻譯整理: 極客重生

https://lwn.net/Articles/860597/

Hi,大家好,昨天不小心看到一篇文章,是關(guān)于BPF安全漏洞問題,BPF給內(nèi)核新功能的開發(fā)帶了很大靈活性,尤其是監(jiān)控和網(wǎng)絡(luò)方面,是Linux內(nèi)核當(dāng)前最火技術(shù)方向之一,但同時(shí)也帶來新的安全隱患。?安全和靈活性,總是矛盾的,類似容器和虛擬機(jī)的安全之爭,極客們的追求就是不斷挖掘技術(shù)的可能性,讓安全性和靈活性都可以滿足。

對eBPF不熟悉可以參考:

Linux網(wǎng)絡(luò)新技術(shù)基石 |eBPF and XDP

正文

自從披露 Spectre 硬件漏洞(2018年轟動世界的CPU漏洞)以來已經(jīng)三年多了,但 Spectre 確實(shí)是一份不斷給予的"禮物"。當(dāng)硬件以可預(yù)測的方式運(yùn)行時(shí),編寫正確且安全的代碼就足夠困難了,當(dāng)處理器可以做隨機(jī)和瘋狂的事情時(shí),問題會變得更糟。為了說明所涉及的挑戰(zhàn),只需查看本公告中描述的 BPF 漏洞即可,該漏洞?已在 5.13-rc7 版本中修復(fù)。

對 Spectre 漏洞的攻擊通常依賴于處理器在預(yù)測模式下執(zhí)行一系列在實(shí)際執(zhí)行中不會發(fā)生的操作。一個(gè)典型的例子是超出范圍的數(shù)組引用,即使代碼執(zhí)行了正確的邊界檢查。一旦處理器發(fā)現(xiàn)它錯(cuò)誤地預(yù)測了邊界檢查的結(jié)果,錯(cuò)誤的訪問就會被取消,但預(yù)測模式下訪問會在內(nèi)存緩存中留下可用于竊取數(shù)據(jù)的痕跡。

在預(yù)測模式執(zhí)行的攻擊方面,BPF 虛擬機(jī)一直是一個(gè)特別值得關(guān)注的領(lǐng)域。大多數(shù)此類攻擊依賴于尋找內(nèi)核代碼片段,當(dāng) CPU預(yù)測性執(zhí)行時(shí),該片段可以做出令人驚訝的事情;內(nèi)核開發(fā)人員已經(jīng)齊心協(xié)力消除這些碎片。但是 BPF 的存在是為了能夠從在內(nèi)核上下文中運(yùn)行的用戶空間加載代碼;這允許攻擊者制作自己的代碼片段并避免梳理內(nèi)核代碼的繁瑣任務(wù)。

BPF 社區(qū)已經(jīng)做了很多工作來挫敗這些攻擊者。例如,數(shù)組索引與位掩碼進(jìn)行 AND 運(yùn)算,因此無論它們可能包含什么值,它們甚至無法推測性地到達(dá)數(shù)組之外。但是很難預(yù)測處理器可能會做出令人驚訝的事情的每種情況。

漏洞

例如,考慮以下代碼片段,該代碼片段直接取自?Daniel Borkmann 修復(fù)此漏洞的提交:

// r0 = 指向映射數(shù)組條目的指針// r6 = 指向可讀棧槽的指針// r9 = 攻擊者控制的標(biāo)量1: r0 = *(u64 *)(r0) // 緩存未命中2:如果 r0 != 0x0 轉(zhuǎn)到第 4 行3:r6 = r94: 如果 r0 != 0x1 轉(zhuǎn)到第 6 行5:r9 = *(u8 *)(r6)6: // 泄漏 r9

順便說一下,這個(gè)補(bǔ)丁的變更日志(change log)是記錄漏洞及其修復(fù)的一個(gè)很好的例子,值得一讀:

From 9183671af6dbf60a1219371d4ed73e23f43b49db Mon Sep 17 00:00:00 2001 From: Daniel Borkmann <daniel@iogearbox.net> Date: Fri, 28 May 2021 15:47:32 +0000 Subject: bpf: Fix leakage under speculation on mispredicted branches驗(yàn)證器僅枚舉有效的控制流路徑并跳過在非推測域中無法訪問的路徑。 因此,它可能會遺漏預(yù)測錯(cuò)誤分支上的推測執(zhí)行下的問題。例如,以下 精心設(shè)計(jì)的程序證明了類型混淆:// r0 = 指向映射數(shù)組條目的指針 // r6 = 指向可讀堆棧槽的指針// r9 = 由攻擊者控制的標(biāo)量1: r0 = *(u64 * )(r0) // 緩存未命中2: 如果 r0 != 0x0 轉(zhuǎn)到第 4 行3: r6 = r9 4: 如果 r0 != 0x1 轉(zhuǎn)到第 6 行5: r9 = *(u8 *)(r6) 6: // 泄漏 r9由于第 3 行運(yùn)行 iff r0 = = 0 并且第 5 行運(yùn)行 iff r0 == 1,驗(yàn)證器 得出結(jié)論,第 5 行的指針取消引用是安全的。但是:如果 攻擊者訓(xùn)練兩個(gè)分支都失敗,從而 推測執(zhí)行以下內(nèi)容... r6 = r9 r9 = *(u8 *)(r6) // 泄漏 r9 ... 那么程序?qū)⑷∠靡粋€(gè)攻擊者控制的值,并可能 通過側(cè)信道在推測執(zhí)行下泄漏其內(nèi)容。這需要 對分支預(yù)測器進(jìn)行錯(cuò)誤訓(xùn)練,這可能相當(dāng)棘手,因?yàn)?分支是相互排斥的。然而,這樣的訓(xùn)練可以 在用戶空間中使用不 互斥的不同分支在一致的地址上完成。也就是說,通過在用戶空間中訓(xùn)練分支... A: if r0 != 0x0 goto line C B: ... C: if r0 != 0x0 goto line D D: ... ... 這樣地址 A 和C 分別 與 PHT(模式歷史表)中與 BPF 程序的 第 2 行和第 4 行相同的 CPU 分支預(yù)測條目發(fā)生沖突。非特權(quán)攻擊者可以簡單地 在 PHT 中暴力破解此類沖突,直到觀察到攻擊成功。錯(cuò)誤訓(xùn)練分支預(yù)測器的替代方法也是可能的 避免暴力破解 PHT 中的沖突。已經(jīng) 證明了一種可靠的攻擊,例如,使用以下精心設(shè)計(jì)的程序:// r0 = 指向 [control] 映射數(shù)組條目的指針// r7 = *(u64 *)(r0 + 0), training/attack phase // r8 = *(u64 *)(r0 + 8), oob address // [...] // r0 = 指向 [data] 映射數(shù)組條目的指針1: if r7 == 0x3 goto line 3 2: r8 = r0 // 精心設(shè)計(jì)的條件跳轉(zhuǎn)序列將第193 行中的條件分支與當(dāng)前執(zhí)行流程分開3: if r0 != 0x0 goto line 5 4: if r0 == 0x0 goto exit 5: if r0 != 0x0 goto line 7 6:如果 r0 == 0x0 轉(zhuǎn)到退出[...]187: if r0 != 0x0 goto line 189 188: if r0 == 0x0 goto exit // 加載任何緩慢加載的值(由于階段 3 中的緩存未命中)... 189: r3 = *(u64 *)(r0 + 0x1200) // ...并將其轉(zhuǎn)換為已知的零以供驗(yàn)證者使用,同時(shí)在執(zhí)行時(shí)緩慢保留加載的依賴項(xiàng):190: r3 &= 1 191: r3 &= 2 // 推測性地繞過相位依賴項(xiàng)192: r7 + = r3 193: if r7 == 0x3 goto exit 194: r4 = *(u8 *)(r8 + 0) // 泄漏 r4可以看出,在訓(xùn)練階段(phase != 0x3),第 1 行的條件發(fā)生了 變化為 false,因此帶有 oob 地址的 r8 被覆蓋 有效的映射值地址,我們可以在第 194 行中毫無問題地讀出該地址 。然而,在攻擊階段,第 2 行被跳過,并且由于 第 189 行中的緩存未命中,其中映射值(歸零后)添加到 階段寄存器中,第 193 行中的條件由于 先前分支預(yù)測器訓(xùn)練,根據(jù)推測,它將 在 oob 地址 r8(此時(shí)未知的標(biāo)量類型)加載字節(jié),然后可能 會通過側(cè)信道泄漏。緩解這些問題的一種方法是“分支”一條無法到達(dá)的路徑,這意味著 當(dāng)前驗(yàn)證路徑一直遵循 is_branch_taken() 路徑 ,我們將另一個(gè)分支推送到驗(yàn)證堆棧。鑒于這是 無法從非推測域訪問,該分支的 vstate 被 明確標(biāo)記為推測。之所以需要這樣做,有兩個(gè)原因: i)?如果僅從推測執(zhí)行中看到此路徑,那么我們稍后仍 希望消除死代碼以使用?jmp-1s清理這些指令,以及? ii)?確保路徑在非推測域中行走的路徑不會從早期在 推測域中行走的路徑中剪除。此外,為了穩(wěn)健性,我們 在推測路徑中將作為條件的一部分的寄存器標(biāo)記為未知, 因?yàn)椴粦?yīng)對其內(nèi)容進(jìn)行任何假設(shè)。這里的修復(fù)減輕了前面描述的類型混淆攻擊,因?yàn)?i)?正在探索的?BPF?程序中的所有代碼路徑以及 ii)?現(xiàn)有的驗(yàn)證器邏輯已經(jīng)確保給定的內(nèi)存訪問指令 引用一個(gè)特定的數(shù)據(jù)結(jié)構(gòu)。在此范圍內(nèi)也已查看的此修復(fù)程序的替代方法是 使用 BPF_JMP_TAKEN 狀態(tài) 以及方向編碼(always-goto、always-fallthrough、unknown)在跳轉(zhuǎn)指令處標(biāo)記 aux->alu_state , 以便混合不同的always-* 方向本身以及 always-* 與未知方向的混合會導(dǎo)致 驗(yàn)證器拒絕程序,例如具有像'if ([...]) { x = 0; } else { x = 1; }' 和隨后的 'if (x == 1) { [...] }'。對于無特權(quán)者,這 將導(dǎo)致只有單方向始終-* 采取的路徑,并且 允許未知的采用路徑,這樣前者可以從條件 跳轉(zhuǎn)修補(bǔ)到無條件跳轉(zhuǎn)(ja)。與這里的這種方法相比,它 有兩個(gè)缺點(diǎn):i) 否則不執(zhí)行任何 指針運(yùn)算等的有效程序可能會被拒絕/破壞,以及 ii) 我們 需要關(guān)閉非特權(quán)的路徑修剪,其中兩個(gè) 在這項(xiàng)工作中可以通過將無效分支推送到驗(yàn)證堆棧來避免。該問題最初是由?Adam?和?Ofek?發(fā)現(xiàn)的,后來 作為?Benedict?和?Piotr?的研究工作獨(dú)立發(fā)現(xiàn)和報(bào)告的。 Fixes: b2157399cc98 ("bpf: prevent out-of-bounds speculation") Reported-by: Adam Morrison <mad@cs.tau.ac.il> Reported-by: Ofek Kirzner <ofekkir@gmail.com> Reported-by: Benedict Schlueter <benedict.schlueter@rub.de> Reported-by: Piotr Krysiuk <piotras@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: John Fastabend <john.fastabend@gmail.com> Reviewed-by: Benedict Schlueter <benedict.schlueter@rub.de> Reviewed-by: Piotr Krysiuk <piotras@gmail.com> Acked-by: Alexei Starovoitov <ast@kernel.org> ---kernel/bpf/verifier.c | 44 ++++++++++++++++++++++++++++++++++++++++----1 file changed, 40 insertions(+), 4 deletions(-)diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index af88d9b9c0143..c6a27574242de 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6483,6 +6483,27 @@ struct bpf_sanitize_info {bool mask_to_left;};+static struct bpf_verifier_state * +sanitize_speculative_path(struct bpf_verifier_env *env, + const struct bpf_insn *insn, + u32 next_idx, u32 curr_idx) +{ + struct bpf_verifier_state *branch; + struct bpf_reg_state *regs; + + branch = push_stack(env, next_idx, curr_idx, true); + if (branch && insn) { + regs = branch->frame[branch->curframe]->regs; + if (BPF_SRC(insn->code) == BPF_K) { + mark_reg_unknown(env, regs, insn->dst_reg); + } else if (BPF_SRC(insn->code) == BPF_X) { + mark_reg_unknown(env, regs, insn->dst_reg); + mark_reg_unknown(env, regs, insn->src_reg); + } + } + return branch; +} +static int sanitize_ptr_alu(struct bpf_verifier_env *env,struct bpf_insn *insn,const struct bpf_reg_state *ptr_reg, @@ -6566,7 +6587,8 @@ do_sim:tmp = *dst_reg;*dst_reg = *ptr_reg;} - ret = push_stack(env, env->insn_idx + 1, env->insn_idx, true); + ret = sanitize_speculative_path(env, NULL, env->insn_idx + 1, + env->insn_idx);if (!ptr_is_dst_reg && ret)*dst_reg = tmp;return !ret ? REASON_STACK : 0; @@ -8763,14 +8785,28 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,if (err)return err;} +if (pred == 1) { - /* only follow the goto, ignore fall-through */ + /* Only follow the goto, ignore fall-through. If needed, push + * the fall-through branch for simulation under speculative + * execution. + */ + if (!env->bypass_spec_v1 && + !sanitize_speculative_path(env, insn, *insn_idx + 1, + *insn_idx)) + return -EFAULT;*insn_idx += insn->off;return 0;} else if (pred == 0) { - /* only follow fall-through branch, since - * that's where the program will go + /* Only follow the fall-through branch, since that's where the + * program will go. If needed, push the goto branch for + * simulation under speculative execution.*/ + if (!env->bypass_spec_v1 && + !sanitize_speculative_path(env, insn, + *insn_idx + insn->off + 1, + *insn_idx)) + return -EFAULT;return 0;} -- cgit 1.2.3-1.el7

在正常(非推測性)執(zhí)行中,上述代碼存在潛在問題。寄存器r9包含攻擊者提供的值;該值在第 3 行分配給r6,然后在第 5 行用作指針。該值可以指向內(nèi)核地址空間中的任何位置;這正是 BPF 驗(yàn)證器旨在防止的那種不受約束的訪問,因此人們可能會認(rèn)為該代碼一開始永遠(yuǎn)不會被內(nèi)核接受。

然而,驗(yàn)證器通過探索執(zhí)行 BPF 程序可能采取的所有可能路徑來工作。在這種情況下,沒有可能的路徑同時(shí)執(zhí)行第 3 行和第 5 行。攻擊者提供的指針的分配僅在r0包含零時(shí)發(fā)生,但該值將阻止第 5 行的執(zhí)行。因此驗(yàn)證器得出結(jié)論:沒有可以導(dǎo)致用戶提供的指針被間接訪問,并允許加載程序的路徑。

但這種驗(yàn)證運(yùn)行確定執(zhí)行場景,預(yù)測執(zhí)行中有著不同的規(guī)則。

上面代碼片段中的第 1 行引用了攻擊者會費(fèi)心確保當(dāng)前未緩存的內(nèi)存,從而導(dǎo)致緩存未命中。然而,處理器將繼續(xù)推測,而不是等待內(nèi)存獲取值,猜測任何涉及r0 的條件語句將如何執(zhí)行。事實(shí)證明,這些猜測很可能是if條件(在第 2 行或第 4 行中)都不會評估為真,因此不會進(jìn)行任何跳轉(zhuǎn)。

這個(gè)怎么可能?通過猜測r0的值并檢查結(jié)果,分支預(yù)測不起作用?;相反,它基于該特定分支的最近歷史。該歷史記錄存儲在 CPU 的“模式歷史表”(PHT)中。但是 CPU 不可能跟蹤大型程序中的每條分支指令,因此 PHT 采用哈希表的形式。攻擊者可以定位代碼,使其分支與精心設(shè)計(jì)的 BPF 程序中的分支位于相同的 PHT 條目中,然后使用該代碼訓(xùn)練分支預(yù)測器以進(jìn)行所需的猜測。

一旦攻擊者加載了代碼,清除了緩存,并欺騙分支預(yù)測器做一些愚蠢的事情,戰(zhàn)斗就結(jié)束了;CPU 將推測性地引用攻擊者提供的地址。那么這只是以任何通常的方式泄漏結(jié)果的問題。這是一個(gè)有點(diǎn)乏味的過程——但計(jì)算機(jī)擅長遵循這樣的過程而不會抱怨。

值得注意的是,這不是假設(shè)性的攻擊。根據(jù)公告,當(dāng)報(bào)告此問題時(shí),多個(gè)概念證明被發(fā)送到?security@kernel.org列表。其中一些不需要訓(xùn)練分支預(yù)測器的步驟(上面鏈接的提交中提供了一個(gè)這樣的步驟)。這些攻擊可以讀取內(nèi)核地址空間中的任何內(nèi)存;考慮到所有物理內(nèi)存都包含在其中,因此可以泄露的內(nèi)容沒有真正的限制。由于非特權(quán)用戶可以加載幾種類型的 BPF 程序,因此不需要 root 訪問權(quán)限來執(zhí)行此攻擊。換句話說,這是一個(gè)嚴(yán)重的漏洞。

修復(fù)

這種情況下的修復(fù)相對簡單。而不是修剪驗(yàn)證者“知道”不會執(zhí)行的路徑,驗(yàn)證者將推測性地模擬它們。因此,例如,當(dāng)檢查r0為零的路徑時(shí)?,未固定的驗(yàn)證者只會得出結(jié)論,第 4 行中的測試必須為真,而不考慮替代方案。修復(fù)后,驗(yàn)證器將查看錯(cuò)誤路徑(包括第 5 行),得出正在使用未知指針的結(jié)論,并阻止程序加載。

這種變化有可能阻止加載之前可以運(yùn)行的正確程序,盡管很難想象包含這種模式的真實(shí)世界的非惡意代碼。當(dāng)然,它會減慢驗(yàn)證過程,因?yàn)樗枰獧z查正常程序執(zhí)行中不會出現(xiàn)的執(zhí)行路徑--那些在我們的預(yù)測執(zhí)行的世界里。

此修復(fù)已合并到主線中,可以在 5.13-rc7 版本中找到。此后,它已進(jìn)入 5.12.13 和 5.10.46 穩(wěn)定更新的版本,但(尚未)進(jìn)入任何早期的穩(wěn)定版本。通過此補(bǔ)丁,這些內(nèi)核可以抵御另一個(gè) Spectre 漏洞,但這個(gè)應(yīng)該不會是最后一個(gè)。

- END -


大家好,我是極客君,鵝廠資深工程師,騰訊云網(wǎng)絡(luò)核心成員,多次獲得五星員工,專注實(shí)戰(zhàn)技術(shù)和職場心得,分享技術(shù)的本質(zhì)原理,校招,社招面試技巧和經(jīng)驗(yàn),希望搭建連接大學(xué)和工作的橋梁,幫你理解技術(shù)實(shí)際落地場景,不光幫你拿的BAT offer,還可以幫你獲得高級工程師的視野,爭取拿SP/SSP,希望幫助更多人蛻變重生,期待你的關(guān)注,有任何問題,大家都可以加我微信,探討技術(shù),大廠offer,轉(zhuǎn)行互聯(lián)網(wǎng),還可以交個(gè)朋友。

沒有進(jìn)技術(shù)交流群小伙伴,可以進(jìn)群交流

- END -


看完一鍵三連在看轉(zhuǎn)發(fā),點(diǎn)贊

是對文章最大的贊賞,極客重生感謝你

推薦閱讀

深入理解編程藝術(shù)之策略與機(jī)制相分離

C語言登頂!|2021年7月編程語言排行榜

聊聊C語言和指針的本質(zhì)


總結(jié)

以上是生活随笔為你收集整理的Spectre CPU漏洞借着BPF春风卷土重来的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 9999免费视频 | 波多野结衣人妻 | 手机av在线不卡 | 国产激情一区二区三区四区 | 99免费观看 | 欧美最猛性xxxxx(亚洲精品) | 深夜福利成人 | 国产三级精品三级在线观看 | 国产在线一区视频 | 亚洲欧洲综合在线 | 九九热视频这里只有精品 | 精品乱码一区二区三区 | 日本黄色xxx| 久久在线免费观看视频 | 欧美午夜精品久久久久久孕妇 | 999国内精品永久免费视频 | 91亚洲在线 | 97超在线| 首尔之春在线观看 | 色婷视频 | 日韩av成人网 | 丝袜中文字幕 | 一区二区三区视频网站 | 99久久亚洲精品 | 亚洲成人一区二区三区 | 一区二区免费视频 | 全国男人的天堂网 | 久久国产精品免费观看 | 日韩在线视频网站 | 1级黄色大片儿 | 伊人久久亚洲综合 | 久久国产精品久久久久久电车 | 伊人手机在线视频 | 欧美性受xxxx黑人猛交88 | 亚洲图片在线观看 | 久久国产精品波多野结衣av | 麻豆婷婷| 光棍福利视频 | 日本一区二区三区在线免费观看 | 国产亚州av | 一区二区三区久久久 | 三级伦理视频 | 天天综合国产 | 黄色av大片 | 中文字幕中文在线 | 国产精品不卡av | 蜜桃视频在线观看网站 | 久久国产激情视频 | 欧美激情一区 | 亚洲最新网址 | 午夜天堂视频 | 久久久久精| 国产中文久久 | av网址免费 | 亚洲日本护士毛茸茸 | 国产a∨精品一区二区三区仙踪林 | 亚洲一区二区图片 | 亚洲欧美日韩精品永久在线 | 人妻无码久久一区二区三区免费 | 久啪视频| 奇米四色在线观看 | 熟妇人妻系列aⅴ无码专区友真希 | 窝窝视频在线 | 素人一区二区 | 黄色一级片国产 | 国产一区二区不卡视频 | 久久麻豆av | 国产91丝袜在线18 | 黄瓜视频成人 | jizz国产在线观看 | 伊人亚洲天堂 | a天堂资源在线 | 日本少妇一区二区三区 | 深夜网站在线观看 | www.久久.com| 亚洲综合五区 | 欧美影院在线 | 求个黄色网址 | 都市激情一区 | 丁香花电影在线观看免费高清 | 麻豆国产精品一区 | 自拍偷拍21p| 911香蕉 | 国产免费黄色小视频 | 自拍在线视频 | 哺乳期喷奶水丰满少妇 | 日本视频一区二区三区 | 国产综合无码一区二区色蜜蜜 | 性久久久久久久久 | 亚洲色图88 | 免费一级毛片麻豆精品 | 99热99这里只有精品 | 亚洲一片| 免费av小说| 超碰在线免费观看97 | 2021毛片 | 91亚洲一区二区三区 | 亚洲综合日韩精品欧美综合区 | 欧美一区三区二区在线观看 |