供應商 Init

init 程序幾乎沒有限制的權限,會使用下列來源的輸入指令碼: 在開機期間將系統初始化的系統和供應商分區 上傳資料集之後,您可以運用 AutoML 自動完成部分資料準備工作這樣的使用行為會導致 Treble 系統/廠商分層產生一個大問題, 供應商指令碼可指示 init 存取不會 構成穩定系統供應商應用程式二進位介面 (ABI) 的一部分。

Vendor init 設計成透過單獨的 要執行安全性增強的 Linux (SELinux) 網域 vendor_init 指令在 /vendor 中找到,並具備特定供應商的權限。

機制

廠商會使用 SELinux 結構定義 u:r:vendor_init:s0。這段 SELinux 結構定義 明顯少於預設 init 環境的權限 檔案、資源等項目 穩定的系統廠商 ABI

Init 會檢查每個載入的指令碼,確認路徑的開頭是否為 /vendor,如果有,就會標記其指令並指示其指令 必須在廠商初始化環境中執行。每個 init 內建項目都會加註 布林值,用於指定是否要在廠商初始環境中執行指令 子程序:

  • 存取檔案系統的指令大多會得到註記,以便在供應商中執行 初始化子程序,因此必須遵守供應商 init SEPolicy。
  • 影響內部啟動狀態的大多數指令 (例如啟動和停止指令) 服務) 會在正常的 init 程序內執行。這些指令是在 請注意,廠商指令碼會呼叫他們執行自己的非 SELinux 授予的權限。

init 的主要處理迴圈內含一項檢查,可確認指令是否已加註 要在供應商子程序中執行,並來自供應商指令碼,則 指令會透過處理序間通訊 (IPC) 傳給供應商 init 子程序,負責執行指令並將結果傳回 init。

使用供應商 Init

根據預設,系統會啟用供應商 init,且其限制適用於所有 init 指令碼 存在於 /vendor 分區中。供應商 init 應公開透明 至於指令碼還不是只存取系統檔案的供應商, 屬性等。

但如果指定供應商指令碼中的指令違反供應商 init 方法, 限制,指令就會失敗失敗指令的核心有一行 來自 init 的 log (會顯示 dmesg 字樣),表示失敗。SELinux 稽核 附帶任何因 SELinux 政策而失敗的指令。範例 執行失敗 (包括 SELinux 稽核):

type=1400 audit(1511821362.996:9): avc: denied { search } for pid=540 comm="init" name="nfc" dev="sda45" ino=1310721 scontext=u:r:vendor_init:s0 tcontext=u:object_r:nfc_data_file:s0 tclass=dir permissive=0
init: Command 'write /data/nfc/bad_file_access 1234' action=boot (/vendor/etc/init/hw/init.walleye.rc:422) took 2ms and failed: Unable to write to file '/data/nfc/bad_file_access': open() failed: Permission denied

如果指令失敗,您有以下兩種方法:

  • 如果指令因預期限製而失敗 (例如 命令正在存取系統檔案或屬性),則命令必須 以適合 Treble 的方式重新實作,只瀏覽穩定的介面。 永不允許規則禁止使用者新增存取不屬於系統檔案的權限 隸屬於穩定的系統廠商 ABI。
  • 如果 SELinux 標籤是新的,但尚未在 系統「vendor_init.te」或在從未允許的情況下排除權限 可能就授予了裝置專屬權限 vendor_init.te

針對搭載 Android 9 以下版本的裝置,使用者可能會略過絕允許規則。 將 data_between_core_and_vendor_violators 類型屬性加入 裝置專屬的 vendor_init.te 檔案

程式碼位置

供應商 init IPC 的大量邏輯位於 system/core/init/subcontext.cpp

指令表格位於 system/core/init/builtins.cpp 中的 BuiltinFunctionMap 類別 並包含註解,說明指令是否必須在廠商中執行 init 子程序

供應商 init 的 SEPolicy 可分為私有模式 (system/sepolicy/private/vendor_init.te) 和公開 (system/sepolicy/public/vendor_init.te) 儲存於 system/sepolicy 中的目錄