編譯 SELinux 政策
本文介紹了如何編譯 SELinux 政策掌测。SELinux 政策組合使用核心 AOSP 政策(平臺)和設(shè)備專用政策(供應(yīng)商)進(jìn)行編譯康二。從 Android 4.4 一直到 Android 7.0 的 SELinux 政策編譯流程合并了所有 sepolicy 片段莫换,然后在根目錄中生成了整體文件塘辅。這意味著 SOC 供應(yīng)商和 ODM 制造商每次修改政策時陪竿,都修改了 boot.img(針對非 A/B 設(shè)備)或 system.img(針對 A/B 設(shè)備)灭忠。
在 Android 8.0 及更高版本中,平臺政策和供應(yīng)商政策是單獨(dú)編譯的肥败。SOC 和原始設(shè)備制造商 (OEM) 可以更新自己那部分政策,編譯自己的映像(vendor.img愕提、boot.img 等)馒稍,然后獨(dú)立于平臺更新來更新這些映像。
不過浅侨,由于模塊化的 SELinux 政策文件存儲在 /vendor 分區(qū)中纽谒,因此 init 進(jìn)程必須提早裝載系統(tǒng)分區(qū)和供應(yīng)商分區(qū),以便能夠從這些分區(qū)中讀取 SELinux 文件如输,并將這些文件與系統(tǒng)目錄中的核心 SELinux 文件合并(裝載操作要在將這些文件加載到內(nèi)核之前進(jìn)行)鼓黔。
源文件
<devsite-heading text="源文件" for="files" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
SELinux 的編譯邏輯位于以下文件中:
-
external/selinux
:外部 SELinux 項(xiàng)目,用于構(gòu)建 HOST 命令行實(shí)用工具以編譯 SELinux 政策和標(biāo)簽不见。-
external/selinux/libselinux
:Android 僅使用外部libselinux
項(xiàng)目的一個子集澳化,以及一些 Android 專用自定義內(nèi)容。如需了解詳情稳吮,請參閱external/selinux/README.android
缎谷。 -
external/selinux/libsepol
: -
external/selinux/checkpolicy
:SELinux 政策編譯器(主機(jī)可執(zhí)行文件:checkpolicy
列林、checkmodule
和dispol
)瑞你。依賴于libsepol
。
-
-
system/sepolicy
:核心 Android SELinux 政策配置希痴,包括上下文文件和政策文件者甲。主要 sepolicy 編譯邏輯也位于此處:system/sepolicy/Android.mk
。
要詳細(xì)了解 system/sepolicy
中的文件砌创,請參閱實(shí)現(xiàn) SELinux过牙。
Android 7.0 及更低版本
本部分介紹如何在 Android 7.x 及更低版本中編譯 SELinux 政策。
編譯 SELinux 政策
SELinux 政策通過將核心 AOSP 政策與設(shè)備專用自定義政策合并而創(chuàng)建纺铭。然后寇钉,系統(tǒng)會將合并后的政策傳遞給政策編譯器和各種檢查工具。設(shè)備專用自定義政策通過在設(shè)備專用 Boardconfig.mk 文件中定義的 BOARD_SEPOLICY_DIRS 變量完成舶赔。該全局編譯變量包含一個用于指定其他政策文件搜索順序的目錄列表扫倡。
例如,SOC 供應(yīng)商和 ODM 可以分別添加一個目錄竟纳,一個用于 SOC 專用設(shè)置撵溃,另一個用于設(shè)備專用設(shè)置,以生成針對指定設(shè)備的最終 SELinux 配置:
BOARD_SEPOLICY_DIRS += device/SOC/common/sepolicy
BOARD_SEPOLICY_DIRS += device/SoC/DEVICE/sepolicy
system/sepolicy 和 BOARD_SEPOLICY_DIRS 中的 file_contexts 文件內(nèi)容會連接在一起锥累,以便在設(shè)備上生成 file_contexts.bin:
sepolicy 文件由多個源文件組成:
純文本 policy.conf 是通過依次連接 security_classes缘挑、initial_sids、*.te 文件桶略、genfs_contexts 以及 port_contexts 而生成的语淘。
對于每個文件(例如 security_classes),其內(nèi)容都是由 system/sepolicy/ 和 BOARDS_SEPOLICY_DIRS 下的同名文件連接而成际歼。
policy.conf 會被發(fā)送到 SELinux 編譯器進(jìn)行語法檢查并被編譯為二進(jìn)制格式惶翻,從而生成設(shè)備上的 sepolicy。
SELinux 文件
編譯完成后鹅心,搭載 Android 7.x 及更低版本的設(shè)備通常包含以下與 SELinux 相關(guān)的文件:
selinux_version
sepolicy: binary output after combining policy files (security_classes, initial_sids, *.te, etc.)
file_contexts
property_contexts
seapp_contexts
service_contexts
system/etc/mac_permissions.xml
如需了解詳情吕粗,請參閱實(shí)現(xiàn) SELinux。
<devsite-heading text="SELinux 初始化" for="android-n-init" level="h3" link="" toc="" class="">### SELinux 初始化</devsite-heading>
在系統(tǒng)啟動時旭愧,SELinux 處于寬容模式(并且不處于強(qiáng)制模式)颅筋。init 進(jìn)程會執(zhí)行以下任務(wù):
- 通過
/sys/fs/selinux/load
將sepolicy
文件從 ramdisk 加載到內(nèi)核。 - 將 SELinux 切換到強(qiáng)制模式输枯。
- 對自己執(zhí)行 re-exec()议泵,以將 SELinux 域規(guī)則應(yīng)用于自身。
為了縮短啟動時間用押,請?jiān)诒M早在 init
進(jìn)程中執(zhí)行 re-exec()
肢簿。
<devsite-heading text="Android 8.0 及更高版本" for="android-o" level="h2" link="" toc="" class="" back-to-top="">## Android 8.0 及更高版本</devsite-heading> <devsite-heading text="Android 8.0 及更高版本" for="android-o" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
在 Android 8.0 中,SELinux 政策拆分為平臺組件和供應(yīng)商組件,以允許獨(dú)立進(jìn)行平臺/供應(yīng)商政策更新池充,同時保持兼容性桩引。
平臺 sepolicy 進(jìn)一步拆分為平臺專用部分和平臺公共部分,以便將特定類型和屬性導(dǎo)出到供應(yīng)商政策寫入程序收夸。平臺會保證將公共類型/屬性作為指定平臺版本的穩(wěn)定 API 進(jìn)行維護(hù)坑匠。借助平臺映射文件,平臺可以保證與之前多個版本的公共類型/屬性兼容卧惜。
<devsite-heading text="平臺公共 sepolicy" for="platform-public" level="h3" link="" toc="" class="">### 平臺公共 sepolicy</devsite-heading>
平臺公共 sepolicy 包含 system/sepolicy/public
下定義的所有內(nèi)容厘灼。平臺可以假設(shè)在公共政策下定義的類型和屬性是指定平臺版本的穩(wěn)定 API。這構(gòu)成了 sepolicy 中平臺導(dǎo)出的部分咽瓷,供應(yīng)商(即設(shè)備)政策開發(fā)者可以在這部分 sepolicy 中編寫其他設(shè)備專用政策设凹。
類型的版本取決于在編寫供應(yīng)商文件時參照的政策版本(由 PLATFORM_SEPOLICY_VERSION
編譯變量所定義)。然后茅姜,相應(yīng)版本的公共政策(以其原始形式)便會與供應(yīng)商政策一起包含在平臺政策中闪朱。因此,最終政策包含平臺專用政策钻洒、當(dāng)前平臺的公共 sepolicy奋姿、設(shè)備專用政策,以及與編寫設(shè)備政策時參照的平臺版本相對應(yīng)的適當(dāng)版本的公共政策素标。
<devsite-heading text="平臺專用 sepolicy" for="platform-private" level="h3" link="" toc="" class="">### 平臺專用 sepolicy</devsite-heading>
平臺專用 sepolicy 包含 /system/sepolicy/private
下定義的所有內(nèi)容称诗。這部分政策構(gòu)成了運(yùn)行平臺功能所需的平臺專用類型、權(quán)限和屬性头遭。這些內(nèi)容不會導(dǎo)出到 vendor/device
政策寫入程序寓免。非平臺政策的寫入程序不得根據(jù)平臺專用 sepolicy 中定義的類型/屬性/規(guī)則來編寫政策擴(kuò)展程序。此外任岸,在進(jìn)行框架專用更新時再榄,可以修改或移除這些規(guī)則。
<devsite-heading text="平臺專用映射" for="platform-private-mapping" level="h3" link="" toc="" class="">### 平臺專用映射</devsite-heading>
平臺專用映射包含相應(yīng)政策聲明,用于將在之前平臺版本的平臺公共政策中公開的屬性映射到當(dāng)前平臺公共 sepolicy 中所使用的具體類型支子。這樣可以確保根據(jù)之前平臺公共 sepolicy 版本中的平臺公共屬性編寫的供應(yīng)商政策可以繼續(xù)運(yùn)行兴垦。版本控制基于在 AOSP 中為指定平臺版本設(shè)置的 PLATFORM_SEPOLICY_VERSION
編譯變量。之前的每個平臺版本都有一個單獨(dú)的映射文件弦蹂;平臺應(yīng)通過相應(yīng)的映射文件接受供應(yīng)商政策。如需了解詳情,請參閱兼容性艺蝴。
<devsite-heading text="編譯 SELinux 政策" for="android-o-build" level="h2" link="" toc="" class="" back-to-top="">## 編譯 SELinux 政策</devsite-heading> <devsite-heading text="編譯 SELinux 政策" for="android-o-build" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
Android 8.0 中的 SELinux 政策是通過合并 /system
和 /vendor
中的部分內(nèi)容而創(chuàng)建。適當(dāng)設(shè)置該政策的邏輯位于 /platform/system/sepolicy/Android.mk
鸟废。
政策存在于以下位置:
| 位置 | 包含 |
| system/sepolicy/public
| 平臺的 sepolicy API |
| system/sepolicy/private
| 平臺實(shí)現(xiàn)詳情(供應(yīng)商可以忽略) |
| system/sepolicy/vendor
| 供應(yīng)商可以使用的政策和上下文文件(供應(yīng)商可以根據(jù)情況忽略) |
| BOARD_SEPOLICY_DIRS
| 供應(yīng)商 sepolicy |
編譯系統(tǒng)采用該政策猜敢,并在系統(tǒng)分區(qū)和供應(yīng)商分區(qū)中分別生成平臺政策組件和供應(yīng)商政策組件。具體步驟包括:
- 將政策轉(zhuǎn)換為 SELinux 通用中間語言 (CIL) 格式,具體如下:
- 平臺公共政策
- 專用 + 公共組合政策
- 公共 + 供應(yīng)商和
BOARD_SEPOLICY_DIRS
政策
- 將公開提供的政策的版本控制為供應(yīng)商政策的一部分缩擂。為此鼠冕,應(yīng)使用生成的公共 CIL 政策向公共 + 供應(yīng)商 +
BOARD_SEPOLICY_DIRS
組合政策指明必須將哪些部分轉(zhuǎn)換為將與平臺政策相關(guān)聯(lián)的屬性。 - 創(chuàng)建將平臺和供應(yīng)商部分關(guān)聯(lián)在一起的映射文件胯盯。最初懈费,該文件只是將公共政策中的類型與供應(yīng)商政策中對應(yīng)的屬性相關(guān)聯(lián);之后博脑,該文件還為未來的平臺版本中維護(hù)的文件提供依據(jù)憎乙,從而兼容以此平臺版本作為目標(biāo)版本的供應(yīng)商政策。
- 合并政策文件(介紹設(shè)備解決方案和預(yù)編譯解決方案)叉趣。
- 合并映射政策泞边、平臺政策和供應(yīng)商政策。
- 編譯輸出二進(jìn)制政策文件疗杉。