※ 引述《kira925 (1 2 3 4 疾風炭)》之銘言:
: https://googleprojectzero.blogspot.tw/2018/01/reading-privileged-
: memory-with-side.html?m=1
: https://tinyurl.com/y82aqvbf (縮網址)
: Google:我忍你們很久了
: 以下內容只是粗略看過 有錯誤請指正
: 目前Google找到了三種不同的問題
: 第一種: bounds check bypass 三家都有中獎,針對特殊的BPF JIT Compiler
: (Google的概念測試對象: Intel Xeon/AMD FX/AMD A8/ARM A57)
: 第二種: branch target injection Intel
: (概念測試對象: Intel Xeon)
: 第三種: rogue data cache load Intel
: (概念測試對象: Intel Xeon)
: 不過情節差異大概是 第一種並不是系統預設會去開啟的東西
: 第二與第三是日常的系統指令
: 順帶一提 第一種可能是先天SPEC就有漏洞
: ARM的回應表示Work as Intended不過也承認確實有漏洞存在
: 他們已經準備好對應的更新了(也要做FUCKWIT?)
: ----
: 讓我們繼續看下去
針對第三種,從paper的例子裡大致講一下
1 ; rcx = kernel address
2 ; rbx = probe array
3 retry:
4 mov al, byte [rcx] <--讀取kernel address
5 shl rax, 0xc
6 jz retry
7 mov rbx, qword [rbx + rax] <--user address
第4行,intel在scheduler要issue指令前,沒有確認load是否有權限讀取
等到指令執行完,要retire時才核查權限
但是等到這個時候,後面的指令也都執行完了
第7行的cache line [rbx + rax]從記憶體搬到了cache內
因為[rbx + rax]是位於user可以存取的範圍內
所以之後可以藉由讀取不同cache line,看他是cache hit/miss
來猜測kernel address裡的內容是什麼
至於其他家處理器,在scheduler要issue指令前就確認了權限
因此第4行指令就根本不會執行了,更不用說後面的567行了
舉個白話文的例子來說
未成年的小明到i餐廳點"高級"清酒喝,服務生在點酒時並未確認小明身分證
把清酒加熱後,上給小明時才發現他未成年
雖然小明沒有喝到酒,但是酒早已被加熱了
小明藉由酒溫知道了哪一瓶才是"高級"清酒,並把他偷出來喝掉
至於其他a餐廳,在點酒時就會先確認身分證,服務生自然不會加熱清酒
因此小明永遠不知道a餐廳真正的"高級"清酒是哪一瓶
例子講完了,至於要怎麼修?
那就在scheduler要issue訪存指令前先確認權限阿
根據架構不同,如果權限存放的地方離scheduler有點遠
讀起來多花一點時間,那就把頻率降低一點來meet timing
或者每個存取都多花一個cycle來確認權限囉
--
: https://googleprojectzero.blogspot.tw/2018/01/reading-privileged-
: memory-with-side.html?m=1
: https://tinyurl.com/y82aqvbf (縮網址)
: Google:我忍你們很久了
: 以下內容只是粗略看過 有錯誤請指正
: 目前Google找到了三種不同的問題
: 第一種: bounds check bypass 三家都有中獎,針對特殊的BPF JIT Compiler
: (Google的概念測試對象: Intel Xeon/AMD FX/AMD A8/ARM A57)
: 第二種: branch target injection Intel
: (概念測試對象: Intel Xeon)
: 第三種: rogue data cache load Intel
: (概念測試對象: Intel Xeon)
: 不過情節差異大概是 第一種並不是系統預設會去開啟的東西
: 第二與第三是日常的系統指令
: 順帶一提 第一種可能是先天SPEC就有漏洞
: ARM的回應表示Work as Intended不過也承認確實有漏洞存在
: 他們已經準備好對應的更新了(也要做FUCKWIT?)
: ----
: 讓我們繼續看下去
針對第三種,從paper的例子裡大致講一下
1 ; rcx = kernel address
2 ; rbx = probe array
3 retry:
4 mov al, byte [rcx] <--讀取kernel address
5 shl rax, 0xc
6 jz retry
7 mov rbx, qword [rbx + rax] <--user address
第4行,intel在scheduler要issue指令前,沒有確認load是否有權限讀取
等到指令執行完,要retire時才核查權限
但是等到這個時候,後面的指令也都執行完了
第7行的cache line [rbx + rax]從記憶體搬到了cache內
因為[rbx + rax]是位於user可以存取的範圍內
所以之後可以藉由讀取不同cache line,看他是cache hit/miss
來猜測kernel address裡的內容是什麼
至於其他家處理器,在scheduler要issue指令前就確認了權限
因此第4行指令就根本不會執行了,更不用說後面的567行了
舉個白話文的例子來說
未成年的小明到i餐廳點"高級"清酒喝,服務生在點酒時並未確認小明身分證
把清酒加熱後,上給小明時才發現他未成年
雖然小明沒有喝到酒,但是酒早已被加熱了
小明藉由酒溫知道了哪一瓶才是"高級"清酒,並把他偷出來喝掉
至於其他a餐廳,在點酒時就會先確認身分證,服務生自然不會加熱清酒
因此小明永遠不知道a餐廳真正的"高級"清酒是哪一瓶
例子講完了,至於要怎麼修?
那就在scheduler要issue訪存指令前先確認權限阿
根據架構不同,如果權限存放的地方離scheduler有點遠
讀起來多花一點時間,那就把頻率降低一點來meet timing
或者每個存取都多花一個cycle來確認權限囉
--
All Comments