RFC-0008:移除 zx_clock_get 和 zx_clock_adjust

RFC-0008:移除 zx_clock_get 和 zx_clock_adjust
狀態已接受
區域
  • 核心
說明

定義淘汰 zx_clock_get 和 zx_clock_adjust 系統呼叫的計畫,然後移除這兩個系統呼叫。

問題
Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2020-10-12
審查日期 (年-月-日)2020-10-29

摘要

我們建議採用五個步驟的程序,淘汰 zx_clock_getzx_clock_adjust 系統呼叫,將剩餘使用者遷移至自 2019 年起推出的替換系統呼叫,最後移除原始系統呼叫。

提振精神

Fuchsia 目前包含兩組獨立的系統呼叫,用於與時間互動:

  1. 原始設計使用 zx_clock_get 讀取核心維護的單調、世界標準時間和執行緒時鐘,並使用 zx_clock_adjust 寫入世界標準時間時鐘。這項設計並未提供任何方法來轉動時鐘、在不同產品上定義其他時鐘,或傳達時鐘狀態。
  2. 在 2019 年,我們新增了 zx_clock_createzx_clock_readzx_clock_updatezx_clock_get_details 系統呼叫,以便執行對時鐘物件的多元管理作業,讓使用者空間定義及維護任意數量的時鐘。zx_clock_get_monotonic 也已新增,可讀取核心的單調時鐘。

Fuchsia 目前定義了兩個不同的世界標準時間時鐘:可使用 zx_clock_get 讀取的核心世界標準時間時鐘,以及可使用 zx_clock_read 讀取的使用者空間世界標準時間時鐘。時間同步系統會嘗試讓這些時鐘保持一致,但由於它們提供不同的功能,因此難免會出現差異。

本提案定義了原始時間系統呼叫的淘汰計畫,完成自 2019 年開始的遷移作業,當時新增了替代系統呼叫的設計。移除這些系統呼叫可解決維護兩種半相容時間管理方式的持續性 (且不斷增加) 作業和認知成本。

實作

zx_clock_getzx_clock_adjust 各自接受 clock_id 引數,用於指定應使用三個可能時間軸中的哪一個。建議您分別考量這三個時間表的遷移作業:

  • ZX_CLOCK_MONOTONIC:對 zx_clock_get(ZX_CLOCK_MONOTONIC) 的呼叫可以直接替換為對 zx_clock_get_monotonic 的呼叫。這個替換的系統呼叫更容易使用,通常也能提供更出色的效能。
  • ZX_CLOCK_THREAD:呼叫 zx_clock_get(ZX_CLOCK_THREAD) 可能會改為呼叫 zx_object_get_info,並使用主題 ZX_INFO_THREAD_STATS。這個替換作業可提供更大的彈性,並可更準確地與執行緒執行時間做為執行緒屬性進行對齊。
  • ZX_CLOCK_UTC - 在 2019 年,系統呼叫 UTC 會由 Fuchsia 平台在使用者空間中管理,而非直接由核心管理。大多數語言執行階段都已修改為讀取使用者空間 UTC 時鐘,因此在大多數情況下,對 zx_clock_get(ZX_CLOCK_UTC) 的呼叫應在語言執行階段中替換為標準 UTC 呼叫。在必要時,您可以使用 zx_utc_reference_get 函式取得唯讀時鐘句柄,以便傳遞至 zx_clock_read。對 zx_clock_adjust(ZX_CLOCK_UTC) 的呼叫可以由對 zx_clock_update 的呼叫取代,使用從 fuchsia.time.Maintenance 取得的讀/寫時鐘句柄。

我們建議您採取五個步驟來移除 zx_clock_getzx_clock_adjust

  1. 更新說明文件,將系統呼叫標示為已淘汰
  2. 將所有已知使用者遷移至替換的系統呼叫
  3. 停止維護核心世界標準時間時鐘並移除 zx_clock_adjust
  4. 從 SDK 中移除 zx_clock_get 宣告
  5. 從 Zircon 中移除 zx_clock_get 實作

步驟 1:更新說明文件,將系統呼叫標示為已淘汰

這個步驟已完成。zx_clock_getzx_clock_adjust 呼叫已清楚標示為已淘汰,說明文件中也包含我們在上述建議的替代解決方案。

步驟 2:將所有已知使用者遷移至替換的系統呼叫

我們正在進行這項作業。fxr/433865 近期將標準語言執行階段 UTC 函式移至使用者空間 UTC 時鐘。這麼做可移除大部分的 zx_clock_get 用法,但仍有長尾效應,因為不同存放區的多個不同呼叫網站仍會使用 zx_clock_get

