Home » Posts tagged "patch"

讀書時間:Spectre 的攻擊方式

上次寫了 Meltdown 攻擊的讀書心得 (參考「讀書時間:Meltdown 的攻擊方式」),結果後來中獎狂流鼻水,加上 Spectre 用的手法就更複雜,慢慢看的情況就拖到最近才看完... 這邊就以讀者看過 Meltdown 那篇心得的前提來描述 Spectre。

Spectre 的精華在於 CPU 支援 branch prediction 與 out-of-order execution,也就是 CPU 遇到 branch 時會學習怎麼跑,這個資訊提供給 out-of-order execution 就可以大幅提昇執行速度。可以參考以前在「CPU Branch Prediction 的成本...」提到的效率問題。

原理的部份可以看這段程式碼:

這類型程式碼常常出現在現代程式的各種安全檢查上:確認 x 沒問題後再實際將資料拉出來處理。而我們可以透過不斷的丟 x 值進去,讓 CPU 學到以為都是 TRUE,而在 CPU 學壞之後,突然丟進超出範圍的 x,產生 branch misprediction,但卻已經因為 out-of-order execution 而讓 CPU 執行過 y = ... 這段指令,進而導致 cache 的內容改變。

然後其中讓人最驚豔的攻擊,就是論文示範了透過瀏覽器的 JavaScript 就能打的讓人不要不要的...

圖片裡,上面這段是 JavaScript 程式碼,下面則是 Chrome V8JIT 後轉成的 assembly (這是 AT&T style):

可以從這段程式碼看到,他想要透過這段 JavaScript 取出本來無法存取到的祕密值 index,然後透過 probeTable 得知 cache 的變化。

在這樣的攻擊下,你就可以取得這個 process 裡可以看到的空間,甚至極端的 case 下有可能是 kernel space (配合 Meltdown 的條件)。

不過如果你不能跑 JavaScript 也沒關係,Spectre 的論文裡也提供各種變形方式提供攻擊。像是這樣的程式碼也可以被拿來攻擊:

if (false but mispredicts as true)
    read array1[R1]
read [R2]

其中 R1 是有帶有祕密值的 register,當 array[R1] 有 cache 時,讀 [R2] 就有機會比較快,而沒有 cache 時就會比較慢 (這是因為 memory bus 被佔用的關係),在這個情境下就能夠產生 timing attack:

Suppose register R1 contains a secret value. If the speculatively executed memory read of array1[R1] is a cache hit, then nothing will go on the memory bus and the read from [R2] will initiate quickly. If the read of array1[R1] is a cache miss, then the second read may take longer, resulting in different timing for the victim thread.

所以相同道理,利用乘法器被佔用的 timing attack 也可以產生攻擊:

if (false but mispredicts as true)
    multiply R1, R2
multiply R3, R4

在論文裡面提到相當多的方法 (甚至連 branch target buffers (BTB) 都可以拿來用),就麻煩去論文裡看了。現在用 cache 算是很有效的方式,所以攻擊手法主要都是透過 cache 在取得資訊。

Spectre 論文提到的 mitigation (workaround) 是透過 mfencelfence 強制程式碼的順序,但這表示 compiler 要針對所有的 branch 加上這段,對效能影響應該蠻明顯的:

In addition, of the three user-mode serializing instructions listed by Intel, only cpuid can be used in normal code, and it destroys many registers. The mfence and lfence (but not sfence) instructions also appear to work, with the added benefit that they do not destroy register contents. Their behavior with respect to speculative execution is not defined, however, so they may not work in all CPUs or system configurations.

Google 推出的 Retpoline 則是想要避免這個問題。Google 在「Retpoline: a software construct for preventing branch-target-injection」這邊詳細說明了 Retpoline 的原理與方法,採取的方向是控制 speculative execution:

However, we may manipulate its generation to control speculative execution while modifying the visible, on-stack value to direct how the branch is actually retired.

這個方式是抽換掉 jmpcall 兩個指令,以 *%r11 為例,他將 jmp *%r11call *%r11 改成 jmp retpoline_r11_trampolinecall retpoline_r11_trampoline (這邊的 jmp 指的是所有 jump 系列的指令,像是 jz 之類的):

retpoline_r11_trampoline:
  call set_up_target;
capture_spec:        
  pause;
  jmp capture_spec;
set_up_target:
  mov %r11, (%rsp); 
  ret;

藉由抽換 %rsp 內容跳回正確位置,然後也利用這樣的程式結構控制 CPU 的 speculative execution。

而在效能損失上,已經有測試報告出來了。其實並沒有像 Google 說的那麼無痛,還是會因為應用差異而有不同等級的效能損失... 可以看到有些應用其實還是很痛:「Benchmarking Linux With The Retpoline Patches For Spectre」。

下半年新出的 CPU 應該會考慮這些問題了吧,不過不知道怎麼提供解法 @_@

Ubuntu 開始更新 Kernel 了...

這波 CPU 安全問題,UbuntuLinux Kernel 的更新計畫 (workaround patch) 放在「Information Leak via speculative execution side channel attacks (CVE-2017-5715, CVE-2017-5753, CVE-2017-5754 aka Spectre and Meltdown)」這邊。

不是所有版本的 kernel 都有更新,像是我之前跑 4.10 發現這次沒在清單內,就換成 linux-image-generic-hwe-16.04-edge 了... 換完後需要再裝 linux-headers-generic-hwe-16.04-edge,然後把舊的 kernel 都清乾淨,最後 nvidia-387 需要重新編過。

這次苦哈哈啊...

microG 的進展...

留在 tab 上的東西,忘記在哪看到的... microG 發佈了新的專案:「LineageOS for microG」。

