本文介紹 Android 如何處理平台 OTA 的策略兼容性問題,其中新平台 SELinux 設置可能與舊供應商 SELinux 設置不同。
基於 Treble 的 SELinux 策略設計考慮了平台和供應商策略之間的二元區別;如果供應商分區生成依賴項,例如platform
< vendor
< oem
,該方案將變得更加複雜。
在 Android 8.0 及更高版本中,SELinux 全局策略分為私有和公共組件。公共組件由策略和相關的基礎設施組成,保證可用於平台版本。此策略將公開給供應商策略編寫者,以使供應商能夠構建供應商策略文件,當與平台提供的策略結合使用時,將為設備生成一個功能齊全的策略。
- 對於版本控制,導出的平台公共策略將被寫入attributes 。
- 為了便於編寫策略,作為策略構建過程的一部分,導出的類型將被轉換為版本化屬性。公共類型也可以直接用於供應商上下文文件提供的標記決策。
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.*
(來自內核 cmdline)和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)
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
。
系統文件系統 (/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 添加創建 add、find 和 list 權限的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-MR1 為27.0
,Android 9 為28.0
。總是整數。例如,如果一個版本的 MR 碰撞需要在system/sepolicy/public
中進行不兼容的更改,但不需要 API 碰撞,那麼該 sepolicy 版本可能是: vN.1
。開發分支中存在的版本是 never-to-be-used-in-shipping-devices 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 和 product 分區,例如N
到N+1
(或更高版本),而供應商停留在N
,供應商可能無法訪問 system_ext 和 product 分區的類型。為防止損壞,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
vendor 的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_context
構建設備特定的file_contexts
。 - 必須安裝在
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
分區中,並在開始時與供應商property_contexts
一起由init
加載。
- 沒有設備特定標籤的 Android 平台
-
vendor_property_contexts
- 通過組合在設備的
Boardconfig.mk
文件中的BOARD_SEPOLICY_DIRS
指向的目錄中找到的property_context
構建設備特定的property_contexts
。 - 必須駐留在
/vendor/etc/selinux/vendor_property_contexts
的vendor
分區中,並在開始時與平台property_context
一起由init
加載
- 通過組合在設備的
服務上下文
在 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_context
構建設備特定的service_contexts
。 - 必須駐留在
/vendor/etc/selinux/vendor_service_contexts
的vendor
分區中,並在開始時由servicemanager
與平台service_contexts
一起加載。 - 儘管
servicemanager
在啟動時會查找此文件,但對於完全兼容的TREBLE
設備,vendor_service_contexts
必須不存在。這是因為vendor
和system
進程之間的所有交互都必須通過hwservicemanager
/hwbinder
。
- 通過組合在設備的
-
plat_hwservice_contexts
- 沒有設備特定標籤的
hwservicemanager
的 Android 平台hwservice_context
。 - 必須駐留在
/system/etc/selinux/plat_hwservice_contexts
的system
分區中,並在開始時由hwservicemanager
與vendor_hwservice_contexts
一起加載。
- 沒有設備特定標籤的
-
vendor_hwservice_contexts
- 通過組合在設備的
hwservice_contexts
文件中的BOARD_SEPOLICY_DIRS
指向的目錄中找到的hwservice_context
構建設備特定的Boardconfig.mk
。 - 必須駐留在
/vendor/etc/selinux/vendor_hwservice_contexts
的vendor
分區中,並在開始時由hwservicemanager
與plat_service_contexts
一起加載。
- 通過組合在設備的
-
vndservice_contexts
- 通過組合在設備的
BOARD_SEPOLICY_DIRS
中的Boardconfig.mk
指向的目錄中找到的vndservicemanager
構建的vndservice_contexts
的特定於設備的service_context
。 - 此文件必須位於
/vendor/etc/selinux/vndservice_contexts
的vendor
分區中,並在開始時由vndservicemanager
加載。
- 通過組合在設備的
Seapp 上下文
在 Android 8.0 中, seapp_contexts
分為兩個文件:
-
plat_seapp_contexts
- 沒有特定於設備的更改的 Android 平台
seapp_context
。 - 必須位於
/system/etc/selinux/plat_seapp_contexts.
的system
分區中。
- 沒有特定於設備的更改的 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
分區中。
- 沒有特定於設備的更改的 Android 平台
- 非平台
mac_permissions.xml
- 從設備的
Boardconfig.mk
文件中的BOARD_SEPOLICY_DIRS
指向的目錄中找到的mac_permissions.xml
構建的平台mac_permissions.xml
的設備特定擴展。 - 必須駐留在
/vendor/etc/selinux/.
的供應vendor
分區中。
- 從設備的