我們會使用程式碼搜尋功能找出呼叫和 syscalls_zx_clock_get_type_* kcounter,以便追蹤進度,並在 Global Integration 的莖和花瓣中消耗這些剩餘用量。考量到可用的資源,以及將上游變更項目推送至下游存放區通常需要數週或數月的時間,因此這項程序將會相當漫長。

如果語言執行階段在 zx_clock_getzx_clock_adjust 周圍提供包裝函式 (例如 Rust 中的 fuchsia_zircon::Time::get 函式),我們會在沒有其他用戶端使用時移除每個包裝函式。

步驟 3:停止維護核心 UTC 時鐘並移除 zx_clock_adjust

如要在 ZX_CLOCK_UTC 中維持準確的時間,就必須從驅動程式和多個測試元件呼叫 zx_clock_getzx_clock_adjust。在步驟 4 之後,這些呼叫將無法再執行,因此我們會停止將核心 UTC 維護為個別步驟。

在步驟 3 中,我們會移除 ZX_CLOCK_UTC 同步處理功能,導致任何嘗試讀取 ZX_CLOCK_UTC 的用戶端發生當機,並完全移除 zx_clock_adjust 系統呼叫 (這個系統呼叫僅用於設定 UTC,且僅由少數特權用戶端叫用)。

在步驟 2 後,我們應該已確信 Global Integration 中沒有使用 UTC 的元件,但在讀取嘗試時導致用戶端當機,可讓我們快速偵測任何遺漏。

具體來說,我們會:

  1. 移除所有驗證 ZX_CLOCK_UTC 的測試。
  2. 修改 zx_clock_get(ZX_CLOCK_UTC),將來電者標記為違反政策的使用者。
  3. 從即時時鐘驅動程式中移除對 zx_clock_adjust 的呼叫 (並完全移除備用 RTC 驅動程式庫,因為這是其唯一用途)
  4. 完全移除 zx_clock_adjust

步驟 4:從 SDK 中移除 zx_clock_get 宣告

在步驟 3 之後,我們可能已成功移除標頭中對 zx_clock_get 的所有呼叫,但仍需要支援依賴 zx_clock_get 的舊版預先建構二進位檔。在這種情況下,我們會移除 SDK 中的 zx_clock_get 宣告,但不會移除 zircon 實作。在這個階段,任何嘗試使用 zx_clock_get 編譯程式碼的動作都會導致編譯失敗。

如果沒有預先建構的二進位檔會依賴 zx_clock_get,我們會直接進行步驟 5。

步驟 5:從 Zircon 中移除 zx_clock_get 實作

一旦沒有預先建構的二進位檔會依賴 zx_clock_get (由其符號匯入決定),我們就會完全移除 zx_clock_get 和相關文件。

成效

這項提案會鼓勵更廣泛地使用效率更高的 zx_clock_get_monotonic 系統呼叫,並簡化 RTC 驅動程式的作業,進而提升整體系統效能,但提升幅度不大。

安全性考量

這項提案不會影響管理單調或執行緒時間的安全性。

在其他作業系統中,攻擊者已利用 UTC 管理安全漏洞執行各種回溯攻擊。這項提案提供更精細的存取權控管機制,可提升 UTC 時間管理的安全性。

使用 zx_clock_adjust 系統呼叫時,根資源必須變更 UTC 時間。這表示需要調整時間的元件也會獲得強大的無關功能,而這也表示任何具有根資源的元件,無論是否需要此權限,皆可修改 UTC。

這項提案實施後,修改 UTC 的唯一方式,就是透過 fuchsia.utc.Maintenance 分發的讀/寫時鐘句柄。這個通訊協定會明確地只導向需要它的元件,且這些元件不會透過此句柄獲得任何額外功能。

隱私權注意事項

這項提案在實施時不會影響隱私權。

這項提案可讓您在日後移除世界標準時間做為環境權威的功能 (程序可在沒有使用者空間世界標準時間時鐘句柄的情況下啟動,且不會再有存取核心世界標準時間時鐘的權限)。這項功能可能可用於提升特定類型資料處理作業的隱私權。

測試

每個時間管理系統呼叫和依賴這些呼叫的時間同步處理基礎架構,都已納入單元、整合和端對端測試。移除這兩個系統呼叫和第二個世界標準時間時鐘,這些測試將會簡化。

說明文件

說明文件更新內容已納入上述實作部分。

缺點、替代方案和未知事項

這項提案的成本不高,我們估計在 1 到 3 個季度的時間內,元件平台和核心團隊的 2 到 3 名工程師每週可投入幾小時的時間。

替代方案主要圍繞著不清理這項技術債務或減少清理這項技術債務而定;舉例來說,您可以停止維護核心 UTC 時鐘,但不移除相關的系統呼叫。這些替代方案可在短期內降低成本,但長期下來會大幅增加成本。

既有技術與參考資料

kernel_objects/clock 可提供使用者空間時鐘運作的簡要概略,建議您閱讀。