RFC-0028:處理權限

RFC-0028:處理權限
狀態已接受
區域
  • FIDL
說明

在 FIDL 中為必要或排除的帳號代碼權利加註。

作者
提交日期 (年/月)2019-04-01
審查日期 (年/月)2019-04-18

「太空先鋒」

摘要

針對 FIDL 中的必要或排除帳號代碼權利加註,具體說明如下:

  1. 具備說明權利的機制,可說明所有處理方式的類型 (例如 Protocolrequest<Protocol>handle)

  2. 在序列化時,強制執行權利篩選;也就是說,權利說明會影響遮罩,而遮罩可指出遮罩必須具有一組權利。

  3. 在還原序列化時,強制執行權利驗證和所提供的權利組合。

提振精神

權限是 Fuchsia 中取得權限的工具。在此之前,FIDL 無法說明處理權。數個地方對處理權利有重要限製或規定,目前規範了對方法上的評論說明。

需要的權限限制範例包括唯讀處理序間通訊 (IPC) 或 VMO 控制代碼,以及非執行型 VMO 控制代碼。

所需的適當要求範例包括可寫入的處理序間通訊 (IPC) 控制代碼。

設計

權利限制

這個提案將新的限制類型新增至 FIDL:權利註解。這適用於 FIDL 資料結構和方法參數中的所有處理類型:控制代碼、通訊協定,以及通訊協定要求。

您可以為已分類的帳號代碼宣告指定權利限制:handle<*subtype*, *RC*>。權利本身僅可在特定帳號代碼子類型情境下有意義,因此無法在純控點中指定。如果未在帳號代碼中指定權利限制,則將以相同的權利轉寄 (不會改變現有行為)。

例子:

handle<vmo, zx.rights.READ | zx.rights.WRITE> 需要讀取和寫入,但傳送給用戶端時,系統會移除任何其他權限

handle<vmo> 未指定權利,將現有權利轉交給他人

「必須」為每個正確限制指定至少一個右側限制 (例如 handle<vmo, > 無效)。

無法為伺服器和用戶端通訊協定端點 (myprotocolrequest<myprotocol>) 指定權利限制。這些端點一律會將權限 zx.TRANSFER | zx.WAIT | zx.INSPECT | zx.WRITE | zx.READ | zx.SIGNAL | zx.SIGNAL_PEER 和子類型設為管道。如果需要自訂權限 (例如無法移動的通訊協定),則可使用 handle<*channel*, *RRC, ORC*>。(使用範本可能會進一步調整,我們會在未來的 FTP 中討論)。

權利限制「必須」遵循「預設拒絕」政策。您必須明確列出所有權利。

語法

處理權限限制是位元類型的運算式,可透過位元運算子指定。在上述範例中,| 是位元或運算子。語法應為一般性,並適用於 FIDL 語言中其他位元類型的值。zx 程式庫會提供位元定義 zx.rights 的全部權限。

雖然重複 zx.rights.[*right*] 的權利規格相當冗長,但在日後的 FTP 中,則可以縮短這個值,因此視為不在 FTP 的涵蓋範圍內。

繫結

繫結必須藉由刪除訊息並使用 epitaph ZX_ERR_ACCESS_DENIED 關閉管道,以回應附帶錯誤所需權利的控制接收和去序列化。

繫結「必須」在無法序列化、刪除訊息和禁止傳送的情況下,以不正確的權利,針對控點的序列化作業做出回應。繫結也必須透過 ZX_ERR_BAD_STATE 關閉管道。

預設設定

沒有預設的帳號代碼權限。此處的理由如下:

  • 預設設定有不明確的行為,可能會因物件類型而不一致。 使用者不會公開說明指定物件的預設權限為何。

  • 預設值不建議使用精細的處理權利,因為在編寫 FIDL 定義時,很容易不考量權利。

  • 如果有預設值,則許多適合候選的物件類型不會有權利或最大權限。「正確預設值」上限會限制變更在這個 FTP 中的有效性,但如果沒有正確預設值,效果會等同於不使用預設值。兩者都沒有幫助,

重複使用帳號代碼聲明

沒有預設值的後果是,指定權利可能十分冗長。 為了改善這種情況,我們可以使用別名功能,為整個帳號代碼宣告命名 (即「使用」關鍵字)。

using readable_vmo = handle<vmo, zx.READ>

另一個方法是允許權利限制的別名 (例如 zx.READ | zx.WRITE 的「io」別名),但這可以提供一層間接指引,以隱瞞權限,尤其是在廣泛使用時。允許在物件層級指定別名,將使用量限制在相同類型的位置。

可參數化

我們想建立一般訊息,包含權限限制可以參數化的頻道。

舉例來說,假設 fuchsia.mem.Buffer 包含 handle<vmo>。您應該可以說有限制的 C 流動 fuchsia.mem.Buffer:C 以限制 handle<vmo>

我們從這裡踏出一般化的類型別名,可以提供範本的簡介,進一步滿足這項需求。雖然這個提案不在本提案的討論範圍內,但進行相關工作時也必須將此要求納入考量。

導入策略

接收的訊息應仰賴 zx_channel_read_etc 系統呼叫,在呼叫點提供權利資訊。繫結會使用權限資訊來驗證所需權利是否存在,並濾除除了所需權限以外的任何其他取得權利。

