自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
供應商初始化
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
初始化程序幾乎沒有限制權限,並使用系統和供應商分區的輸入指令碼,在開機程序期間初始化系統。這類存取權會導致 Treble 系統/供應商分割出現重大漏洞,因為供應商指令碼可能會指示初始化程序存取不屬於穩定系統供應商應用程式二進位介面 (ABI) 的檔案、屬性等。
供應商初始化功能旨在利用獨立的安全強化 Linux (SELinux) 網域 vendor_init
來執行 /vendor
中的指令,並使用供應商專屬權限。
機制
供應商初始化會在啟動程序初期,使用 SELinux 內容 u:r:vendor_init:s0
分支初始化的子程序。此 SELinux 內容的權限比預設初始化內容少得多,且其存取權僅限於特定廠商或穩定系統廠商 ABI 的檔案、屬性等。
初始化會檢查載入的每個指令碼,查看其路徑是否以 /vendor
開頭,如果是的話,就會標記該指令碼,指出其指令必須在供應商初始化內容中執行。每個初始化內建項目都會加上布林註解,指出指令是否必須在供應商初始化子程序中執行:
- 大多數存取檔案系統的指令都會標註為在供應商初始化子程序中執行,因此會受到供應商初始化 SEPolicy 的管制。
- 影響內部初始化狀態的大部分指令 (例如啟動和停止服務) 會在正常的初始化程序中執行。這些指令會知道供應商指令碼會呼叫它們,以便自行處理非 SELinux 權限。
init 的主要處理迴圈包含檢查,如果指令已註解要在供應商子程序中執行,且來自供應商指令碼,則該指令會透過程序間通訊 (IPC) 傳送至供應商初始子程序,該子程序會執行指令並將結果傳回至 init。
使用供應商初始化
供應商初始化功能預設為啟用,且其限制會套用至 /vendor
區段中的所有初始化指令碼。如果供應商的指令碼已不再存取系統專屬檔案、屬性等,供應商初始化應對供應商保持透明。
不過,如果特定供應商指令碼中的指令違反供應商初始化限制,則指令會失敗。失敗的指令會在內核記錄中顯示一行訊息 (可透過 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
中授予權限,也未透過 neverallow 規則排除權限,則新標籤可能會在裝置專屬的 vendor_init.te
中授予權限。
如果是 Android 9 之前推出的裝置,您可以將 data_between_core_and_vendor_violators
type 屬性新增至裝置專屬的 vendor_init.te
檔案,藉此略過 neverallows 規則。
程式碼位置
供應商初始化 IPC 的大部分邏輯位於 system/core/init/subcontext.cpp。
指令表位於 system/core/init/builtins.cpp 中的 BuiltinFunctionMap
類別,並包含註解,指出指令是否必須在供應商初始子程序中執行。
供應商初始化程序的 SEPolicy 會分散在 system/sepolicy 中的私人 (system/sepolicy/private/vendor_init.te) 和公開 (system/sepolicy/public/vendor_init.te) 目錄。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# Vendor init\n\nThe init process has nearly unrestricted permissions and uses input scripts from\nboth the system and vendor partitions to initialize the system during the boot\nprocess. This access causes a huge hole in the Treble system/vendor split, as\nvendor scripts may instruct init to access files, properties, etc. that don't\nform part of the stable system-vendor application binary interface (ABI).\n\n\n*Vendor init* is designed to close this hole by using a separate\nsecurity-enhanced Linux (SELinux) domain `vendor_init` to run\ncommands found in `/vendor` with vendor-specific permissions.\n\nMechanism\n---------\n\n\nVendor init forks a subprocess of init early in the boot process with the\nSELinux context `u:r:vendor_init:s0`. This SELinux context has\nconsiderably fewer permissions than the default init context and its access is\nconfined to files, properties, etc. that are either vendor-specific or part of\nthe stable system-vendor ABI.\n\n\nInit checks each script it loads to see if its path starts with\n`/vendor` and if so, tags it with an indication that its commands\nmust be run in the vendor init context. Each init builtin is annotated with a\nboolean that specifies whether or not the command must be run in the vendor init\nsubprocess:\n\n- Most commands that access the file system are annotated to run in the vendor init subprocess and are therefore subjected to the vendor init SEPolicy.\n- Most commands that impact internal init state (e.g., starting and stopping services) are run within the normal init process. These commands are made aware that a vendor script is calling them to do their own non-SELinux permissions handling.\n\n\nThe main processing loop of init contains a check that if a command is annotated\nto run in the vendor subprocess and originates from a vendor script, that\ncommand is sent through inter-process communication (IPC) to the vendor init\nsubprocess, which runs the command and sends the result back to init.\n\nUse vendor init\n---------------\n\n\nVendor init is enabled by default and its restrictions apply to all init scripts\npresent in the `/vendor` partition. Vendor init should be transparent\nto vendors whose scripts are already not accessing system only files,\nproperties, etc.\n\n\nHowever, if commands in a given vendor script violate the vendor init\nrestrictions, the commands fail. Failing commands have a line in the kernel\nlog (visible with dmesg) from init indicating failure. An SELinux audit\naccompanies any failing command that failed due to the SELinux policy. Example\nof a failure including an SELinux audit: \n\n```\ntype=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\ninit: 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\n```\n\n\nIf a command fails, there are two options:\n\n- If the command is failing due to an intended restriction (such as if the command is accessing a system file or property), the command must be re-implemented in a Treble-friendly way, going through only stable interfaces. Neverallow rules prevent adding permissions to access system files that aren't part of the stable system-vendor ABI.\n- If the SELinux label is new and isn't already granted permissions in the system `vendor_init.te` nor excluded permissions through the neverallow rules, the new label may be granted permissions in the device-specific `vendor_init.te`.\n\n\nFor devices launching before Android 9, the neverallows rules may be bypassed by\nadding the `data_between_core_and_vendor_violators` typeattribute to\nthe device-specific `vendor_init.te` file.\n\nCode locations\n--------------\n\n\nThe bulk of the logic for the vendor init IPC is in [system/core/init/subcontext.cpp](https://android.googlesource.com/platform/system/core/+/android16-release/init/subcontext.cpp).\n\n\nThe table of commands is in the `BuiltinFunctionMap` class in [system/core/init/builtins.cpp](https://android.googlesource.com/platform/system/core/+/android16-release/init/builtins.cpp)\nand includes annotations that indicate if the command must run in the vendor\ninit subprocess.\n\n\nThe SEPolicy for vendor init is split across the private ([system/sepolicy/private/vendor_init.te](https://android.googlesource.com/platform/system/sepolicy/+/android16-release/private/vendor_init.te))\nand public ([system/sepolicy/public/vendor_init.te](https://android.googlesource.com/platform/system/sepolicy/+/android16-release/public/vendor_init.te))\ndirectories in system/sepolicy."]]