RFC-0008:移除 zx_clock_get 和 zx_clock_adjust

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

定義要淘汰的計畫,然後移除 zx_clock_get 和 zx_clock_adjust syscalls。

問題
變更
作者
審查人員
提交日期 (年/月)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 讀取的核心 UTC 時鐘,以及可使用 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_INFO_THREAD_STATS 主題的 zx_object_get_info 呼叫。這個替代方法不僅提供更多彈性,也更好地與執行緒執行時間做為執行緒屬性相符。
  • 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) 的呼叫可能會使用從 fuchsia.time.Maintenance 取得的讀取/寫入時鐘控點來呼叫 zx_clock_update

我們建議移除 zx_clock_getzx_clock_adjust 的五個步驟:

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

步驟 1:更新說明文件,將 syscalls 標示為已淘汰

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

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

這個步驟正在執行中。fxr/433865 最近將標準語言執行階段 UTC 函式移至使用者空間 UTC 時鐘。這已移除大部分的 zx_clock_get 用法,但長尾仍來自不同存放區的眾多不同呼叫網站。

我們會使用程式碼搜尋功能找出呼叫和 syscalls_zx_clock_get_type_* 區塊,以追蹤進度,在 Global 整合中,消耗這些剩餘用量。這個過程相當漫長,考量到可用的資源,且將上游變更滾動到下游存放區通常可能需要數週或數個月的時間。

如果語言執行階段為 zx_clock_getzx_clock_adjust 提供包裝函式 (例如 Rust 中的 fuchsia_zircon::Time::get 函式),一旦沒有其他用戶端使用,我們就會移除該包裝函式。

步驟 3:停止維護核心世界標準時間時鐘,並移除 zx_clock_adjust

如要在 ZX_CLOCK_UTC 中維持準確的時間,就需要從驅動程式和多個測試元件呼叫 zx_clock_getzx_clock_adjust。步驟 4 之後將無法進行這些呼叫,因此我們停止以獨立步驟維護核心 (世界標準時間)。

在步驟 3 中,我們將移除 ZX_CLOCK_UTC 同步處理,對任何嘗試讀取 ZX_CLOCK_UTC 的用戶端造成當機,並完全移除 zx_clock_adjust 系統呼叫。此系統呼叫只會用於設定世界標準時間,而且只會由少數具有特殊權限的用戶端叫用。

步驟 2 之後,我們應該相信已經沒有其他元件在全域整合中使用 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 系統呼叫時,需要根資源才能變更世界標準時間。這表示需要調整時間的元件也能獲得強大的不相關功能,也就是說,具備根資源的元件有權限可以修改世界標準時間 (無論是否需要這項電源)。

本提案實作後,只有透過 fuchsia.utc.Maintenance 發布的讀取/寫入時鐘控制代碼才能修改 UTC。這類通訊協定只會明確轉送至需要的元件,而且不會連同這個帳號代碼提供額外功能。

隱私權注意事項

這項提案在導入時不會影響隱私權。

本提案將允許移除 UTC 時間做為日後的環境授權程序 (可能會在沒有使用者空間世界標準時間時鐘控點的情況下啟動程序,也無法再存取核心 UTC 時鐘)。這可能有助於加強特定資料處理類型的隱私權。

測試

每個時間管理系統呼叫和仰賴的時間同步處理基礎架構,現在都涵蓋了單元、整合和端對端測試。透過移除兩個系統呼叫和第二個世界標準時間時鐘,可以簡化這些測試。

說明文件

以上實作章節中包含說明文件更新內容。

缺點、替代方案和未知

本提案的成本相當低,我們估計,在 1 至 3 個季度中,我們估計,每週由元件平台和核心團隊的 2 至 3 名工程師進行幾小時的研究。

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

先前的圖片和參考資料

kernel_objects/clock 提供使用者空間時鐘作業的清楚總覽,建議您讀取。