SELinux 的預設設定為「拒絕」,也就是說,每個在核心中具有掛鉤的存取權,都必須明確由政策允許。也就是說,政策檔案包含大量與規則、類型、類別、權限等相關的資訊。徹底考量 SELinux 則不在本文件的討論範圍內,但只需瞭解如何撰寫 現在,政策規則在推出新 Android 裝置時至關重要。目前已有許多關於 SELinux 的資訊。如需建議的資源,請參閱支援文件。
金鑰檔案
如要啟用 SELinux,請將 最新 Android 核心,然後整合 system/sepolicy 目錄。編譯時,這些檔案會包含 SELinux 核心安全性政策,並涵蓋上游 Android 作業系統。
一般而言,我們不建議您修改 system/sepolicy
檔案
請改為在 /device/manufacturer/device-name/sepolicy
目錄中新增或編輯專屬的裝置政策檔案。在 Android 8.0 以上版本中,您對這些檔案所做的變更應只會影響供應商目錄中的政策。如要進一步瞭解
Android 8.0 以上版本中的公共政策,請參閱
在 Android 中自訂 SEPolicy
8.0 以上版本。無論 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
不支援延長功能 屬性。這項設定已做為核心政策的一部分載入,但 變更可能不會套用至核心 電網、需要重新啟動或 卸載檔案系統再重新掛接,以完全套用變更。 您也可以使用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 Daemon 強制執行。KeyStore 一直都是 提供的命名空間KeyStore 2.0 會額外強制執行政策 先前定義的命名空間詳細描述這種格式和慣例 請前往這裡。
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
或BOARD_BOOTCONFIG := androidboot.selinux=permissive
這項設定僅適用於首次開發裝置政策的情況。建立初始引導政策後,請移除這個參數,以便裝置強制執行或通過 CTS。 - 以寬鬆模式啟動系統,查看啟動時遇到的拒絕:
在 Ubuntu 14.04 以上版本:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
在 Ubuntu 12.04: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
- 檢查 init.device.rc 和 fstab.device 檔案,
確保每次使用
mount
時,都會對應到適當的 加上標籤的檔案系統,或context= mount
選項 。 - 檢查各項拒絕要求並建立 SELinux 政策,以妥善處理每個拒絕政策。請參閱「自訂」中的範例。
您應先採用 AOSP 中的政策,然後再根據這些政策進行自訂。如要進一步瞭解政策策略和 下文會詳細說明這些步驟 編寫 SELinux 政策。
用途
以下是製作自有軟體和相關 SELinux 政策時,應考慮的特定漏洞利用方法:
符號連結:由於符號連結會顯示為檔案,因此系統通常會將其視為檔案,這可能會導致漏洞攻擊。舉例來說,某些具權限的元件 (例如 init
) 會變更特定檔案的權限,有時會過度開放。
接著,攻擊者可能會使用其所控制的程式碼的符號連結來取代這些檔案。 並允許攻擊者覆寫任意檔案。不過,如果你知道自己的 應用程式絕不會穿越符號連結,您可以禁止這麼做 SELinux
系統檔案:請考慮使用
且此動作只應由系統伺服器修改。不過,由於 netd
、init
和 vold
是以系統管理員身分執行,因此可以存取這些系統檔案。因此,如果 netd
遭到入侵,
入侵這些檔案,也可能是系統伺服器本身。
使用 SELinux 時,您可以將這些檔案識別為系統伺服器資料檔案。
因此,只有系統伺服器有讀取/寫入存取權。即使 netd
遭到入侵,也無法切換至系統伺服器網域,並以 root 權限存取這些系統檔案。
應用程式資料:另一個例子是必須以 root 權限執行,但不應存取應用程式資料的函式類別。這項功能非常實用,因為您可以提出廣泛的斷言,例如禁止與應用程式資料無關的特定網域存取網際網路。
setattr:針對 chmod
和 chown
等指令,您可以指出相關聯的網域可執行 setattr
的檔案組合。任何外有可能是
因而禁止這些變更。所以應用程式可能會在執行時
並比較chmod
和chown
app_data_files
但不含 shell_data_files
或 system_data_files
。