本頁說明 Android 如何處理平台無線 (OTA) 更新的政策相容性問題,因為新的平台 SELinux 設定可能與舊的供應商 SELinux 設定不同。
物件擁有權和標籤
每個物件都必須明確定義擁有權,才能將平台和供應商政策分開。舉例來說,如果供應商政策標籤 /dev/foo
和平台政策標籤 /dev/foo
在後續的 OTA 中,有未定義的行為 (例如意外拒絕),或更嚴重的是啟動失敗,在 SELinux 中,這會顯示為標籤衝突。裝置節點只能有一個標籤,該標籤會解析為最後套用的標籤。因此:
- 需要存取未成功套用標籤的程序會失去資源存取權。
- 取得檔案存取權的程序可能會中斷,因為建立的裝置節點有誤。
凡是具有 SELinux 標籤的物件 (包括屬性、服務、程序、檔案和通訊端),都可能發生平台與供應商標籤之間的衝突。為避免發生這些問題,請清楚定義這些物件的擁有權。
型別/屬性命名空間
除了標籤衝突外,SELinux 類型和屬性名稱也可能發生衝突。SELinux 不允許重複宣告相同型別和屬性。如果政策含有重複的聲明,編譯就會失敗。為避免型別和屬性名稱發生衝突,強烈建議所有供應商宣告都以 vendor_
前置半形字元開頭。舉例來說,供應商應使用 type vendor_foo, domain;
,而非 type foo, domain;
。
檔案擁有權
由於平台和供應商政策通常會為所有檔案系統提供標籤,因此要避免檔案發生衝突並不容易。與型別命名不同,檔案的命名空間並不實用,因為其中許多檔案都是由核心建立。為避免發生這類衝突,請按照本節的檔案系統命名指引操作。如果是 Android 8.0,這些是建議,並無技術上的強制規定。日後,供應商測試套件 (VTS) 將會強制執行這些建議。
系統 (/system)
只有系統映像檔必須透過 file_contexts
、service_contexts
等為 /system
元件提供標籤。如果在供應商政策中加入 /system
元件的標籤,可能無法進行僅限架構的 OTA 更新。
供應商 (/vendor)
AOSP SELinux 政策已標記平台互動的 vendor
分區部分,因此可為平台程序編寫 SELinux 規則,以便與 vendor
分區部分通訊或存取這些部分。範例:
/vendor path | 平台提供的標籤 | 平台程序 (視標籤而定) |
---|---|---|
/vendor(/.*)?
|
vendor_file
|
架構中的所有 HAL 用戶端,例如 ueventd 。
|
/vendor/framework(/.*)?
|
vendor_framework_file
|
dex2oat 、appdomain 等。
|
/vendor/app(/.*)?
|
vendor_app_file
|
dex2oat 、installd 、idmap 等。
|
/vendor/overlay(/.*)
|
vendor_overlay_file
|
system_server 、zygote 、idmap 等。
|
因此,在 vendor
分區中標記其他檔案時,必須遵守特定規則 (透過 neverallows
強制執行):
vendor_file
必須是vendor
分區中所有檔案的預設標籤。平台政策規定必須這樣做,才能存取直通 HAL 實作項目。- 透過供應商政策在
vendor
分區中新增的所有exec_types
都必須具備vendor_file_type
屬性。這項限制會透過 neverallow 強制執行。 - 為避免日後與平台/架構更新發生衝突,請勿在
vendor
分區中標記exec_types
以外的檔案。 - 針對 AOSP 識別的相同程序 HAL,所有程式庫依附元件都必須標示為
same_process_hal_file.
Procfs (/proc)
/proc
中的檔案只能使用 genfscon
標籤標示。在 Android 7.0 中,平台和供應商政策都使用 genfscon
為 procfs
中的檔案加上標籤。
建議:僅限平台政策標籤 /proc
。
如果供應商程序需要存取 /proc
中的檔案,且這些檔案目前標示為預設標籤 (proc
),供應商政策不應明確標示這些檔案,而應使用一般 proc
類型,為供應商網域新增規則。這樣一來,平台更新就能配合日後透過 procfs
公開的 Kernel 介面,並視需要明確標示。
Debugfs (/sys/kernel/debug)
Debugfs
可在 file_contexts
和 genfscon
中加上標籤。在 Android 7.0 至 Android 10 中,平台和供應商標籤都是 debugfs
。
在 Android 11 中,debugfs
無法在正式版裝置上存取或掛接。裝置製造商應移除 debugfs
。
Tracefs (/sys/kernel/debug/tracing)
Tracefs
可在 file_contexts
和 genfscon
中加上標籤。在 Android 7.0 中,只有平台標籤 tracefs
。
建議:只有平台可以標示 tracefs
。
Sysfs (/sys)
/sys
中的檔案可能會同時使用 file_contexts
和 genfscon
標示。在 Android 7.0 中,平台和供應商都會使用 genfscon
為 sysfs
中的檔案加上標籤。
建議:平台可能會標示非裝置專用的 sysfs
節點。否則只有供應商可以標記檔案。
tmpfs (/dev)
/dev
中的檔案可能會在 file_contexts
中加上標籤。在 Android 7.0 中,平台和供應商標籤檔案都位於此處。
最佳化建議:供應商只能標記 /dev/vendor
中的檔案 (例如 /dev/vendor/foo
、/dev/vendor/socket/bar
)。
Rootfs (/)
/
中的檔案可能會在 file_contexts
中加上標籤。在 Android 7.0 中,平台和供應商標籤檔案都位於此處。
建議:只有系統可以在 /
中標示檔案。
資料 (/data)
資料標記方式是結合 file_contexts
和 seapp_contexts
。
最佳化建議:禁止在外部使用供應商標籤。
/data/vendor
只有平台可以標記 /data
的其他部分。
Genfs 標籤版本
從 2025 年 4 月的供應商 API 級別開始,使用 genfscon
在 system/sepolicy/compat/plat_sepolicy_genfs_ver.cil
中指派的較新 SELinux 標籤,對於舊版 vendor
分割區為選用項目。這樣一來,舊版 vendor
分區就能保留現有的 SEPolicy 實作項目。這項設定由 Makefile 變數 BOARD_GENFS_LABELS_VERSION
控制,該變數儲存在 /vendor/etc/selinux/genfs_labels_version.txt
中。
範例:
-
在供應商 API 級別 202404 中,
/sys/class/udc
節點預設標示為sysfs
。 -
從供應商 API 級別 202504 開始,
/sys/class/udc
會標示為sysfs_udc
。
不過,/sys/class/udc
可能會由使用 API 層級 202404 的vendor
分區使用,無論是預設的 sysfs
標籤或供應商專屬標籤都可能。無條件將 /sys/class/udc
標示為 sysfs_udc
可能會導致與這些 vendor
分區不相容。勾選 BOARD_GENFS_LABELS_VERSION
後,平台會繼續使用舊版 vendor
分區的標籤和權限。
BOARD_GENFS_LABELS_VERSION
可以大於或等於供應商 API 級別。舉例來說,使用 API 級別 202404 的 vendor
分區可以將 BOARD_GENFS_LABELS_VERSION
設為 202504,採用 202504 推出的新標籤。請參閱
202504 專屬 genfs 標籤清單。
標記 genfscon
節點時,平台必須考量舊版 vendor
分區,並視需要導入相容性備援機制。平台可以使用平台專屬程式庫查詢 genfs 標籤版本。
-
在原生平台,請使用
libgenfslabelsversion
。如需libgenfslabelsversion
的標頭檔案,請參閱genfslabelsversion.h
。 -
在 Java 中,請使用
android.os.SELinux.getGenfsLabelsVersion()
。
平台公共政策
平台 SELinux 政策分為私有和公開。平台公開政策包含的類型和屬性一律適用於供應商 API 層級,可做為平台和供應商之間的 API。這項政策會提供給供應商政策撰寫者,讓供應商建構供應商政策檔案,並與平台專屬政策合併,為裝置產生完整運作的政策。平台公開政策定義於 system/sepolicy/public
。
舉例來說,在供應商的環境中,代表初始化程序的 vendor_init
類型定義於 system/sepolicy/public/vendor_init.te
下方:
type vendor_init, domain;
供應商可以參考 vendor_init
型別,編寫自訂政策規則:
# Allow vendor_init to set vendor_audio_prop in vendor's init scripts
set_prop(vendor_init, vendor_audio_prop)
相容性屬性
SELinux 政策是來源和目標類型之間,針對特定物件類別和權限的互動。受 SELinux 政策影響的每個物件 (例如程序、檔案) 只能有一種型別,但該型別可能有多個屬性。
這項政策主要以現有類型撰寫,這裡的 vendor_init
和 debugfs
都是型別:
allow vendor_init debugfs:dir { mounton };
這是因為政策是根據所有型別編寫而成。不過,如果供應商政策和平台政策使用特定類型,且特定物件的標籤只在其中一項政策中變更,另一項政策可能包含先前獲得或失去存取權的政策。舉例來說,假設平台政策將 sysfs 節點標示為 sysfs
:
/sys(/.*)? u:object_r:sysfs:s0
供應商政策會授予 /sys/usb
的存取權,標示為:
sysfs
:
allow vendor_init sysfs:chr_file rw_file_perms;
如果平台政策變更為將 /sys/usb
標示為 sysfs_usb
,供應商政策會維持不變,但由於缺少新 sysfs_usb
類型的政策,vendor_init
會失去 /sys/usb
的存取權:
/sys/usb u:object_r:sysfs_usb:s0
為解決這個問題,Android 導入了版本化屬性的概念。在編譯期間,建構系統會自動將供應商政策中使用的平台公開型別,轉換為這些已加入版本的屬性。這項翻譯功能會透過對應檔案啟用,將已加上版本的屬性與平台的一或多個公開類型建立關聯。
舉例來說,假設 /sys/usb
標示為 sysfs
,且 2025 年 4 月的供應商政策授予 vendor_init
存取 /sys/usb
的權限。在這種情況下:
-
供應商政策會寫入規則
allow vendor_init sysfs:chr_file rw_file_perms;
,因為/sys/usb
在 202504 平台政策中標示為sysfs
。建構系統編譯供應商政策時,會自動將規則轉換為allow vendor_init_202504 sysfs_202504:chr_file rw_file_perms;
。屬性vendor_init_202504
和sysfs_202504
分別對應至vendor_init
和sysfs
類型,這些是平台定義的類型。 -
建構系統會產生識別資訊對應檔
/system/etc/selinux/mapping/202504.cil
。由於system
和vendor
分區都使用相同的202504
版本,因此對應檔案包含從type_202504
到type
的身分對應。舉例來說,vendor_init_202504
對應至vendor_init
,sysfs_202504
對應至sysfs
:(typeattributeset sysfs_202504 (sysfs)) (typeattributeset vendor_init_202504 (vendor_init)) ...
當版本從 202504 升級至 202604 時,系統會在 system/sepolicy/private/compat/202504/202504.cil
下建立 202504 vendor
分區的新對應檔案,並安裝至 202604 或更新版本 system
分區的 /system/etc/selinux/mapping/202504.cil
。如先前所述,這個對應檔案一開始會包含身分對應。如果 202604 平台政策新增 sysfs_usb
的標籤 /sys/usb
,對應檔案會更新,將 sysfs_202504
對應至 sysfs_usb
:
(typeattributeset sysfs_202504 (sysfs sysfs_usb)) (typeattributeset vendor_init_202504 (vendor_init)) ...
這項更新可讓轉換後的供應商政策規則 allow
vendor_init_202504 sysfs_202504:chr_file rw_file_perms;
自動授予新 sysfs_usb
類型的存取權 vendor_init
。
為維持與舊版 vendor
分區的相容性,每當新增公開型別時,該型別必須對應至對應檔案 system/sepolicy/private/compat/ver/ver.cil
中的至少一個版本化屬性,或列於 system/sepolicy/private/compat/ver/ver.ignore.cil
下方,說明先前供應商版本中沒有相符的型別。
平台政策、供應商政策和對應檔案的組合,可讓系統在不更新供應商政策的情況下進行更新。此外,系統會自動將屬性轉換為版本化屬性,因此供應商政策不必處理版本化作業,可繼續使用公開型別。
system_ext 公開和產品公開政策
從 Android 11 開始,system_ext
和 product
分區可將指定公開型別匯出至 vendor
分區。與平台公開政策相同,供應商政策會使用自動轉換為版本化屬性的類型和規則,例如從 type
轉換為 type_ver
,其中 ver 是 vendor
分區的供應商 API 層級。
如果 system_ext
和 product
分區是根據相同的平台版本 ver,建構系統會產生基本對應檔案至 system_ext/etc/selinux/mapping/ver.cil
和 product/etc/selinux/mapping/ver.cil
,其中包含從 type
到 type_ver
的身分對應。供應商政策可透過版本化屬性 type_ver
存取 type
。
如果只更新 system_ext
和 product
分區 (例如從 ver 更新至 ver+1 或更新版本),但 vendor
分區仍為 ver,供應商政策可能會失去 system_ext
和 product
分區的存取權。為避免中斷,system_ext
和 product
分區應提供從具體型別到 type_ver
屬性的對應檔案。如果合作夥伴支援 ver vendor
分區 (使用 ver+1 或更新版本 system_ext
和 product
分區),則須負責維護對應檔案。
如要將對應檔案安裝至 system_ext
和 product
分區,裝置實作人員或供應商應採取下列行動:
- 從 ver
system_ext
和product
分區 將產生的基本對應檔案複製到來源樹狀結構。 - 視需要修改對應檔案。
-
將對應檔案安裝至 ver+1 (或更新版本) 和
product
分割區。system_ext
舉例來說,假設 202504 system_ext
分區有一個名為 foo_type
的公開型別。然後,202504 system_ext
分區中的 system_ext/etc/selinux/mapping/202504.cil
會如下所示:
(typeattributeset foo_type_202504 (foo_type)) (expandtypeattribute foo_type_202504 true) (typeattribute foo_type_202504)
如果 bar_type
已新增至 202604 system_ext
,且 bar_type
應對應至 202504 foo_type
分區,則 202504.cil
可從 (typeattributeset foo_type_202504 (foo_type))
更新至 (typeattributeset foo_type_202504 (foo_type bar_type))
,然後安裝至 202604 system_ext
分區。vendor
202504 vendor
分區可以繼續存取 202604 system_ext
的 foo_type
和 bar_type
。
Android 9 的屬性變更
升級至 Android 9 的裝置可以使用下列屬性,但搭載 Android 9 的裝置不得使用。
違規者屬性
Android 9 包含下列網域相關屬性:
data_between_core_and_vendor_violators
. 所有網域的屬性,這些網域違反不得在vendor
和coredomains
之間透過路徑共用檔案的規定。平台和供應商程序不應使用磁碟上的檔案進行通訊 (ABI 不穩定)。建議:- 供應商代碼應使用
/data/vendor
。 - 系統不應使用
/data/vendor
。
- 供應商代碼應使用
system_executes_vendor_violators
。所有系統網域 (init
和shell domains
除外) 的屬性,都違反不得執行供應商二進位檔的規定。執行供應商二進位檔時,API 不穩定。平台不應直接執行供應商二進位檔。建議:- 這類對供應商二進位檔的平台依附元件必須位於 HIDL HAL 後方。
或
coredomains
需要存取供應商二進位檔的vendor
應移至coredomain
分區,並停止成為coredomains
。
- 這類對供應商二進位檔的平台依附元件必須位於 HIDL HAL 後方。
不受信任的屬性
代管任意程式碼的不受信任應用程式不應存取 HwBinder 服務,但可存取被視為足夠安全,可供這類應用程式存取的服務 (請參閱下方的安全服務)。主要原因有二:
- HwBinder 伺服器不會執行用戶端驗證,因為 HIDL 目前不會公開呼叫端 UID 資訊。即使 HIDL 確實公開這類資料,許多 HwBinder 服務不是在應用程式層級以下運作 (例如 HAL),就是不得依據應用程式 ID 進行授權。因此,為確保安全,預設假設是每個 HwBinder 服務都會將所有用戶端視為同樣有權執行服務提供的作業。
- HAL 伺服器 (HwBinder 服務的子集) 包含的程式碼,安全問題發生率高於
system/core
元件,且可存取堆疊的較低層 (一路到硬體),因此增加規避 Android 安全性模型的機會。
安全服務
安全服務包括:
same_process_hwservice
。這些服務 (依定義) 會在用戶端的程序中執行,因此與程序執行的用戶端網域具有相同的存取權。coredomain_hwservice
。這些服務不會造成與原因 #2 相關的風險。hal_configstore_ISurfaceFlingerConfigs
。這項服務專為任何網域設計。hal_graphics_allocator_hwservice
。這些作業也由surfaceflinger
Binder 服務提供,應用程式可存取這項服務。hal_omx_hwservice
。這是mediacodec
Binder 服務的 HwBinder 版本,應用程式可存取此服務。hal_codec2_hwservice
。這是hal_omx_hwservice
的新版本。
可用的屬性
所有不安全的 hwservices
都具有 untrusted_app_visible_hwservice
屬性。對應的 HAL 伺服器具有 untrusted_app_visible_halserver
屬性。搭載 Android 9 的裝置「不得」使用 untrusted
屬性。
建議:
- 不信任的應用程式應改為與系統服務通訊,再由系統服務與供應商 HIDL HAL 通訊。舉例來說,應用程式可以與
binderservicedomain
對話,然後mediaserver
(即binderservicedomain
) 會與hal_graphics_allocator
對話。或
- 需要直接存取
vendor
HAL 的應用程式應有自己的供應商定義 sepolicy 網域。
檔案屬性測試
Android 9 包含建構時間測試,可確保特定位置的所有檔案都具有適當的屬性 (例如,sysfs
中的所有檔案都具有必要的 sysfs_type
屬性)。
SELinux 內容標籤
為支援平台和供應商 sepolicy 的區別,系統會以不同方式建構 SELinux 內容檔案,確保兩者分開。
檔案內容
Android 8.0 針對 file_contexts
導入下列變更:
- 為避免在啟動期間裝置上產生額外的編譯負擔,
file_contexts
不會以二進位形式存在。而是可讀取的規則運算式文字檔,例如{property, service}_contexts
(7.0 之前的版本就是如此)。 file_contexts
分成兩個檔案:plat_file_contexts
- Android 平台
file_context
,除了/vendor
分區的標籤必須精確標示,確保 sepolicy 檔案正常運作外,其他部分沒有裝置專屬標籤。 - 必須位於裝置的
system
分割區/system/etc/selinux/plat_file_contexts
,並在啟動時由init
與供應商file_context
一併載入。
- Android 平台
vendor_file_contexts
- 裝置專屬
file_context
是透過合併裝置Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
所指向目錄中的file_contexts
所建構。 - 必須安裝在
vendor
分割區的/vendor/etc/selinux/vendor_file_contexts
中,並在啟動時由init
與平台file_context
一併載入。
- 裝置專屬
房源背景資訊
在 Android 8.0 中,property_contexts
分成兩個檔案:
plat_property_contexts
- Android 平台
property_context
,沒有裝置專屬標籤。 - 必須位於
system
分區的/system/etc/selinux/plat_property_contexts
,並在啟動時由init
與供應商property_contexts
一併載入。
- Android 平台
vendor_property_contexts
- 裝置專屬的
property_context
是透過合併裝置Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
所指向目錄中的property_contexts
所建構。 - 必須位於
vendor
分區的/vendor/etc/selinux/vendor_property_contexts
,並在啟動時由init
與平台property_context
一併載入
- 裝置專屬的
服務環境
在 Android 8.0 中,service_contexts
會拆分成下列檔案:
plat_service_contexts
- Android 平台專屬
service_context
,適用於servicemanager
。service_context
沒有裝置專屬標籤。 - 必須位於
system
分區的/system/etc/selinux/plat_service_contexts
,並在啟動時由servicemanager
與供應商service_contexts
一併載入。
- Android 平台專屬
vendor_service_contexts
- 裝置專屬
service_context
是透過合併裝置Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
所指向目錄中的service_contexts
所建構。 - 必須位於
vendor
分區的/vendor/etc/selinux/vendor_service_contexts
,並在啟動時由servicemanager
與平台service_contexts
一併載入。 - 雖然
servicemanager
會在啟動時尋找這個檔案,但如要讓TREBLE
裝置完全符合規範,vendor_service_contexts
「不得」存在。這是因為vendor
和system
程序之間的所有互動都必須經過hwservicemanager
/hwbinder
。
- 裝置專屬
plat_hwservice_contexts
- Android 平台
hwservice_context
,沒有裝置專屬標籤。hwservicemanager
- 必須位於
system
分區的/system/etc/selinux/plat_hwservice_contexts
,並在啟動時與vendor_hwservice_contexts
一併由hwservicemanager
載入。
- Android 平台
vendor_hwservice_contexts
- 裝置專屬
hwservice_context
是透過合併裝置Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
所指向目錄中的hwservice_contexts
所建構。 - 必須位於
vendor
分區的/vendor/etc/selinux/vendor_hwservice_contexts
,並在啟動時由hwservicemanager
與plat_service_contexts
一併載入。
- 裝置專屬
vndservice_contexts
- 裝置專屬
service_context
,是透過合併在裝置Boardconfig.mk
中BOARD_SEPOLICY_DIRS
所指向目錄中找到的vndservice_contexts
所建構。vndservicemanager
- 這個檔案必須位於
vendor
分區的/vendor/etc/selinux/vndservice_contexts
,並在啟動時由vndservicemanager
載入。
- 裝置專屬
Seapp 內容
在 Android 8.0 中,seapp_contexts
分成兩個檔案:
plat_seapp_contexts
- Android 平台
seapp_context
,且沒有裝置專屬變更。 - 必須位於
system
分區,且位於/system/etc/selinux/plat_seapp_contexts.
- Android 平台
vendor_seapp_contexts
- 平台
seapp_context
的裝置專屬擴充功能,是透過合併裝置Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
所指向目錄的seapp_contexts
所建構。 - 必須位於
vendor
分區的/vendor/etc/selinux/vendor_seapp_contexts
。
- 平台
MAC 權限
在 Android 8.0 中,mac_permissions.xml
分成兩個檔案:
- 月台
mac_permissions.xml
- Android 平台
mac_permissions.xml
,且沒有特定裝置的變更。 - 必須位於
system
分區,且位於/system/etc/selinux/.
- Android 平台
- 非平台
mac_permissions.xml
- 平台專屬的裝置擴充功能,由裝置
Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
所指向目錄的mac_permissions.xml
建構而成。mac_permissions.xml
- 必須位於
vendor
分區,且位於/vendor/etc/selinux/.
- 平台專屬的裝置擴充功能,由裝置