| RFC-0149:FIDL 編碼驗證並非必要 | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 不再需要在 FIDL 編碼期間進行驗證。不過,驗證仍會在解碼期間進行,且編碼期間的填補必須為零。 |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2021-11-19 |
| 審查日期 (年-月-日) | 2022-01-22 |
摘要
不再需要在 FIDL 編碼期間進行驗證。不過,解碼時仍會進行驗證,且編碼時必須將填補歸零。
提振精神
這項 RFC 的動機是放寬設計限制,目前這些限制規定繫結必須在編碼期間驗證。這不代表繫結一定會改變行為,只是限制較少。事實上,在大多數情況下,這些值不太可能因這項 RFC 而變更。
不過,我們不再強制在編碼期間進行驗證,原因如下:
效能:在編碼期間,驗證會產生額外負擔。舉例來說,結構體編碼的快速路徑會縮減為
memcpy,但如果結構體中有需要驗證的列舉欄位,許多繫結就無法採用這個路徑。HLCPP 繫結的效能影響特別顯著,因為這類繫結會走訪要編碼的物件兩次,一次用於編碼,一次用於驗證 (不過,重新設計繫結或許可以避免這種情況)。程式碼大小:驗證邏輯會增加程式碼大小。如果繫結會產生程式碼或使用巨集,程式碼大小的增幅最為顯著,因為驗證邏輯會在輸出內容中重複多次。
利害關係人
主持人:pascallouis
審查者:pascallouis、yifeit、mkember
已諮詢:
azaslavsky
社交:
這份 RFC 已發布在 FEC 討論郵寄清單中。
設計
繫結「可能」或「可能不會」在編碼期間驗證 FIDL 物件。 更準確地說,物件不再需要以某種方式編碼,確保物件在解碼期間一律通過驗證。
繫結「必須」確保編碼後,填補位元組會歸零。 不過,編碼器本身不需要將填補歸零,例如可透過程式設計語言的保證歸零。
繫結「必須」在解碼期間驗證 FIDL 物件。
實作
這項 RFC 目前沒有立即交付項目,繫結目前會驗證 FIDL 物件,且可能會繼續這麼做。不過,繫結日後將可放寬驗證檢查。
效能
效能影響取決於具體用途和繫結。以下列舉幾個驗證對成效的影響:
在 Rust 中,如果結構體包含 15 個 uint8 和 1 個布林值,且啟用布林值驗證,編碼速度會比未啟用驗證時慢 3.2 倍 (52 奈秒)。如果結構體有 254 個 uint8 和 1 個布林值,速度會慢 21 倍 (844 奈秒)。但在 LLCPP 中,相同結構的效能成本微不足道。選擇這個測試案例的原因是,在許多繫結中,結構體、陣列或向量主體中的單一布林值或列舉會阻止
memcpy最佳化。如果進行列舉驗證,在 LLCPP 中編碼 256 個列舉的陣列會慢 2.2 倍 (2.6 微秒),在 Rust 中會慢 1.2 倍 (192 奈秒),在 Go 中則會慢 9 倍 (1.1 微秒)。
驗證會導致 HLCPP 物件的編碼速度減緩 1 到 5 倍。16 個元素的表格編碼速度會慢 1.7 倍 (400 奈秒),訊息標頭則會慢 1.3 倍 (37 奈秒)。
這些測量結果來自搭載 Intel Core i5-7300U CPU @ 2.60GHz 的電腦。 請注意,這些是微型基準,實際效能可能有所不同。
這些基準使用的 CL:
人體工學
繫結人體工學應該不會受到影響。 不過,如果繫結在編碼期間停用驗證,就不會再針對特定失敗模式「快速失敗」,這可能會影響使用者。
回溯相容性
這項異動應該不會影響回溯相容性。
安全性考量
過去的填充位元組會歸零,而非經過驗證,未來也會繼續歸零。這點很重要,因為 FIDL 物件可能會在舊的配置上配置,導致記憶體複製到連線時發生洩漏。對於大多數其他類型的驗證,洩漏風險較不顯著。
系統會執行兩大類驗證。
值限制
布林值、列舉、位元 - 驗證可確保支援這些型別的整數位於預期範圍內。
浮點數 - 浮點數驗證目前不屬於規格的一部分,但繫結可能仍會執行部分驗證,特別是為了避免 NaN 值。
UTF-8 - FIDL 字串是向量,酬載中含有 UTF-8 資料。驗證可確保這些檔案採用 UTF-8 編碼。
這類型的欄位通常由使用者透過繫結 API 指派。驗證可確保使用者透過 API 提供有效輸入內容,且沒有其他形式的非預期錯誤 (例如記憶體損毀) 變更值。請注意,記憶體損毀錯誤可能發生在處理物件的任何階段,因此期望這類錯誤會被 (例如) 布林值驗證機制偵測到,某種程度上是任意的。
- 大小限制 - 特定物件 (例如表格) 的大小有限制。
傳輸作業必須遵守特定大小限制,例如管道傳輸作業的 64k 訊息大小限制,可避免訊息大小無限擴增。因此,這通常不是需要立即解決的問題,在到達解碼器之前不必處理。
州/省錯誤
非必要類型視為選用類型:基本上就是缺少酬載的非必要類型。
信封內嵌位元 - 信封含有欄位,可指出資料是否應內嵌儲存。信封大小可能 <= 4 個位元組,應內嵌儲存,但缺少內嵌位元標記。
向量不存在,但計數不為零 - 編碼期間絕不會發生這種情況。
如果未在到達解碼器之前發現這些問題,都不會造成重大負面影響。這些問題通常也是 FIDL 實作中的內部問題,可透過其他方式確保正確性。
結論
雖然需要考慮安全性問題,但這類錯誤通常可在解碼端而非編碼端偵測到,因為資訊洩漏的風險很低。
隱私權注意事項
不會影響隱私權。
測試
這項 RFC 實施後,測試需求通常會減少。
說明文件
為解決這個問題,您需要更新 FIDL 繫結規格。
缺點、替代方案和未知事項
限制越多,彈性就越少,這是自然而然的取捨。就驗證而言,限制越多,宣稱的安全性效益就越高,而彈性則可改善效能和程式碼大小。這項 RFC 認為安全性優勢並不大,FIDL 應優先移除這項需求。
移除這項規定後,繫結可選擇保留或移除現有的編碼端驗證。 實際上,繫結應會盡可能移除這項驗證,但部分繫結可能會繼續在偵錯模式中進行驗證,以便及早發現問題。
既有技術和參考資料
無