SELinux 的預設設定為「拒絕」,也就是說,每個在核心中具有掛鉤的存取權,都必須由政策明確允許。也就是說,政策檔案包含大量關於規則、類型、類別、權限等的資訊。完整考量 SELinux 的範圍超出本文件的範圍,但在啟用新 Android 裝置時,瞭解如何編寫政策規則是必要的。目前已有許多關於 SELinux 的資訊。如需建議的資源,請參閱支援文件。
金鑰檔案
如要啟用 SELinux,請整合最新的 Android 核心,然後納入 system/sepolicy 目錄中找到的檔案。編譯時,這些檔案會包含 SELinux 核心安全性政策,並涵蓋上游 Android 作業系統。
一般來說,您不應直接修改 system/sepolicy
檔案。請改為在 /device/manufacturer/device-name/sepolicy
目錄中新增或編輯專屬的裝置政策檔案。在 Android 8.0 以上版本中,您對這些檔案所做的變更應只會影響供應商目錄中的政策。如要進一步瞭解在 Android 8.0 以上版本中分隔公開的 sepolicy,請參閱「在 Android 8.0 以上版本中自訂 SEPolicy」。無論 Android 版本為何,您仍需修改下列檔案:
政策檔案
結尾為 *.te
的檔案是 SELinux 政策來源檔案,用於定義網域及其標籤。您可能需要在 /device/manufacturer/device-name/sepolicy
中建立新的政策檔案,但請盡可能更新現有檔案。
背景資訊檔案
您可以在背景資訊檔案中指定物件的標籤。
file_contexts
會為檔案指派標籤,並由各種使用者空間元件使用。建立新政策時,請建立或更新這個檔案,為檔案指派新標籤。如要套用新的file_contexts
,請重新建構檔案系統映像檔,或在要重新標記的檔案上執行restorecon
。升級時,系統會自動將file_contexts
的變更套用至系統和 userdata 分割區,作為升級的一部分。在分區掛載為讀寫模式後,您也可以在升級至其他分區時自動套用變更,方法是在 init.board.rc 檔案中新增restorecon_recursive
呼叫。genfs_contexts
會將標籤指派給不支援擴充屬性的檔案系統,例如proc
或vfat
。這項設定會在核心政策中載入,但可能不會對核心內的 inode 生效,因此需要重新啟動或卸載及重新掛載檔案系統,才能完全套用變更。您也可以使用context=mount
選項,將特定標籤指派給特定掛載點,例如vfat
。property_contexts
會將標籤指派給 Android 系統屬性,以便控管哪些程序可以設定這些屬性。這項設定會在啟動期間由init
程序讀取。service_contexts
會將標籤指派給 Android 繫結器服務,以控管哪些程序可以新增 (註冊) 及查找 (查詢) 服務的繫結器參照。這項設定會在啟動期間由servicemanager
程序讀取。seapp_contexts
會為應用程式程序和/data/data
目錄指派標籤。每次啟動應用程式時,zygote
程序會讀取這項設定,installd
也會在啟動期間讀取這項設定。mac_permissions.xml
會根據應用程式的簽名和選用的套件名稱,為應用程式指派seinfo
標記。seinfo
標記可用於seapp_contexts
檔案中的鍵,為所有具有該seinfo
標記的應用程式指派特定標籤。這項設定會在啟動期間由system_server
讀取。keystore2_key_contexts
會為 Keystore 2.0 命名空間指派標籤。這些命名空間是由 KeyStore2 守護程序強制執行。KeyStore 一向提供以 UID/AID 為基礎的命名空間。Keystore 2.0 也會強制執行 sepolicy 定義的命名空間。如要進一步瞭解這個檔案的格式和慣例,請參閱這篇文章。
BoardConfig.mk makefile
編輯或新增政策和內容檔案後,請更新 /device/manufacturer/device-name/BoardConfig.mk
的 makefile,以便參照 sepolicy
子目錄和每個新的政策檔案。如要進一步瞭解 BOARD_SEPOLICY
變數,請參閱
system/sepolicy/README
檔案。
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
重建後,裝置就會啟用 SELinux。您現在可以自訂 SELinux 政策,以便根據「自訂」一節所述,為 Android 作業系統新增自訂項目,或是根據「驗證」一節所述,驗證現有設定。
新政策檔案和 BoardConfig.mk 更新完成後,系統會自動將新政策設定建構至最終核心政策檔案。如要進一步瞭解如何在裝置上建構 sepolicy,請參閱「建構 sepolicy」。
實作
如要開始使用 SELinux,請按照下列步驟操作:
- 在核心中啟用 SELinux:
CONFIG_SECURITY_SELINUX=y
- 變更 kernel_cmdline 或 bootconfig 參數,以便:
或BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
這項參數僅供裝置政策的初始開發作業使用。建立初始引導政策後,請移除這個參數,以便裝置強制執行或通過 CTS。BOARD_BOOTCONFIG := androidboot.selinux=permissive
- 以寬鬆模式啟動系統,查看開機時遇到的拒絕:
在 Ubuntu 14.04 以上版本中: 在 Ubuntu 12.04 上:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- 評估輸出內容是否有類似
init: Warning! Service name needs a SELinux domain defined; please fix!
的警告。如需操作說明和工具,請參閱「驗證」。 - 找出需要標示的裝置和其他新檔案。
- 為物件使用現有或新的標籤。查看
*_contexts
檔案,瞭解先前如何標示項目,並利用標籤含義的知識指派新標籤。理想情況下,這是符合政策的現有標籤,但有時需要新標籤,並且需要該標籤的存取規則。將標籤新增至適當的內容檔案。 - 找出應有專屬安全性網域的網域/程序。
您可能需要為每個網域撰寫全新的政策。舉例來說,從
init
衍生的所有服務都應有自己的 下列指令可協助您找出仍在執行的服務 (但所有服務都需要這類處理方式):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- 檢查
init.device.rc
,找出沒有網域類型的網域。在開發過程中盡早為其提供網域,以免在init
上新增規則,或將init
存取權與其自身政策中的存取權混淆。 - 設定
BOARD_CONFIG.mk
以使用BOARD_SEPOLICY_*
變數。如要進一步瞭解如何設定這項功能,請參閱system/sepolicy
中的 README。 - 檢查 init.device.rc 和 fstab.device 檔案,並確認每次使用
mount
都對應至正確標示的檔案系統,或指定context= mount
選項。 - 請逐一查看拒絕原因,並建立 SELinux 政策來妥善處理。請參閱「自訂」中的範例。
您應先採用 AOSP 中的政策,然後再根據這些政策進行自訂。如要進一步瞭解政策策略,並深入探討其中一些步驟,請參閱「撰寫 SELinux 政策」。
用途
以下是製作自有軟體和相關 SELinux 政策時,應考慮的特定漏洞利用方法:
符號連結:符號連結會顯示為檔案,因此系統經常會將其視為檔案,進而導致漏洞攻擊。舉例來說,某些具權限的元件 (例如 init
) 會變更特定檔案的權限,有時會過度開放。
攻擊者可能會將這些檔案替換為他們控制的程式碼的符號連結,讓攻擊者能夠覆寫任意檔案。不過,如果您知道應用程式從未遍歷符號連結,可以使用 SELinux 禁止這項操作。
系統檔案:請考量系統檔案的類別,這些檔案應僅由系統伺服器修改。不過,由於 netd
、init
和 vold
是以 root 身分執行,因此可以存取這些系統檔案。因此,如果 netd
遭到入侵,可能會危害這些檔案,甚至是系統伺服器本身。
您可以使用 SELinux 將這些檔案標示為系統伺服器資料檔案。因此,只有系統伺服器有讀取/寫入存取權。即使 netd
遭到入侵,也無法切換至系統伺服器網域,並以 root 權限存取這些系統檔案。
應用程式資料:另一個例子是必須以 root 權限執行,但不應存取應用程式資料的函式類別。這項功能非常實用,因為您可以提出廣泛的斷言,例如禁止與應用程式資料無關的特定網域存取網際網路。
setattr:針對 chmod
和 chown
等指令,您可以指出相關聯的網域可執行 setattr
的檔案組合。任何超出此範圍的變更都可能遭到禁止,即使是使用 root 權限也一樣。因此,應用程式可能會針對標示為 app_data_files
的裝置執行 chmod
和 chown
,但不會針對 shell_data_files
或 system_data_files
執行。