本文介紹 Android 如何處理平台 OTA 的策略相容性問題,其中新平台 SELinux 設定可能與舊供應商 SELinux 設定不同。
基於 Treble 的 SELinux 策略設計考慮了平台和供應商策略之間的二元區別;如果供應商分區產生依賴關係,例如platform
< vendor
< oem
,則該方案會變得更加複雜。
在 Android 8.0 及更高版本中,SELinux 全域策略分為私有和公用元件。公共組件由策略和相關基礎設施組成,保證可用於平台版本。該策略將向供應商策略編寫者公開,以使供應商能夠建立供應商策略文件,該文件與平台提供的策略相結合,可為設備產生功能齊全的策略。
- 對於版本控制,導出的平台公共策略將被編寫為屬性。
- 為了便於策略編寫,導出的類型將在策略建置過程中轉換為版本化屬性。公共類型也可以直接用於供應商上下文文件提供的標籤決策。
Android 維護平台策略中匯出的具體類型與每個平台版本的對應版本屬性之間的對應。這確保了當物件被標記為類型時,它不會破壞先前版本中平台公共策略所保證的行為。透過使每個平台版本的映射檔案保持最新來維護此映射,該檔案保留公共策略中匯出的每種類型的屬性成員資格資訊。
物件所有權和標籤
在 Android 8.0 及更高版本中自訂策略時,必須明確定義每個物件的所有權,以保持平台和供應商策略分開。例如,如果供應商標記/dev/foo
且平台隨後在後續 OTA 中標記/dev/foo
,則會出現未定義的行為。對於 SELinux,這表現為標籤衝突。設備節點只能有一個標籤,該標籤解析為最後應用的標籤。因此:
- 需要存取未成功應用的標籤的進程將失去對資源的存取權。
- 由於創建了錯誤的設備節點,存取該檔案的程序可能會中斷。
系統屬性也可能存在命名衝突,導致系統上出現未定義的行為(以及 SELinux 標籤)。對於具有 SELinux 標籤的任何對象,包括屬性、服務、流程、檔案和套接字,平台和供應商標籤之間都可能發生衝突。為了避免這些問題,請明確定義這些物件的所有權。
除了標籤衝突之外,SELinux 類型/屬性名稱也可能發生衝突。類型/屬性名稱衝突總是會導致策略編譯器錯誤。
類型/屬性命名空間
SELinux 不允許相同類型/屬性的多個聲明。具有重複聲明的策略將無法編譯。為了避免類型和屬性名稱衝突,所有供應商聲明都應以np_
開頭的命名空間。
type foo, domain; → type np_foo, domain;
系統屬性和過程標籤所有權
避免標籤衝突的最佳解決方案是使用屬性命名空間。為了在重命名或新增匯出平台屬性時輕鬆識別平台屬性並避免名稱衝突,請確保所有供應商屬性都有自己的前綴:
財產種類 | 可接受的前綴 |
---|---|
控制屬性 | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor. |
可讀寫 | vendor. |
只讀 | ro.vendor. ro.boot. ro.hardware. |
執著的 | persist.vendor. |
供應商可以繼續使用ro.boot.*
(來自核心命令列)和ro.hardware.*
(明顯與硬體相關的屬性)。
init rc 檔案中的所有供應商服務都應該有vendor.
用於非系統分區的init rc 檔案中的服務。類似的規則適用於供應商屬性的 SELinux 標籤(供應商屬性的vendor_
)。
文件所有權
防止文件衝突具有挑戰性,因為平台和供應商策略通常都為所有文件系統提供標籤。與類型命名不同,檔案的命名空間並不實用,因為其中許多檔案是由核心建立的。為了防止這些衝突,請遵循本節中的檔案系統命名指南。對於 Android 8.0,這些是沒有技術強制執行的建議。將來,這些建議將由供應商測試套件(VTS) 強制執行。
系統(/系統)
只有系統映像必須透過file_contexts
、 service_contexts
等為/system
元件提供標籤。如果在/vendor
策略中新增/system
元件的標籤,則可能無法進行僅框架的 OTA 更新。
供應商(/供應商)
AOSP SELinux 策略已經標記了與平台互動的vendor
分區的部分,這使得能夠為平台進程編寫 SELinux 規則,以便能夠對話和/或存取vendor
分區的部分。例子:
/vendor 路徑 | 平台提供的標籤 | 平台流程取決於標籤 |
---|---|---|
/vendor(/. * )? | vendor_file | Framework、 ueventd 等中的所有 HAL 用戶端 |
/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 實現。 - 透過供應商 SEPolicy 在
vendor
分區中新增的所有新exec_types
必須具有vendor_file_type
屬性。這是透過 neverallows 強制執行的。 - 為了避免與未來的平台/框架更新發生衝突,請避免在
vendor
分區中標記除exec_types
以外的檔案。 - AOSP 識別的相同進程 HAL 的所有庫相依性必須標記為
same_process_hal_file.
進程 (/proc)
/proc
中的檔案可以僅使用genfscon
標籤進行標記。在 Android 7.0 中,平台和供應商策略都使用genfscon
來標記procfs
中的檔案。
建議:僅平台策略標籤/proc
。如果vendor
程序需要存取/proc
中目前標有預設標籤 ( proc
) 的文件,則供應商策略不應明確標記它們,而應使用通用proc
類型為供應商網域新增規則。這使得平台更新能夠適應透過procfs
公開的未來核心接口,並根據需要明確標記它們。
調試(/sys/kernel/debug)
可以在file_contexts
和genfscon
中標記Debugfs
。在 Android 7.0 到 Android 10 中,平台和供應商都標記為debugfs
。
在 Android 11 中,無法在生產裝置上存取或安裝debugfs
。設備製造商應刪除debugfs
。
Tracefs(/sys/kernel/debug/tracing)
Tracefs
可以在file_contexts
和genfscon
中標記。在Android 7.0中,只有平台標籤為tracefs
。
建議:只有平台可以標記tracefs
。
系統檔案系統 (/sys)
/sys
中的檔案可以使用file_contexts
和genfscon
進行標記。在 Android 7.0 中,平台和供應商都使用file_contexts
和genfscon
來標記sysfs
中的檔案。
建議:平台可能會標記不特定於設備的sysfs
節點。否則,只有供應商可以標記文件。
tmpfs (/dev)
/dev
中的檔案可能會在file_contexts
中進行標記。在 Android 7.0 中,平台和供應商標籤檔案均位於此處。
建議:供應商可以只標記/dev/vendor
中的檔案(例如/dev/vendor/foo
、 /dev/vendor/socket/bar
)。
根檔案系統 (/)
/
中的檔案可以在file_contexts
中標記。在 Android 7.0 中,平台和供應商標籤檔案均位於此處。
建議:只有系統可以在/
中標記檔案。
數據(/數據)
資料透過file_contexts
和seapp_contexts
的組合進行標記。
建議:禁止在/data/vendor
之外新增供應商標籤。只有平台可以標記/data
的其他部分。
相容性屬性
SELinux 策略是來源類型和目標類型之間針對特定物件類別和權限的交互作用。受 SELinux 策略影響的每個物件(進程、檔案等)可能只有一種類型,但該類型可能有多個屬性。
策略主要是根據現有類型編寫的:
allow source_type target_type:target_class permission(s);
這是有效的,因為策略是根據所有類型的知識編寫的。但是,如果供應商策略和平台策略使用特定類型,並且特定物件的標籤僅在其中一個策略中發生更改,則另一個策略可能包含獲得或失去先前依賴的存取權限的策略。例如:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
可以改為:
File_contexts: /sys/A u:object_r:sysfs_A:s0
儘管供應商策略保持不變,但由於缺乏新sysfs_A
類型的策略, v_domain
將失去存取權限。
透過根據屬性定義策略,我們可以為底層物件提供一個類型,該類型具有與平台和供應商程式碼的策略相對應的屬性。可以對所有類型執行此操作,以有效地建立屬性策略,其中從不使用特定類型。實際上,這僅對於平台和供應商之間重疊的策略部分是必需的,這些部分被定義並提供為作為供應商策略的一部分構建的平台公共策略。
將公共策略定義為版本化屬性可以滿足兩個策略相容性目標:
- 確保供應商代碼在平台更新後繼續運作。透過向與供應商程式碼所依賴的物件相對應的物件的具體類型添加屬性來實現,從而保留存取權限。
- 否決政策的能力。透過將策略集清晰地描述為屬性來實現,一旦它們對應的版本不再受支持,就可以將其刪除。開發可以在平台中繼續,因為知道舊策略仍然存在於供應商策略中,並且在升級時/如果升級時將自動刪除。
策略可寫性
為了實現策略開發不需要了解特定版本變更的目標,Android 8.0 包含平台公共策略類型及其屬性之間的對應。類型foo
映射到屬性foo_v N
,其中N
是目標版本。 vN
對應於PLATFORM_SEPOLICY_VERSION
建置變量,格式為MM.NN
,其中MM
對應於平台 SDK 編號, NN
是平台 sepolicy 特定版本。
公共策略中的屬性沒有版本控制,而是作為 API 存在,平台和供應商策略可以在該 API 上構建,以保持兩個分區之間的介面穩定。平台和供應商策略編寫者都可以繼續以現在的方式編寫策略。
平台公共政策導出為allow source_foo target_bar: class perm ;
包含在供應商政策中。在編譯期間(包括對應的版本),它會轉換為將進入裝置供應商部分的策略(以轉換後的通用中間語言 (CIL) 所示):
(allow source_foo_vN target_bar_vN (class (perm)))
由於供應商政策永遠不會領先於平台,因此它不應該關心以前的版本。然而,平台策略需要知道供應商策略有多早,包括其類型的屬性,並設定與版本化屬性相對應的策略。
政策差異
如果不跨版本差異將屬性對應到類型,則透過在每個類型末尾新增_v N
來自動建立屬性不會執行任何操作。 Android 維護屬性版本之間的對應以及類型到這些屬性的對應。這是在前面提到的映射檔案中使用語句完成的,例如 (CIL):
(typeattributeset foo_vN (foo))
平台升級
以下部分詳細介紹了平台升級的場景。
相同類型
當物件不更改策略版本中的標籤時,就會發生這種情況。這對於來源類型和目標類型是相同的,並且可以透過/dev/binder
看到,它在所有版本中都標記為binder_device
。它在轉變後的政策中表現為:
binder_device_v1 … binder_device_vN
從v1
→ v2
升級時,平台策略必須包含:
type binder_device; -> (type binder_device) (in CIL)
在 v1 映射檔 (CIL) 中:
(typeattributeset binder_device_v1 (binder_device))
在 v2 映射檔 (CIL) 中:
(typeattributeset binder_device_v2 (binder_device))
在 v1 供應商政策 (CIL) 中:
(typeattribute binder_device_v1) (allow binder_device_v1 …)
在 v2 供應商政策 (CIL) 中:
(typeattribute binder_device_v2) (allow binder_device_v2 …)
新類型
當平台添加新類型時會發生這種情況,這可能在添加新功能或策略增強期間發生。
- 新功能。當該類型標記先前不存在的物件(例如新的服務流程)時,供應商代碼以前沒有直接與其交互,因此不存在相應的策略。與該類型相對應的新屬性在先前版本中沒有屬性,因此不需要在針對該版本的映射檔案中包含條目。
- 政策強化。當類型表示策略強化時,新類型屬性必須連結回與前一個屬性相對應的屬性鏈(類似於前面將
/sys/A
從sysfs
變更為sysfs_A
的範例)。供應商程式碼依賴允許存取sysfs
的規則,並且需要包含該規則作為新類型的屬性。
從v1
→ v2
升級時,平台策略必須包含:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
在 v1 映射檔 (CIL) 中:
(typeattributeset sysfs_v1 (sysfs sysfs_A))
在 v2 映射檔 (CIL) 中:
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
在 v1 供應商政策 (CIL) 中:
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
在 v2 供應商政策 (CIL) 中:
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
刪除的類型
當刪除類型時會發生這種(罕見)情況,當底層物件出現以下情況時可能會發生這種情況:
- 仍然存在,但獲得了不同的標籤。
- 已被平台刪除。
在策略放鬆期間,類型被刪除,並且標有該類型的物件被賦予不同的、已經存在的標籤。這表示屬性映射的合併:供應商代碼仍然必須能夠透過其曾經擁有的屬性來存取底層對象,但係統的其餘部分現在必須能夠透過其新屬性來存取它。
如果切換到的屬性是新的,則重新標記與新類型的情況相同,只不過當使用現有標籤時,新增舊屬性新類型會導致其他物件也用該類型標記可以重新存取。這本質上是平台所做的事情,並且被認為是保持相容性的可接受的權衡。
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
範例版本 1:折疊類型(刪除 sysfs_A)
從v1
→ v2
升級時,平台策略必須包含:
type sysfs; (type sysfs) (in CIL)
在 v1 映射檔 (CIL) 中:
(typeattributeset sysfs_v1 (sysfs)) (type sysfs_A) # in case vendors used the sysfs_A label on objects (typeattributeset sysfs_A_v1 (sysfs sysfs_A))
在 v2 映射檔 (CIL) 中:
(typeattributeset sysfs_v2 (sysfs))
在 v1 供應商政策 (CIL) 中:
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
在 v2 供應商政策 (CIL) 中:
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
範例版本 2:完全刪除(foo 類型)
從v1
→ v2
升級時,平台策略必須包含:
# nothing - we got rid of the type
在 v1 映射檔 (CIL) 中:
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
在 v2 映射檔 (CIL) 中:
# nothing - get rid of it
在 v1 供應商政策 (CIL) 中:
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
在 v2 供應商政策 (CIL) 中:
(typeattribute sysfs_v2) (allow sysfs_v2 …)
新類別/權限
當平台升級引入先前版本中不存在的新策略元件時,就會發生這種情況。例如,當 Android 新增了建立新增、尋找和列出權限的servicemanager
物件管理器時,想要向servicemanager
註冊的供應商守護程式需要不可用的權限。在Android 8.0中,只有平台策略可以新增新的類別和權限。
為了允許供應商策略創建或擴展的所有網域不受阻礙地使用新類,平台策略需要包含類似於以下內容的規則:
allow {domain -coredomain} *:new_class perm;
這甚至可能需要允許存取所有介面(公共策略)類型的策略,以確保供應商映像獲得存取權限。如果這導致不可接受的安全性策略(因為 servicemanager 變更可能會導致這種情況),則可能會強制供應商升級。
刪除的類別/權限
當刪除物件管理器(例如ZygoteConnection
物件管理器)時會出現這種情況,且不應導致問題。物件管理器類別和權限可以保留在策略中定義,直到供應商版本不再使用它。這是透過將定義新增至相應的映射檔案來完成的。
新/重新標籤類型的供應商定制
新的供應商類型是供應商政策制定的核心,因為需要它們來描述新的流程、二進位檔案、設備、子系統和儲存的資料。因此,必須允許創建供應商定義的類型。
由於供應商策略始終是設備上最舊的,因此無需自動將所有供應商類型轉換為策略中的屬性。該平台不依賴供應商政策中標記的任何內容,因為該平台對此一無所知;但是,該平台將提供用於與標有這些類型(例如domain
、 sysfs_type
等)的物件進行互動的屬性和公共類型。為了使平台繼續與這些物件正確交互,必須正確應用屬性和類型,並且可能需要將特定規則新增至可自訂的網域(例如init
)。
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
應該會移動到供應商分區,從而不再是coredomain
。
- 此類對供應商二進位檔案的平台依賴性必須位於 HIDL HAL 後面。
不受信任的屬性
託管任意程式碼的不受信任的應用程式不應存取 HwBinder 服務,除非那些被認為足夠安全的應用程式可以從此類應用程式存取(請參閱下面的安全服務)。造成這種情況的兩個主要原因是:
- HwBinder 伺服器不執行客戶端身份驗證,因為 HIDL 目前不公開呼叫者 UID 資訊。即使 HIDL 確實公開了此類數據,許多 HwBinder 服務要么在低於應用程式(例如 HAL)的層級運行,要么不得依賴應用程式身分進行授權。因此,為了安全起見,預設假設是每個 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
屬性)。
平台公共政策
平台公共策略是符合Android 8.0架構模型的核心,而不是單純地維護v1和v2平台策略的聯合。供應商暴露於平台策略的子集,其中包含可用類型和屬性以及這些類型和屬性的規則,這些規則隨後成為供應商策略的一部分(即vendor_sepolicy.cil
)。
類型和規則在供應商產生的策略中自動轉換為attribute_v N
,以便所有平台提供的類型都是版本化屬性(但屬性未版本化)。該平台負責將其提供的特定類型映射到適當的屬性中,以確保供應商策略繼續發揮作用,並包含為特定版本提供的規則。平台公共政策和供應商政策的結合滿足了 Android 8.0 架構模型允許獨立平台和供應商建構的目標。
映射到屬性鏈
當使用屬性對應到策略版本時,一個類型會對應到一個屬性或多個屬性,確保標有該類型的物件可以透過與其先前類型相對應的屬性進行存取。
保持對策略編寫者隱藏版本資訊的目標意味著自動產生版本化屬性並將它們指派給適當的類型。在靜態類型的常見情況下,這很簡單: type_foo
對應到type_foo_v1
。
對於物件標籤更改,例如sysfs
→ sysfs_A
或mediaserver
→ audioserver
,建立此對應並不簡單(在上面的範例中進行了描述)。平台策略維護者必須確定如何在物件的轉換點建立映射,這需要了解物件及其指派的標籤之間的關係並確定何時發生這種情況。為了向後相容,這種複雜性需要在平台端進行管理,這是唯一可以升級的分區。
版本升級
為了簡單起見,Android 平台會在新的發布分支被削減時發布一個 sepolicy 版本。如上所述,版本號碼包含在PLATFORM_SEPOLICY_VERSION
中,格式為MM.nn
,其中MM
對應於 SDK 值, nn
是/platform/system/sepolicy.
例如,Kitkat 為19.0
、Lollipop 為21.0
、Lollipop-MR1 為22.0
、Marshmallow 為23.0
、Nougat 為24.0
、Nougat-MR1 為25.0
、Oreo 為26.0
、Oreo-MR 10010 100 1000 27.0
28.0
,始終為整數。例如,如果 MR 版本升級需要在system/sepolicy/public
中進行不相容的更改,但不需要 API 升級,則該 sepolicy 版本可能是: vN.1
。開發分支中存在的版本是永遠不會在運輸設備中使用的10000.0
。
Android 在升級時可能會棄用最舊的版本。對於何時棄用某個版本的輸入,Android 可能會收集具有供應商策略且運行該 Android 版本且仍在接收主要平台更新的裝置數量。如果該數字小於某個閾值,則該版本將被棄用。
多個屬性對效能的影響
如https://github.com/SELinuxProject/cil/issues/9所述,分配給類型的大量屬性會在策略快取未命中時導致效能問題。
這已被證實是 Android 中的一個問題,因此對 Android 8.0進行了更改,以刪除策略編譯器新增到策略中的屬性,並刪除未使用的屬性。這些變更解決了效能回歸問題。
System_ext 公共與產品公共政策
從Android 11開始,允許system_ext和product分區將其指定的公共類型匯出到vendor分區。與平台公共策略類似,供應商使用自動轉換為版本化屬性的類型和規則,例如從type
轉換為type_ N
,其中N
是建立供應商分區所針對的平台的版本。
當 system_ext 和 Product 分區基於相同平台版本N
時,建置系統會產生到system_ext/etc/selinux/mapping/ N .cil
和product/etc/selinux/mapping/ N .cil
基礎映射文件,其中包含標識從type
到type_ N
的映射。供應商可以使用版本化屬性type_ N
存取type
。
如果僅更新 system_ext 和產品分區,例如N
到N+1
(或更高),而供應商保持在N
,則供應商可能會失去對 system_ext 和產品分區類型的存取。為了防止損壞,system_ext和product分區應該提供從具體類型到type_ N
屬性的映射檔案。如果每個合作夥伴要支援具有N+1
(或更高)system_ext 和產品分區的N
供應商,則每個合作夥伴都負責維護映射檔案。
為此,合作夥伴應:
- 將產生的基本映射檔案從
N
system_ext 和產品分區複製到其來源樹。 - 根據需要修改映射檔。
- 將映射檔案安裝到
N+1
(或更高)system_ext 和產品分區。
例如,假設N
system_ext 有一個名為foo_type
的公用型別。那麼N
system_ext 分區中的system_ext/etc/selinux/mapping/ N .cil
將如下所示:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
如果bar_type
被加入到N+1
system_ext,並且如果bar_type
應該對應到N
供應商的foo_type
,則N .cil
可以從
(typeattributeset foo_type_N (foo_type))
到
(typeattributeset foo_type_N (foo_type bar_type))
然後安裝到N+1
system_ext分割區。 N
vendor可以繼續存取N+1
system_ext的foo_type
和bar_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/etc/selinux/plat_file_contexts
system
分區中,並由init
在啟動時與供應商file_context
一起載入。
- Android 平台
-
vendor_file_contexts
- 透過組合在裝置的
Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
指向的目錄中找到的file_contexts
來建立特定於裝置的file_context
。 - 必須安裝在
vendor
分區中的/vendor/etc/selinux/vendor_file_contexts
中,並由init
在啟動時與平台file_context
一起載入。
- 透過組合在裝置的
-
財產環境
在 Android 8.0 中, property_contexts
分成兩個檔案:
-
plat_property_contexts
- Android 平台
property_context
沒有特定於裝置的標籤。 - 必須駐留在
/system/etc/selinux/plat_property_contexts
system
分區中,並由init
在開始時與供應商property_contexts
一起載入。
- Android 平台
-
vendor_property_contexts
- 透過組合在裝置的
Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
指向的目錄中找到的property_contexts
來建構特定於裝置的property_context
。 - 必須駐留在
/vendor/etc/selinux/vendor_property_contexts
vendor
分區中,並由init
在啟動時與平台property_context
一起載入
- 透過組合在裝置的
服務情境
在 Android 8.0 中, service_contexts
分成以下檔案:
-
plat_service_contexts
-
servicemanager
的 Android 平台特定的service_context
。service_context
沒有特定於設備的標籤。 - 必須駐留在
/system/etc/selinux/plat_service_contexts
system
分區中,並由servicemanager
在啟動時與供應商service_contexts
一起載入。
-
-
vendor_service_contexts
- 透過組合在設備的
Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
指向的目錄中找到的service_contexts
來建立特定於設備的service_context
。 - 必須駐留在
/vendor/etc/selinux/vendor_service_contexts
vendor
分區中,並由servicemanager
在啟動時與平台service_contexts
一起載入。 - 儘管
servicemanager
在啟動時會尋找此文件,但對於完全相容的TREBLE
設備,vendor_service_contexts
不得存在。這是因為vendor
和system
程序之間的所有互動都必須經過hwservicemanager
/hwbinder
。
- 透過組合在設備的
-
plat_hwservice_contexts
- Android 平台
hwservice_context
用於hwservicemanager
,沒有特定於裝置的標籤。 - 必須駐留在
/system/etc/selinux/plat_hwservice_contexts
system
分區中,並由hwservicemanager
在開始時與vendor_hwservice_contexts
一起載入。
- Android 平台
-
vendor_hwservice_contexts
- 透過組合在設備的
Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
指向的目錄中找到的hwservice_contexts
來建立特定於設備的hwservice_context
。 - 必須駐留在
/vendor/etc/selinux/vendor_hwservice_contexts
vendor
分區中,並由hwservicemanager
在開始時與plat_service_contexts
一起載入。
- 透過組合在設備的
-
vndservice_contexts
-
vndservicemanager
的裝置特定service_context
透過組合在裝置的Boardconfig.mk
中BOARD_SEPOLICY_DIRS
指向的目錄中找到的vndservice_contexts
來建構。 - 該檔案必須駐留在
/vendor/etc/selinux/vndservice_contexts
vendor
分區中,並在啟動時由vndservicemanager
載入。
-
Seaapp 上下文
在 Android 8.0 中, seapp_contexts
分成兩個檔案:
-
plat_seapp_contexts
- Android 平台
seapp_context
沒有特定於裝置的變更。 - 必須駐留在 /system/etc/selinux/plat_seapp_contexts 的
system
分區/system/etc/selinux/plat_seapp_contexts.
- Android 平台
-
vendor_seapp_contexts
- 透過組合在裝置的
Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
指向的目錄中找到的seapp_contexts
來建構平台seapp_context
的裝置特定擴充。 - 必須駐留在
/vendor/etc/selinux/vendor_seapp_contexts
vendor
分區。
- 透過組合在裝置的
MAC權限
在 Android 8.0 中, mac_permissions.xml
分為兩個檔案:
- 平台
mac_permissions.xml
- Android 平台
mac_permissions.xml
沒有特定於裝置的變更。 - 必須駐留在 /system/etc/selinux/ 的
system
分區/system/etc/selinux/.
- Android 平台
- 非平台
mac_permissions.xml
- 從裝置
Boardconfig.mk
檔案中BOARD_SEPOLICY_DIRS
所指向的目錄中找到的mac_permissions.xml
建構的平台mac_permissions.xml
裝置特定擴充。 - 必須駐留在 /vendor/etc/selinux/ 的
vendor
分區/vendor/etc/selinux/.
- 從裝置