microG 是 AndroidGoogle 服務 API 的重新實作 (所以 open source),不像 Open GApps 還是屬於 proprietary software。

這次的事情是 microG 的人 fork 了 LineageOS 專案,因為 LineageOS 專案拒絕 microG 的 signature spoofing patch:

Why do we need a custom build of LineageOS to have microG? Can't I install microG on the official LineageOS?

MicroG requires a patch called "signature spoofing", which allows the microG's apps to spoof themselves as Google Apps. LineageOS' developers refused (multiple times) to include the patch, forcing us to fork their project.

另外也提到了他們覺得拒絕的原因很鳥:

Wait, on their FAQ page I see that they don't want to include the patch for security reasons. Is this ROM unsafe?

No. LineageOS' developers hide behind the "security reasons" shield, but in reality they don't care enough about the freedom of their users to risk to upset Google by giving them an alternative to the Play Services.
The signature spoofing could be an unsafe feature only if the user blindly gives any permission to any app, as this permission can't be obtained automatically by the apps.

Moreover, to further strengthen the security of our ROM, we modified the signature spoofing permission so that only system privileged apps can obtain it, and no security threat is posed to our users.

於是就 fork 了新的專案... 就觀察看看吧。

AWS 的 Patch Manager 支援 Linux

在「Amazon EC2 Systems Manager Patch Manager now supports Linux」這邊 AWS 宣佈了 Patch Manager 支援 Linux 的消息。

目前支援的包括了:

  • Amazon Linux 2014.03 and later (2015.03 and later for 64-bit)
  • Ubuntu Server 16.04 LTS, 14.04 LTS, and 12.04 LTS
  • RHEL 6.5 and later (7.x and later for 64-Bit)

連已經超過 LTS 支援期的 Ubuntu 12.04 都支援了... 不過 CentOS 看起來沒順便支援?

可以設計一些規定 (與組織內規範相關的,像是 approval process) 讓 Patch Manager 決定要怎麼佈:

可以用這個直接處理安全性更新...

cURL 接下來的安全性更新...

cURL 的維護老大放話要大家注意接下來的安全性更新:「An alert on the upcoming 7.51.0 release」。

最少 11 個安全性更新:

This release will bundle no less than _eleven_ security advisories and their associated fixes (unless we get more reported in the time we have left).

由於這些 security issue 的特性,會採取不公開的 branch 修正再 merge 回來,再加上這麼大的數量,對於穩定性的衝擊是未知的:

Merging eleven previously non-disclosed branches into master just before a release is not ideal but done so to minimize the security impact on existing users when the problems get known.

所以目前的規劃是會在 release 的 48 個小時前公開 (希望藉由這封信讓有能力的人一起集中來看),藉此來降低衝擊:

My plan is to merge them all into master and push around 48 hours before release, watch the autobuilds closesly, have a few extra coverity scans done and then fix up what's found before the release.

這安全更新的數量好像有點多 orz

Adobe 居然決定加碼投入資源更新 Linux 上 NPAPI 版的 Flash (也就是舊版 API)

在「Beta News – Flash Player NPAPI for Linux」這邊看到 Adobe 要投入資源處理 LinuxNPAPI 版的 Flash Player...

先前 Linux 下是 NPAPI 與 PPAPI 兩個版本都有 Flash Player,但是 NPAPI 維持在 11.2,只做安全性更新:

Linux users have access to both NPAPI and PPAPI versions of Flash Player. However, for the last four years, the NPAPI version has been held at 11.2 and regularly updated with only security fixes while the PPAPI version (used in Chrome and Chromium based browsers), is in line with the standard Windows and Mac releases.

然後決定加碼讓兩邊同步:

Today we are updating the beta channel with Linux NPAPI Flash Player by moving it forward and in sync with the modern release branch (currently version 23). We have done this significant change to improve security and provide additional mitigation to the Linux community.

Flash Player 你趕快退場啊啊啊...

CloudFlare 提供的 SPDY + HTTP/2 patch 可以在 nginx 1.11 上面跑了...

SPDY 對行動裝置還是很重要,尤其是 Android 裝置在 5.0 之後才有支援 HTTP/2,但在 3.0 之後就有支援 SPDY,也就是超過一半的 Android 用戶只有 SPDY 但沒有 HTTP/2 能力:

查資料的時候發現當初 CloudFlare 提供的 SPDY + HTTP/2 patch 本來只能對 nginx 1.9.7 更新 (參考之前寫的「CloudFlare 放出可以同時支援 HTTP/2 與 SPDY 的 nginx patch」),後來有人再更新到 1.9.15,而在留言的地方也可以看到有人回報在 1.11.0 上面可以跑:「Update NGINX SPDY patch for 1.9.15」:

Works fine against nginx 1.11.0 and OpenSSL 1.0.2h (with ChaCha20 patch). I am building nginx as an Ubuntu 16.04 package.

而最新版 1.11.1 只有一個安全性更新,應該也可以跑... 來找看看會不會有人包 ppa 出來。

CloudFlare 放出可以同時支援 HTTP/2 與 SPDY 的 nginx patch

CloudFlare 放出可以同時支援 HTTP/2SPDYnginx patch:「Open sourcing our NGINX HTTP/2 + SPDY code」。

不過 patch 的版本有點舊:

We've extracted our changes and they are available as a patch here. This patch should build cleanly against NGINX 1.9.7.

如同原文下面 comment 提到的問題,nginx 1.9.7 太舊了 (2015/11/17 放出的版本),到現在有出了不少安全性更新,以及對 HTTP/2 的 bugfix。應該會需要再等官方把新版的 patch 拿出來改之後才能用。

Archives