最近數天內實在歡樂異常,拜Google Project Zero計畫背書之所賜,持續「炎上」火勢越燒越大,還一路延燒「好厝邊」AMD和ARM的Intel處理器漏洞事件,應該是資訊業界時下最夯的熱門話題,為嶄新的2018年打響了擾人清夢的第一砲,而Intel執行長在這極度敏感的心裡關鍵時刻,將手上的持股出清到公司董事會規定的低標,所引發的爭議,更是跳到太平洋也洗不清,反正現在太平洋也沒多乾淨。
總之,唯一可以肯定的是,一路觀察下來,真正有看懂Google那篇官方部落格文的媒體,恐怕僅為鳳毛鱗爪,但惟恐天下不亂大肆散播恐慌,東拼西湊出一篇篇看似連筆者都看不懂的「有字天書」報導者,絕對有如過江之鯽,然後又一票科技文青繼續一如往昔的驚呆了。
但相信各位科科們絕對不會滿足於坊間多數媒體捉風補影繪聲繪影的報導中,僅僅那句比較有意義的「利用處理器預測執行機制,先斬後奏提前存取記憶體,又沒做好權限安全性檢驗的漏洞」和一票看不懂的聖經密碼像KPTI KASLR KAISER Spectre Meltdown等,而是希望能在腦中描繪出整個命案現場的全貌與畫在馬路上的人形粉筆圈,所以你才會勉力爬文爬到這裡。
我們先回到原點,從基本觀念—近代作業系統的兩大重要元素「保護模式」與「虛擬記憶體」—為起點,一步一腳印的踏入迷宮的最深處,最起碼了解為何作業系統修正此漏洞後,那號稱造成最多30%的效能損失,到底兇手是誰,人是誰殺的,誰是在畫面中全身一直塗成黑色還不停奸笑著的黑衣人。
多工作業系統或任何虛擬化環境的兩種基本運作權限
如同現實世界對公用資源的保防措施,為了確保多工作業系統 (或虛擬機器) 的正常運作,隔離不同應用程式 (或作業系統) 所使用的系統資源,免於來自錯誤程式的破壞,確保使用者不會互相干擾,我們必須保護作業系統核心與虛擬機器Hypervisor、系統檔案與共用資源,所以至少需要兩種不同的運作權限:「使用者模式 (User Mode)」 與「系統模式 (System Mode)」。
先回顧作業系統的啟動流程:按下開機按鈕,處理器先從Boot ROM擷取並執行系統自我檢測程式 (也就是BIOS和UEFI的工作),然後從大型儲存媒介讀取OS Loader,再將作業系統核心 (Kernel) 載入至記憶體,接著在系統模式執行作業系統核心,開始載入裝置驅動程式,直到作業系統已經可以完全管理電腦的底層硬體裝置,就進入應用程式執行階段,啟動使用者模式。
此外,可能「動搖國本」更動系統底層狀態的指令,都應該被定義為只能在系統模式執行的「特權指令 (Privileged Instruction)」,如在使用者模式執行,則將觸發處理器的例外處理機制,再經由作業系統的「設陷 (Trap,或稱為軟體中斷)」,決定是否執行該指令,如應用程式透過「系統呼叫 (System Call)」,要求得到更多的記憶體空間或進行I/O存取。
奠定多工作業系統精巧記憶體保護的虛擬記憶體
一般電腦玩家對「虛擬記憶體」的認知多半僅限於「主記憶體不夠時,電腦將塞不下的東西丟到硬碟,然後就開始聽著硬碟發出陣陣的哀號」,但這就太過小看虛擬記憶體對近代多工作業系統那舉足輕重的重要性了,甚至說虛擬記憶體是當代汎用型作業系統的地基也不為過。
由小到大,虛擬記憶體的重點如下:
- 程式不再受限於可用的實體記憶體總量,並將實際上四散各處的實體記憶體位址 (Physical Address),轉化為一整塊連續可用的虛擬記憶體空間,簡化程式開發的工作。
- 所謂的「虛擬位址 (Virtual Address)」也就是應用程式眼中所看到的記憶體位址。值得注意的是,越接近處理器核心的快取記憶體,越傾向使用虛擬位址進行索引 (Index),原因不言可喻。
- 主記憶體只須包含被程式使用到的部份,不必整個塞進去,意味更多程式可一起獨樂樂不如眾樂樂。
- 允許大量的應用程式同時在同一台電腦上執行,並減少載入與置換每個程式的I/O負擔。(不過在記憶體貴的要命的年代,沒事一直聽硬碟慘叫的老玩家可能感受不到)
- 每個行程 (Process) 都享有自己的虛擬位址空間,不同的虛擬頁 (Page) 會映射到不同的實體記憶體位址。
- 提供更精巧的記憶體保護,如透過前述的保護模式、系統呼叫,與虛擬分頁中的權限位元,作業系統可透過改變分頁表 (Page Table) ,對執行中的眾多應用程式號令天下「朕給你的,才是你的,朕不給你的,你不能搶」。如發生分頁錯誤 (Page Fault),應用程式所需要的分頁不位於主記憶體,此時就須啟動例外處理以中斷執行中的行程並「處理後事」。
換言之,經由虛擬記憶體的管理,作業系統核心和應用程式所佔用的實體記憶體位址與分佈方式,並非井水不犯河水,現實上是有可能「水乳交融」在一起的。
此外,為了加速虛擬位址與實體位址之間的轉換,處理器通常內建了一個稱為TLB (Translation Lookaside Buffer)的小型快取記憶體,不同的分頁表管理策略,如同迥異的記憶體存取模式,對其命中率都會產生極大的影響,而且因為TLB算是分頁表的子集合,TLB誤失和分頁錯誤一樣的不好應付,頻繁的「刷洗 (Flush)」TLB內容對整體效能的傷害,有如深度指令管線發生預測執行錯誤般的「火燒摩天樓」一樣的可怕,甚至有過之而無不及。
開始冒煙但尚未起火的關鍵線索
科科們也許已經抱怨著「這些不都是爾孰能詳」的計算機組織基礎知識嗎?但恭喜各位,你們其實已經開始誤入真正的雷區了。
- 既然系統權限已經受到重重保護,為何還會被「僭越」?
- 要如何旁敲側擊出享受分頁表庇蔭的作業系統核心的實體記憶體位址?
- 為何這些作業系統的補洞程式會造成大量TLB Flush,並增加執行系統呼叫的成本?
後面我們就來開始踩地雷,瞧瞧Google團隊是如何對當代非循序執行 (Out-Of-Order Execution) 處理器上下其手,祝各位科科不要被炸上天呀。ㄎㄎ。
4 則回應
可是我完全看不懂這篇想表示的是甚麼....QAQ