本頁將逐步說明 FIDL 轉移 Zircon 的方式 處理這項功能尤其著重於 「帳號代碼」的意義以及處理權利的驗證方式
情境
假設有一個簡單的用戶端和伺服器透過下列通訊協定進行通訊:
protocol LifeOfAHandle {
Method(resource struct {
h zx.Handle:<VMO, zx.Rights.MAP | zx.Rights.READ | zx.Rights.WRITE>;
}) -> ();
};
假設我們僅從帳號代碼權限中移除 zx.Rights.WRITE,
重新編譯伺服器,而非用戶端。用戶端建立 VMO 後會發生什麼事
並傳送給「Method」?
圖表
在這種情況下,用戶端會以「寄件者」的身分運作,而伺服器的狀態為 接收器。我們使用以下字詞,是因為這會影響 轉移帳號代碼用途如果方法傳回控制代碼,則 步驟反向操作
如需圖表的詳細說明,請參閱下文。
說明
使用者代碼 (傳送者)
- 假設傳送方使用
zx_vmo_create系統呼叫取得 VMO。 傳回的帳號代碼h1對 VMO 有預設權限:DUPLICATE。TRANSFER、READ、WRITE、MAP、GET_PROPERTY和SET_PROPERTY。 - 呼叫
Method,並向其傳遞h1。
- 假設傳送方使用
FIDL 繫結 (傳送者)
將
h1納入指定 FIDL 權利的帳號代碼 類型:MAP、READ和WRITE。這會讓核心瞭解 轉移h1時提供。繫結不知道什麼權利h1(他們不知道該序列是否參照 VMO, 但與權利不同的是,這通常代表在靜態型別系統中 導致使用者不易傳送錯誤的帳號代碼類型)。zx_handle_disposition{ .operation = ZX_HANDLE_OP_MOVE, .handle = h1, .type = ZX_OBJ_TYPE_VMO, .rights = ZX_RIGHT_MAP | ZX_RIGHT_READ | ZX_RIGHT_WRITE, }叫用
zx_channel_write_etcsyscall (或類似模式)。
核心
- 確保傳送方程序的控制代碼中含有
h1。 - 確保
h1參照 VMO。 - 確認
h1(至少) 擁有MAP、READ和WRITE的權利。 - 將權限限制為只包含
MAP、READ和WRITE,並移除 權利DUPLICATE、TRANSFER、GET_PROPERTY和SET_PROPERTY。 我們稱這個受限帳號代碼為h2。這相當於 叫用zx_handle_replacesyscall。 - 使用
h2而非h1將訊息排入佇列。
- 確保傳送方程序的控制代碼中含有
FIDL 繫結 (接收端)
- 叫用
zx_channel_read_etcsyscall (或類似模式)。 從傳回的帳號代碼資訊中解除包裝
h2。與帳號代碼不同 帳號代碼會儲存帳號代碼的「實際」類型和權利 完全按照核心回報的問題顯示zx_handle_info{ .handle = h2, .type = ZX_OBJ_TYPE_VMO, .rights = ZX_RIGHT_MAP | ZX_RIGHT_READ | ZX_RIGHT_WRITE, }取得 FIDL 類型中的預期類型和權利:
MAP和READ。確認
h2具備這些權利 (至少)由於
h2含有非預期的正確WRITE,因此請叫用zx_handle_replace進行 syscall 以取得新控制代碼h3, 權利MAP和READ。
- 叫用
使用者代碼 (接收端)
- 使用
h引數的Method服務,即h3。
- 使用