本頁將逐步說明 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_etc
syscall (或類似模式)。
核心
- 確保傳送方程序的控制代碼中含有
h1
。 - 確保
h1
參照 VMO。 - 確認
h1
(至少) 擁有MAP
、READ
和WRITE
的權利。 - 將權限限制為只包含
MAP
、READ
和WRITE
,並移除 權利DUPLICATE
、TRANSFER
、GET_PROPERTY
和SET_PROPERTY
。 我們稱這個受限帳號代碼為h2
。這相當於 叫用zx_handle_replace
syscall。 - 使用
h2
而非h1
將訊息排入佇列。
- 確保傳送方程序的控制代碼中含有
FIDL 繫結 (接收端)
- 叫用
zx_channel_read_etc
syscall (或類似模式)。 從傳回的帳號代碼資訊中解除包裝
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
。
- 使用