RFC-0143:User-Top Top-Byte-Ignore

RFC-0143:Userspace Top-Byte-Ignore
狀態已接受
區域
  • 核心
說明

變更核心 ABI 以支援含有標記的使用者空間指標。

變更
作者
審查人員
提交日期 (年/月)2021-11-30
審查日期 (年/月)2021-11-30

摘要

本文件建議對核心 ABI 進行變更,以便支援標記的使用者空間指標。

提振精神

Top-Byte-Ignore (TBI) 是所有 ARMv8.0 CPU 上的一項功能,會導致系統在載入和商店時忽略虛擬位址的頂端位元組。位元 55 則是在位址轉譯前的位元 56-63 擴充。這項功能允許使用 (忽略) 的頂端位元組做為標記或其他頻內中繼資料。TBI 的立即應用之一是在使用者空間中啟用 Hardware-輔助 AddressSanitizer (HWASan),而這類標記會儲存在頂端位元組中,以便追蹤記憶體。

本文件說明核心應如何處理已標記的使用者指標。

雖然 TBI 和 HWASan 是標記指標最為相關的用途,但此設計並不是只涵蓋這些指標。還有其他平台的硬體功能都類似,可支援標記指標。其他使用者空間程式則能將這些標記位元用於自己的特定用途。這個設計應易於一般支援其他具有標記指標的實作,而不需要聚焦於單一使用者應用程式。

術語

這些是本提案會經常使用的一些字詞。有「地址」和「指標」。這些概念類似,但的處理方式不同。基本上,部分系統呼叫是針對地址運作,有些則呼叫指標。

地址

位址是 64 位元整數,代表使用者位址空間邊界內的位置。地址絕不會標記。會操控位址空間的 Syscall 以地址運作。地址的值一律會在位址空間的範圍內 (以 ZX_INFO_VMAR 表示) 限制。

指標

指標是一種程式設計語言的概念,通常用來表示可參照記憶體的位置。每種語言都會定義指標實作及其翻譯為硬體。對於 C/C++,在 HWASan 的結構定義中,指標是一個 64 位元整數,由標記位元和位址位元組成。您可以標記非零的標記位元或未標記 (表示標記位元為零)。存取使用者記憶體的 Syscall 一般會在指標上運作。

標記

標記是指指標的上位元,通常用於中繼資料。在已啟用 TBI 的 ARM 上,標記為 8 位元的寬,由位元 56-63 組成。

待定 (最高位元 - 忽略)

ARM MTEIntel LAM 等其他潛在的硬體功能也支援「忽略」指標上半部部分的方法。除非另有說明,否則本文件中使用的「TBI」一詞代表任何支援忽略標記的一般硬體功能,而不只是 ARM TBI。

設計

核心程式碼應複製硬體行為。您應處理標記,確保核心行為對使用者合理。

以下列舉一些系統啟用 TBI 後的行為:

  1. zx_channel_write 可以接受標記的指標,而呼叫的行為會與未標記指標相同。

  2. 如果處理程序對標記的使用者指標造成網頁錯誤,系統就會解決網頁錯誤,就像是在同一個未標記的指標上發生一樣,但有一個例外狀況。如果錯誤產生 Zircon 例外狀況,例外狀況報告的錯誤指標會包含硬體所保留的原始標記指標。

  3. 為進行未來的喚醒/等待解析,系統會忽略提供指標上的任何標記。換句話說,如果喚醒僅與標記不同的指標,則不論其指定的任何標記為何,仍會喚醒等待該指標的所有等候人員。

  4. 從程序讀取記憶體 (例如使用 zx_process_read_memory) 時,核心會接受「address」做為目前讀取記憶體區塊位置的引數。與軟體偵錯搭配使用,偵錯工具需要將偵錯指標值明確轉譯為位址,以便透過核心 API 讀取。

標記指標 ABI:標記不敏感,但代碼保留

啟用 TBI 後會發生以下情況:

  1. 核心將忽略從 syscalls 收到的使用者指標標記。舉例來說,如果 zx_channel_read 呼叫的緩衝區指標含有標記,其行為會與未標記緩衝區指標相同。

  2. 在接受地址的系統呼叫 (即zx_vaddr_t)。舉例來說,傳遞至 zx_process_read_memory 的虛擬地址無法加上標記。將需要地址的標記指標視為其他無效地址,系統會將其視為其他無效地址。

  3. 當核心接受標記的指標時,無論是透過系統呼叫還是錯誤,核心都會嘗試將標記保留至使用者程式碼日後可能觀察到的程度。舉例來說,如果使用者程式在標記的使用者指標上出錯,如果硬體可以保留該標記,產生的 Zircon 例外狀況報告就會包含該標記。如果硬體不保證能夠保留標記,系統就會刪除標記。如果沒有任何使用者空間可以觀察標記的機制,核心可以自行移除,前提是不會改變系統行為。如果硬體僅保證保留標記的部分保留,則核心可能只會去除未保證保留的位元。

  4. 核心本身一律不會產生標記的指標。舉例來說,透過 zx_vmar_map 對應 VMO 時,核心選取的結果值會是沒有標記的純位址。

  5. 比較使用者空間指標時,核心會忽略任何可能出現的標記。例如,如果執行緒在有標記 A 的指標上等候 (透過 zx_futex_wait),而另一個執行緒正 (透過 zx_futex_wake) 對位址位元相同的指標 (但標記 B 標記) 喚醒,則系統會喚醒等候程序。