傳送訊息時應依賴 zx_channel_write_etc,這樣會降低指定權利組合的權利,並驗證是否具備所有必要權利。如果驗證失敗,系統會傳回 ACCESS_DENIED。收到這則回應後,繫結將負責關閉管道。為了比對現有行為,ZX_HANDLE_OP_MOVE 將用於這項系統呼叫,相當於呼叫 zx_handle_replace 再呼叫 zx_channel_write。如未指定權利,ZX_RIGHT_SAME_RIGHTS 將取代權利。

我們正在設計一個提供詳細實作文件的意圖,

人體工學

長期來看,這是一項人體工學的改善。在 FIDL 中一律以標準方式完成權利文件和檢查,而不是臨時註解和檢查。

說明文件與範例

須將說明文件變更至:

回溯相容性

ABI 相容性

權限變更「不得」破壞 ABI 相容性。

來源相容性

權限變更「可能」破壞來源相容性。不過,這是非預期的程式碼相容性,如果繫結作者選擇這個路徑,應清楚記錄。

新增必要的權限

與訊息收件者端的回溯相容性,它只提供更多能力,因此具備額外的必要權利。然而,在訊息傳送者端,新增必要的權利是回溯不相容的變更,因為現在必須在傳送前存在。

移除必要權限

傳送端與傳送端可以回溯相容,可移除必要權利,但無法回溯相容。接收者現在不會收到預期中的訊息。

新增選擇性權限

可回溯相容於新增選用權限。

移除選填權限

傳送端與傳送端可以回溯相容,可以移除選用的權利,但回溯不相容。收件者現在不會收到先前已收到的通訊內容。

環境假設

這個模型的部署過程可能會失敗,舉例來說,用戶端可能會假設透過連線收到的所有 VMO 皆可對應,即使伺服器無意提供這項保證。

其中一個看來這個狀態是這個 FTP 的完整動機:移除此廣泛且隱含的合約。

效能

Microbenchmark 顯示 zx_channel_write_etczx_channel_read_etc 的效能非常相似。如果是具有 1 個控制代碼的 64 位元組訊息,zx_channel_write/zx_channel_read 需要 962ns,而 zx_channel_write_etc/zx_channel_read_etc 則接收 1000 毫秒。

讀取或寫入控點時所需的處理陣列會從 256 個位元組 (ZX_CHANNEL_MAX_MSG_HANDLES * sizeof(zx_handle_t)) 增加至 1,024 個位元組 (ZX_CHANNEL_MAX_MSG_HANDLES * sizeof(zx_handle_info_t))。同樣地,在寫入控點時分配的堆疊陣列,將從 256 個位元組增加到 1280 個位元組 ((ZX_CHANNEL_MAX_MSG_HANDLES * sizeof(zx_handle_disposition)))。

為使堆疊分配的上限為 256 個位元組,如果其過大 (超過 16 個用於讀取的控點或超過 12 個寫入處理),我們必須使用堆積配置資料表。做為本次變更的一部分,我們會查看訊息大小和處理資料表的合併堆疊分配需求 (我們現在只考慮訊息大小)。

安全性

這是安全性改善項目。進而更準確地稽核 API 介面。這項工具會將權限檢查移到繫結中,與所有呼叫網站的相同檢查項目相比,評論品質較佳。

舉例來說,一旦權利已完全用盡,就更容易稽核所有轉移可執行 VMO 擁有權的位置。如今這已變得困難。

測試

每個繫結實作都應進行單元測試。

這項功能的推出也應確保 FIDL 通訊協定經過修改以使用這項功能測試新功能。

缺點、替代方案和未知

缺點:將公開 API 納入考量

在某些情況下,這項功能會「雜訊」。在一般執行系統時,可能不會取得遺漏的權限路徑。但仍會使用公用系統 API 中的實際狀態

我們認為這裡的費用令人明確且精確,而妥善使用別名就足以滿足大多數需求。

考慮試想可能避免或減少的問題有兩種類別:

  1. 因權限不相容而中斷:可能從來源極大發生失敗 (如果再次轉移控點,也可能會在其他程序中向下游)。

  2. 未記錄的假設會造成相容性問題:部分用戶端/伺服器傳遞的控點可能會超出所需權限,導致對等端必須依賴這些權利而造成相容性問題,前提是這些假設存在錯誤。

我們瞭解,直接說出權利內容並不令人煩心,但也可用來為能力輸入資訊。

替代做法:權利的下限和上限

初始設計針對權利的下邊界和上限 (例如「沒有執行右側」或「可寫入右側」)。從安全性的角度來看,Fuchsia 應針對所有功能 (與權限) 採用「預設拒絕」政策。

因此,如果能力 (或右側) 未明確提及,就不應授予該功能。元件資訊清單已採用此方式進行沙箱作業,理想情況下,FIDL API 應屬於這樣。

可能還希望額外明確表達「非必要權利」,亦即不一定提供的權利。

因此,從限制語法的觀點來看,也就是在編寫 FIDL API 時輸入的人物類型,我們的目標是列出權利,並將部分列為選用項目。

請注意,從限制語意的觀點來看,需要在 JSON IR 中表示,並透過繫結實作的內容,此語法變更會繼續表達下下限和上限檢查。

必要來源相容性

在 Fuchsia 中,權利通常以 uint32 表示,且權利的值隨時可能變更。因此,預期 FIDL 中的權利值變動似乎並不合理,因為這不會明顯導致產生的原始碼變更。不過,在某些情況下,可能會破壞來源相容性;例如在有指定權利的情況下,就會產生特定方法 (例如 write()),因此本例為 zx.rights.WRITE。因此,我們未規定權限變更不會破壞來源相容性。