《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 通信與網(wǎng)絡(luò) > 業(yè)界動(dòng)態(tài) > 一個(gè)硬件安全工程師眼中的Meltdown

一個(gè)硬件安全工程師眼中的Meltdown

2018-01-08
作者:Tbsoft博士
關(guān)鍵詞: Meltdown 安全漏洞

  1、現(xiàn)代計(jì)算機(jī)體系結(jié)構(gòu)(Architecture,也譯作架構(gòu)或者系統(tǒng)結(jié)構(gòu))和CPU微體系結(jié)構(gòu)(Microarchitecture,也譯作微架構(gòu)或者微結(jié)構(gòu))

  現(xiàn)代計(jì)算機(jī)的體系結(jié)構(gòu)基本都是基于馮·諾依曼體系結(jié)構(gòu),也就是“存儲(chǔ)程序方式”,即程序指令代碼(指令)和數(shù)據(jù)都放在內(nèi)存中,運(yùn)行時(shí)CPU從內(nèi)存中逐條取指令并執(zhí)行,指令還可以在必要時(shí)訪問(wèn)內(nèi)存數(shù)據(jù)。

  哈佛結(jié)構(gòu)是馮·諾依曼結(jié)構(gòu)的一種變形,特點(diǎn)是將程序(指令)存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器分開(kāi),即有兩塊獨(dú)立的內(nèi)存,一塊存放指令,一塊存放數(shù)據(jù),但沒(méi)有脫離“存儲(chǔ)程序方式”這種基本的方式,因此仍然屬于馮·諾依曼結(jié)構(gòu)的變形或者改進(jìn)。

  對(duì)于程序員,即使是匯編語(yǔ)言甚至機(jī)器語(yǔ)言程序員,最多也只能涉及到內(nèi)存指令和數(shù)據(jù)這一級(jí),計(jì)算機(jī)暴露給程序員的,只能是馮·諾依曼結(jié)構(gòu)或者哈佛結(jié)構(gòu),稱為計(jì)算機(jī)體系結(jié)構(gòu)(Architecture)。

  但CPU本身是由運(yùn)算器、控制器、寄存器等部件組成的硬件電路,內(nèi)存指令被取入CPU后,在CPU內(nèi)部還要經(jīng)過(guò)復(fù)雜的指令譯碼等過(guò)程,才能驅(qū)動(dòng)CPU硬件電路相應(yīng)部件,按照指令具體需求進(jìn)行相應(yīng)動(dòng)作,最終完成指令執(zhí)行,這一過(guò)程是由CPU內(nèi)部的取指令、指令譯碼、部件驅(qū)動(dòng)等硬件電路完成的,不同CPU差異很大,即使指令集相同的CPU也可以有不同的電路實(shí)現(xiàn)方法,這種CPU內(nèi)部硬件電路的結(jié)構(gòu),稱為CPU的微體系結(jié)構(gòu)(Microarchitecture)。

  CPU微結(jié)構(gòu)是設(shè)計(jì)CPU的核心,對(duì)于程序員而言,CPU微結(jié)構(gòu)并不暴露給程序員,最底層的程序員的極限也只能是通過(guò)CPU指令來(lái)訪問(wèn)CPU,換而言之,程序員使用CPU的最小操作粒度是指令。但CPU指令在CPU內(nèi)部可能還會(huì)被解析成為更小的執(zhí)行單元,最終驅(qū)動(dòng)CPU的單個(gè)硬件電路部件,也就是說(shuō),在CPU微結(jié)構(gòu)中有更小的操作粒度,例如微操作(MicroOP,μO(píng)P)或者微指令,它們都是由CPU微結(jié)構(gòu)決定的。

  或者說(shuō),CPU對(duì)于程序員而言也是一個(gè)黑盒子,程序員只要按照CPU指令集,用相應(yīng)的指令編寫(xiě)程序(如果是高級(jí)語(yǔ)言,則由編譯器或者解釋器將高級(jí)語(yǔ)言語(yǔ)句最終轉(zhuǎn)換為CPU指令),并將指令程序和相應(yīng)數(shù)據(jù)加載到內(nèi)存(現(xiàn)代通常由操作系統(tǒng)完成)即可執(zhí)行程序,程序員只訪問(wèn)到計(jì)算機(jī)體系結(jié)構(gòu)這一級(jí),至于指令在CPU內(nèi)部是怎么進(jìn)一步解析并最終執(zhí)行的,那是CPU微結(jié)構(gòu)決定的,對(duì)程序員不開(kāi)放,程序員不關(guān)心,通常也不應(yīng)該關(guān)心,實(shí)際也無(wú)法關(guān)心。

  2、如何提高CPU的運(yùn)行速度

  CPU執(zhí)行一條指令,一般來(lái)說(shuō),最少也要經(jīng)過(guò)從內(nèi)存中取指令,將指令譯碼解析成微操作(μO(píng)P),微操作最終驅(qū)動(dòng)硬件電路部件三個(gè)步驟(簡(jiǎn)稱取指令、譯碼和執(zhí)行),如果執(zhí)行一條指令,要等到這三個(gè)步驟都完成后,才能執(zhí)行下一條指令,則一條指令執(zhí)行時(shí)間過(guò)長(zhǎng)(用CPU硬件術(shù)語(yǔ)說(shuō)就是消耗多個(gè)時(shí)鐘周期),CPU運(yùn)行速度就無(wú)法得到有效提高。

  如果在第一條指令譯碼時(shí),同時(shí)取第二條指令;然后等到第一條指令執(zhí)行時(shí),第二條指令同時(shí)譯碼,同時(shí)還取第三條指令……這樣周而復(fù)始,取指令、譯碼和執(zhí)行就可以重疊進(jìn)行,就好比生產(chǎn)流水線上的工人,第一個(gè)工人對(duì)第一個(gè)產(chǎn)品加工好第一道工序后,將產(chǎn)品傳遞給第二個(gè)工人加工第二道工序,這是第一個(gè)工人可以對(duì)第二個(gè)產(chǎn)品加工第一道工序了……這樣可以避免工人不必要的空閑等待,生產(chǎn)效率就會(huì)大大提高,這一提高CPU運(yùn)行速度的方法,也就稱為“流水線”,現(xiàn)代CPU均使用流水線技術(shù)。

  流水線有效減少了單條指令的平均執(zhí)行時(shí)間,但指令仍然是一條條順序執(zhí)行的,實(shí)際上,很多指令是彼此不相關(guān)的,例如訪問(wèn)兩組完全不同寄存器的兩條指令,它們完全可以并行執(zhí)行,執(zhí)行順序的先后并不影響最終執(zhí)行結(jié)果,對(duì)于這樣的不相關(guān)指令,完全可以設(shè)計(jì)多個(gè)執(zhí)行部件電路,直接扔到不同執(zhí)行部件中去并行執(zhí)行,稱為亂序(Out-of-order)執(zhí)行,可以進(jìn)一步提高指令執(zhí)行速度。亂序執(zhí)行在現(xiàn)代CPU中廣泛應(yīng)用,甚至對(duì)于有相關(guān)性的指令,也可以采用寄存器換名等手段將它們變成不相關(guān)指令,從而進(jìn)行亂序執(zhí)行。

  但流水線和亂序執(zhí)行都會(huì)碰到一個(gè)問(wèn)題,從原理上講它們僅適用于純順序執(zhí)行的指令,一旦遇到分支,即條件跳轉(zhuǎn)指令,因?yàn)椴粓?zhí)行到條件跳轉(zhuǎn)指令本身,是沒(méi)法知道程序轉(zhuǎn)向何處執(zhí)行的,也就是條件跳轉(zhuǎn)指令的下一條指令在未執(zhí)行前不確定,因此無(wú)法預(yù)先取得條件跳轉(zhuǎn)指令的后續(xù)指令,這時(shí)流水線和亂序執(zhí)行都會(huì)失效,因?yàn)樗鼈兊那疤崾穷A(yù)先取得后續(xù)指令。

  為了盡量解決這個(gè)問(wèn)題,現(xiàn)代CPU廣泛使用“分支預(yù)測(cè)”手段,也就是預(yù)測(cè)條件跳轉(zhuǎn)指令會(huì)跳向哪個(gè)分支,然后對(duì)這個(gè)分支進(jìn)行預(yù)取后續(xù)指令。分支預(yù)測(cè)的常用策略是:如果某一段時(shí)間內(nèi)某一條件跳轉(zhuǎn)都走向某一固定分支,則可以預(yù)測(cè)這條條件跳轉(zhuǎn)指令下一次很大可能也走向這一分支。

  典型例子:程序中的循環(huán)結(jié)構(gòu)一般要循環(huán)多次才結(jié)束,那么在循環(huán)結(jié)束之前,判斷循環(huán)條件的條件跳轉(zhuǎn)指令顯然都是走向繼續(xù)循環(huán)分支的。

  分支預(yù)測(cè)配合流水線和亂序執(zhí)行,能夠大大提高CPU的運(yùn)行速度,因此現(xiàn)代CPU微結(jié)構(gòu)基本都使用這種設(shè)計(jì)。

  3、分支預(yù)測(cè)帶來(lái)的問(wèn)題——指令執(zhí)行的“回滾”

  分支預(yù)測(cè)并不能保證100%的成功預(yù)測(cè),一旦預(yù)測(cè)失敗,也就是最終執(zhí)行到條件跳轉(zhuǎn)指令時(shí),發(fā)現(xiàn)跳轉(zhuǎn)目標(biāo)不是先前預(yù)測(cè)的分支方向,那么按照分支預(yù)測(cè)預(yù)取的后續(xù)指令實(shí)際上失效,這些指令已經(jīng)完成的工作必須“取消”掉,否則就會(huì)造成錯(cuò)誤的指令執(zhí)行。

  用一個(gè)程序員容易理解的比喻:分支預(yù)測(cè)的后續(xù)指令執(zhí)行,好比一個(gè)“事務(wù)”,如果分支預(yù)測(cè)是正確的,那么“事務(wù)”可以“提交”,這些后續(xù)指令就真正起作用;如果最終執(zhí)行到條件跳轉(zhuǎn)指令時(shí)發(fā)現(xiàn)分支預(yù)測(cè)是錯(cuò)誤的,則“事務(wù)”必須“回滾”,即使后續(xù)指令已經(jīng)執(zhí)行了,甚至是亂序執(zhí)行了,已經(jīng)完成的工作也都必須全部“撤銷”,后續(xù)指令要看起來(lái)沒(méi)有起任何作用,重新到正確的分支取新的指令執(zhí)行。

  理論上說(shuō),不管指令執(zhí)行“提交”還是“回滾”,都只與CPU微結(jié)構(gòu)相關(guān),其過(guò)程程序員應(yīng)該看不到,程序員只能看到宏觀指令按照程序流程執(zhí)行,CPU內(nèi)部對(duì)程序員仍然應(yīng)該是黑盒子。

  4、克服CPU運(yùn)行速度與內(nèi)存訪問(wèn)速度的差異——高速緩存(Cache)

  目前CPU主頻已經(jīng)達(dá)到3GHz以上,普遍采用多核并行,盡管主內(nèi)存(DDR SDRAM)的主頻已經(jīng)達(dá)到2GHz—3GHz甚至更高,也無(wú)法完全滿足多核CPU運(yùn)行速度的需求,因?yàn)橹噶顖?zhí)行還是必須從內(nèi)存中取指令,如果內(nèi)存訪問(wèn)速度不夠,CPU運(yùn)行速度會(huì)受到內(nèi)存訪問(wèn)速度的限制。

  為了克服這個(gè)問(wèn)題,目前采用在CPU與主內(nèi)存之間插入多級(jí)高速緩存(Cache)的方法,Cache是一種訪問(wèn)速度極高的存儲(chǔ)器,甚至可以集成在CPU內(nèi)部,成為CPU微結(jié)構(gòu)的一部分。Cache與主內(nèi)存之間以塊為單位交換數(shù)據(jù),塊長(zhǎng)一般為數(shù)十字節(jié)。

  當(dāng)CPU需要訪問(wèn)內(nèi)存,例如從內(nèi)存中取指令時(shí),第一次需要先將相應(yīng)內(nèi)存塊一次性讀入到空閑的Cache塊,CPU再直接訪問(wèn)Cache塊,此時(shí)內(nèi)存訪問(wèn)速度會(huì)慢一些,因?yàn)榇嬖谥鲀?nèi)存與Cache之間傳輸成塊數(shù)據(jù)的時(shí)間;CPU第二次訪問(wèn)相同塊內(nèi)存時(shí),即可直接訪問(wèn)Cache塊,而無(wú)須訪問(wèn)主內(nèi)存,內(nèi)存訪問(wèn)速度會(huì)快得多。

  主內(nèi)存—Cache系統(tǒng)構(gòu)成現(xiàn)代CPU的內(nèi)存儲(chǔ)器系統(tǒng),其原理與操作系統(tǒng)中的硬盤(pán)—內(nèi)存系統(tǒng)構(gòu)成虛擬內(nèi)存的原理極其相似。

  5、指令執(zhí)行的“回滾”在主內(nèi)存—Cache系統(tǒng)留下的“痕跡”

  如上所述,如果分支預(yù)測(cè)失敗,則分支預(yù)測(cè)預(yù)取的后續(xù)指令,哪怕已經(jīng)亂序執(zhí)行了多條指令,也必須“回滾”,指令在CPU微結(jié)構(gòu)中已經(jīng)完成的工作必須全部“撤銷”。

  “撤銷”指令是容易的,指令最終完成的工作,無(wú)外乎是對(duì)寄存器或者內(nèi)存的修改,可以暫且將修改“緩存”起來(lái),如果“撤銷”,最終不真正修改寄存器或者內(nèi)存即可。

  但對(duì)于內(nèi)存讀寫(xiě)指令(在CPU設(shè)計(jì)中通常稱為L(zhǎng)oad/Store指令或者LD/ST指令),以讀內(nèi)存指令為例,如果最終“提交”,就必須讀取實(shí)際的內(nèi)存地址,如果相應(yīng)內(nèi)存塊還沒(méi)有被讀入到Cache塊,讀取速度就會(huì)受到影響,因此在讀內(nèi)存指令最終“提交”或者“回滾”之前,CPU微結(jié)構(gòu)一般會(huì)事先將Cache塊準(zhǔn)備好,也就是如果相應(yīng)內(nèi)存塊還沒(méi)有被讀入到Cache塊則預(yù)先讀入。

  也就是說(shuō),即使分支預(yù)測(cè)失敗,已經(jīng)亂序執(zhí)行的多條預(yù)取指令中只要有讀內(nèi)存指令,就算最后被“回滾”,對(duì)廣義的CPU微結(jié)構(gòu)還是有影響的——相應(yīng)內(nèi)存塊已經(jīng)讀入到了Cache塊。

  而內(nèi)存塊是否已經(jīng)讀入到Cache塊,訪問(wèn)速度是有一定差異的,這相當(dāng)于“回滾”的讀內(nèi)存指令在CPU微結(jié)構(gòu)中留下的“痕跡”,這個(gè)“痕跡”是可以被作為“側(cè)信道”利用的。

  6、Meltdown攻擊原理的通俗簡(jiǎn)明解釋

  操作系統(tǒng)的內(nèi)核數(shù)據(jù)是受到CPU微結(jié)構(gòu)保護(hù)的,用戶模式的應(yīng)用程序無(wú)法訪問(wèn),如果訪問(wèn)是要引發(fā)CPU錯(cuò)誤異常的。

  構(gòu)造一個(gè)分支,先檢測(cè)讀取內(nèi)存的地址是否合法,合法就讀取相應(yīng)地址內(nèi)存字節(jié),然后根據(jù)內(nèi)存字節(jié)的值,讓內(nèi)存字節(jié)的值與映射到不同Cache塊的內(nèi)存塊對(duì)應(yīng)起來(lái),再故意讀取一下映射到不同Cache塊的內(nèi)存塊;如果訪問(wèn)內(nèi)存的地址非法,例如操作系統(tǒng)內(nèi)核數(shù)據(jù)地址,直接不讀取。

  顯然,這樣的分支,無(wú)論讀取合法地址還是非法地址都是不會(huì)出錯(cuò)的。

  用大循環(huán)執(zhí)行多次這個(gè)分支,前若干次,讀取內(nèi)存地址都是合法的,“訓(xùn)練”CPU的分支預(yù)測(cè),讓CPU微結(jié)構(gòu)認(rèn)為下次也應(yīng)該走向讀取內(nèi)存這一分支。

  然后,突然執(zhí)行一次非法的操作系統(tǒng)內(nèi)核數(shù)據(jù)地址讀取。

  按道理說(shuō),讀取內(nèi)存地址非法,應(yīng)該走向不讀取這一分支,可是CPU的分支預(yù)測(cè)已經(jīng)被“訓(xùn)練”成了“條件反射”,CPU稀里糊涂地預(yù)取了讀取非法地址的指令,并亂序并行執(zhí)行,只是暫時(shí)沒(méi)有“提交”,因?yàn)闆](méi)有“提交”,即使讀取非法地址內(nèi)存,也不會(huì)引發(fā)CPU異常;而且此時(shí)根據(jù)非法地址內(nèi)存字節(jié)的值,故意讀取映射到不同Cache塊內(nèi)存塊的指令,相應(yīng)的Cache塊也被CPU微結(jié)構(gòu)準(zhǔn)備好了(因?yàn)槭遣⑿衼y序執(zhí)行嘛),也就是相應(yīng)內(nèi)存塊已經(jīng)讀入到了Cache塊。

  當(dāng)然,最后CPU發(fā)現(xiàn)這次分支預(yù)測(cè)錯(cuò)了,沒(méi)關(guān)系,預(yù)取的指令亂序并行執(zhí)行“回滾”,讀取非法地址的指令根本沒(méi)執(zhí)行,沒(méi)有引發(fā)CPU異常,皆大歡喜。

  可是,“痕跡”卻悄悄留下了,與非法地址內(nèi)存字節(jié)值有意對(duì)應(yīng)起來(lái)的內(nèi)存塊已經(jīng)讀入到了Cache塊。

  用程序遍歷一下所有可能對(duì)應(yīng)的內(nèi)存塊,看誰(shuí)訪問(wèn)速度最快,誰(shuí)就很可能在Cache中,而非法地址對(duì)應(yīng)的操作系統(tǒng)內(nèi)核數(shù)據(jù)字節(jié)值是有意與內(nèi)存塊對(duì)應(yīng)的,原本在用戶模式下不能訪問(wèn)的操作系統(tǒng)內(nèi)核數(shù)據(jù)字節(jié)值就被推算出來(lái)。

  這就是所謂的“側(cè)信道泄漏”。

  7、這一攻擊實(shí)質(zhì)的一句話解釋

  CPU微結(jié)構(gòu)內(nèi)部信息通過(guò)側(cè)信道向宏觀計(jì)算機(jī)體系結(jié)構(gòu)的泄漏。

  8、一句話教訓(xùn)

  設(shè)計(jì)CPU追求速度快是理所當(dāng)然的,但速度和安全性之間要有平衡點(diǎn),微結(jié)構(gòu)無(wú)論怎樣追求高速優(yōu)化,屁股要擦干凈,不要向宏觀體系結(jié)構(gòu)泄漏內(nèi)部信息。

  1965年intel創(chuàng)世人之一、時(shí)任仙童半導(dǎo)體公司電子工程師的戈登摩爾提出了摩爾定律,對(duì)人類的計(jì)算之路的快速進(jìn)步做出了預(yù)言。過(guò)去二十年,人類在互聯(lián)網(wǎng)的帶動(dòng)下,信息化發(fā)展一路狂奔。這種對(duì)速度的追求一定程度上,透支的是安全的掉隊(duì)。也許這正是一個(gè)重新定義平衡點(diǎn)的時(shí)刻。


本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。