已針對全部啟用 ARM64 TBI

TBI 將由核心啟動選項控管。啟用之後,系統會針對所有使用者空間程序啟用 TBI。

偵錯軟體

偵錯工具必須瞭解待定。ARM TBI 不允許在偵錯註冊上設定標記。偵錯工具需要明確簽署最重大的 VA 位元,才能設定偵錯暫存器。

實作

啟動選項會控制使用者位址空間是否已啟用 ARM TBI。如要啟用 ARM TBI,請在翻譯控制註冊器 (EL1) 中設定 TBI0TBI1 位元。

除了啟用/停用 TBI 之外,我們還需要確認現有的 sys 呼叫可正確處理指標/位址。只有少數地方會處理使用者指標 (例如 user_ptr),因此實作本提案所需的變更相對較小。

我們可以透過新的系統功能,向使用者表明執行的 TBI 類型。我們可以引入全新的地圖項目種類 ZX_FEATURE_KIND_ADDRESS_TAGGING,並支援代表位址標記的新功能位元,例如適用於 ARM TBI 的 ZX_ARM64_FEATURE_ADDRESS_TAGGING_TBI

效能

效能影響應該可以忽略,而且現有的微基準將用於驗證。

測試

我們需要測試以下項目:

  1. 檢查使用不同標記指標的 Sys 呼叫,並有效忽略這些標記。

  2. 對已標記與未標記的指標 (非標記敏感行為) 進行喚醒。

  3. 如果在標記指標上出錯,標記會在例外狀況 (代碼保留行為) 中保留。

  4. 任何讓使用者空間得知核心 TBI 的行為,例如是否有系統功能,或是會傳回熱門位元忽略量的查詢。

  5. 驗證標記的指標會遭到預期地址的系統呼叫拒絕。

如果不支援 TBI,則必須略過這些測試。

說明文件

本 RFC 中所有關於標記指標 ABI 的說明文件都已記錄在這份 RFC 中。實作這個方法後,我們可能需要更新部分 Zircon 說明文件,指定 syscall 不接受標記的引數。

保證保留代碼一定程度的 Syscall 需要記錄,以指定要保留及移除的位元。

缺點、替代方案和未知

TBI 切換精細程度

我們有兩種層級可以控制 TBI 的範圍:全域和每個程序。每項程序方法都涉及一些機制,可在程序建立時或開始時間切換 TBI。這會需要新的 syscall、引數或位元標記,藉此進行更多測試,並可能會導入新的錯誤或安全性問題,而這需要時間才能發現。提供程序切換鈕非常昂貴

全域外接切換裝置較不複雜,有助於避免許多「不明不明項目」的問題,而必須實作執行階段切換。此外,如果系統的所有應用程式都感知 TBI 或不具備 TBI 感知,而非混用兩者,那麼您可能還比較安全。

在使用者模式中去除標記

這包括在傳送至核心之前,先移除 syscall 層中的所有標記。如此一來,您便無需變更核心,而核心在標記方面仍可保持診斷。其中一個問題是關於使用者空間指標的錯誤處理。如果標記的指標上產生錯誤,則每個使用者空間處理常式會負責刪除標記。

支援其他位址模式

本提案應夠靈活,以考慮「忽略」頂端位元的其他硬體功能。我們近期並未計劃支援這些功能,但開啟狀態需要盡量避免變更。

ARM Memory Tagging Extension (MTE)

MTE 是一種以 TBI 為基礎的功能,用於尋找不良的記憶體存取情形。記憶體標記的運作方式是將每個配置和指標與特定標記值建立關聯。如果指標上的標記與嘗試存取的配置不同,代表因標記不符而導致記憶體存取問題不佳。使用 MTE 時,這個標記是儲存在指標頂端位元組的 4 位元值。

在此 ABI 下,當啟用 MTE 時,標記會參照指標的前 8 位元,但只有 56-59 位元會收到錯誤,因為硬體只能保證保留這 4 位元。

Intel 線性位址遮蓋 (LAM)

LAM 是 x86 即將推出的功能,會在載入/商店時遮蓋指標中前 7 或 16 位元的內容。這會透過修改 CR3 註冊表在全域控制。與 TBI 不同的是,LAM 不會保留頁面錯誤中的任何標記位元。

先前的圖片和參考資料

在 AArch64 Linux 中標記虛擬位址

本提案的設計靈感來自在 Linux 加上標記的位址 ABI,因此大多數核心行為應該在接受標記指標時仍不受影響。其中一個主要差異在於 Linux 支援在每個執行緒切換 ABI,而本提案的目標則是在建構/啟動時間全面切換 ABI。此外,Linux 一律會啟用 ARM TBI,而 ARM TBI 也是由相同的建構選項控管。