自定義 SELinux
集成基本級別的 SELinux 功能并全面分析結(jié)果后,您可以添加自己的政策設(shè)置,以便涵蓋對 Android 操作系統(tǒng)所做的自定義。這些政策必須仍然滿足 Android 兼容性計劃的要求,并且不得移除默認(rèn)的 SELinux 設(shè)置。
制造商不得移除現(xiàn)有的 SELinux 政策,否則可能會破壞 Android SELinux 的實施方式及其管控的應(yīng)用。這包括可能需要改進以遵守政策并正常運行的第三方應(yīng)用。應(yīng)用必須無需任何修改即可繼續(xù)在啟用了 SELinux 的設(shè)備上正常運行。
當(dāng)開始自定義 SELinux 時,請注意:
- 為所有新的守護進程編寫 SELinux 政策
- 盡可能使用預(yù)定義的域
- 為作為
init服務(wù)衍生的所有進程分配域 - 在編寫政策之前先熟悉相關(guān)的宏
- 向 AOSP 提交對核心政策進行的更改
同時,謹(jǐn)記下列禁忌:
- 不得創(chuàng)建不兼容的政策
- 不得允許對最終用戶政策進行自定義
- 不得允許對移動設(shè)備管理 (MDM) 政策進行自定義
- 不得恐嚇違反政策的用戶
- 不得添加后門程序
要查看具體要求,請參閱 Android 兼容性定義文檔中的“內(nèi)核安全功能”部分。
SELinux 采用白名單方法,這意味著只能授予政策中明確允許的訪問權(quán)限。由于 Android 的默認(rèn) SELinux 政策已經(jīng)支持 Android 開放源代碼項目,因此您無需以任何方式修改 SELinux 設(shè)置。如果您要自定義 SELinux 設(shè)置,則應(yīng)格外謹(jǐn)慎,以免破壞現(xiàn)有應(yīng)用。要開始使用,請按下列步驟操作:
- 使用最新的 Android 內(nèi)核。
- 采用最小權(quán)限原則。
- 僅針對您向 Android 添加的內(nèi)容調(diào)整 SELinux 政策。默認(rèn)政策能夠自動適用于 Android 開源項目代碼庫。
- 將各個軟件組件拆分成多個負(fù)責(zé)執(zhí)行單項任務(wù)的模塊。
- 創(chuàng)建將這些任務(wù)與無關(guān)功能隔離開來的 SELinux 政策。
- 將這些政策放在
/device/<var>manufacturer</var>/<var>device-name</var>/sepolicy目錄中的*.te文件(te 是 SELinux 政策源代碼文件使用的擴展名)內(nèi),然后使用BOARD_SEPOLICY變量將它們納入到您的版本中。 - 先將新域設(shè)為寬容域。為此,可以在該域的
.te文件中使用寬容聲明。 - 分析結(jié)果并優(yōu)化域定義。
- 當(dāng) userdebug 版本中不再出現(xiàn)拒絕事件時,移除寬容聲明。
完成 SELinux 政策更改的集成工作后,請在開發(fā)工作流程中添加一個步驟,以確保向前兼容 SELinux。在理想的軟件開發(fā)過程中,SELinux 政策只會在軟件模型發(fā)生變化時才需要更改,而不會在實際的實施方式變化時更改。
當(dāng)您開始自定義 SELinux 時,首先要審核自己向 Android 添加的內(nèi)容。如果添加的是執(zhí)行新功能的組件,則在開啟強制模式之前,您需要先確認(rèn)該組件是否符合 Android 的安全政策,以及原始設(shè)備制造商 (OEM) 制定的所有相關(guān)政策。
為了防止出現(xiàn)不必要的問題,與其過度限制和不兼容,不如過度寬泛和過度兼容,因為前者會導(dǎo)致設(shè)備功能損壞。不過,如果您的更改能夠惠及其他人,則應(yīng)將這些更改作為補丁程序提交至默認(rèn) SELinux 政策。如果相應(yīng)補丁程序已應(yīng)用于默認(rèn)安全政策,您將不需要針對每個新的 Android 版本進行此項更改。
政策聲明示例
<devsite-heading text="政策聲明示例" for="example_policy_statements" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
SELinux 基于 M4 計算機語言,因此支持多種有助于節(jié)省時間的宏。
在以下示例中,所有域都被授予向 /dev/null 讀寫數(shù)據(jù)的權(quán)限以及從 /dev/zero 讀取數(shù)據(jù)的權(quán)限。
<devsite-code><pre class="" is-upgraded=""># Allow read / write access to /dev/null
allow domain null_device:chr_file { getattr open read ioctl lock append write};
Allow read-only access to /dev/zero
allow domain zero_device:chr_file { getattr open read ioctl lock };
</pre></devsite-code>
此聲明也可以通過 SELinux *_file_perms 宏編寫(簡短版):
<devsite-code><pre class="" is-upgraded=""># Allow read / write access to /dev/null
allow domain null_device:chr_file rw_file_perms;
Allow read-only access to /dev/zero
allow domain zero_device:chr_file r_file_perms;
</pre></devsite-code> <devsite-heading text="政策示例" for="example_policy" level="h2" link="" toc="" class="" back-to-top="">## 政策示例</devsite-heading> <devsite-heading text="政策示例" for="example_policy" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
以下是一個完整的 DHCP 政策示例,我們將在下文中對其進行分析:
<devsite-code><pre class="" is-upgraded="">type dhcp, domain;
permissive dhcp;
type dhcp_exec, exec_type, file_type;
type dhcp_data_file, file_type, data_file_type;
init_daemon_domain(dhcp)
net_domain(dhcp)
allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service
};
allow dhcp self:packet_socket create_socket_perms;
allow dhcp self:netlink_route_socket { create_socket_perms nlmsg_write };
allow dhcp shell_exec:file rx_file_perms;
allow dhcp system_file:file rx_file_perms;
For /proc/sys/net/ipv4/conf/*/promote_secondaries
allow dhcp proc_net:file write;
allow dhcp system_prop:property_service set ;
unix_socket_connect(dhcp, property, init)
type_transition dhcp system_data_file:{ dir file } dhcp_data_file;
allow dhcp dhcp_data_file:dir create_dir_perms;
allow dhcp dhcp_data_file:file create_file_perms;
allow dhcp netd:fd use;
allow dhcp netd:fifo_file rw_file_perms;
allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write };
allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket
netlink_nflog_socket } { read write };
</pre></devsite-code>
下面我們來分析一下該示例:
在第一行(即類型聲明)中,該政策聲明 DHCP 守護進程將沿用基本的安全政策 (domain)。在前面的聲明示例中,DHCP 可以向 /dev/null 讀寫數(shù)據(jù)。
在第二行中,DHCP 被聲明為寬容域。
在 init_daemon_domain(dhcp) 這一行中,該政策聲明 DHCP 是從 init 衍生而來的,并且可以與其通信。
在 net_domain(dhcp) 這一行中,該政策允許 DHCP 使用 net 域中的常用網(wǎng)絡(luò)功能,例如讀取和寫入 TCP 數(shù)據(jù)包、通過套接字進行通信,以及執(zhí)行 DNS 請求。
在 allow dhcp proc_net:file write; 這一行中,該政策聲明 DHCP 可以向 /proc 中的特定文件寫入數(shù)據(jù)。這一行顯示了 SELinux 的詳細(xì)文件標(biāo)簽。它使用 proc_net 標(biāo)簽來限定 DHCP 僅對 /proc/sys/net 中的文件具有寫入權(quán)限。
該示例的最后一部分以 allow dhcp netd:fd use; 開頭,描述了允許應(yīng)用之間如何交互。該政策聲明 DHCP 和 netd 之間可通過文件描述符、FIFO 文件、數(shù)據(jù)報套接字以及 UNIX 信息流套接字進行通信。DHCP 只能向數(shù)據(jù)報套接字和 UNIX 信息流套接字中讀寫數(shù)據(jù),但不能創(chuàng)建或打開此類套接字。
<devsite-heading text="可用控件" for="available_controls" level="h2" link="" toc="" class="" back-to-top="">## 可用控件</devsite-heading> <devsite-heading text="可用控件" for="available_controls" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
| 類 | 權(quán)限 |
| 文件 | <devsite-code><pre is-upgraded="">ioctl read write create getattr setattr lock relabelfrom relabelto append
unlink link rename execute swapon quotaon mounton</pre></devsite-code> |
| |
| 目錄 | <devsite-code><pre is-upgraded="">add_name remove_name reparent search rmdir open audit_access execmod</pre></devsite-code> |
| |
| 套接字 | <devsite-code><pre is-upgraded="">ioctl read write create getattr setattr lock relabelfrom relabelto append bind
connect listen accept getopt setopt shutdown recvfrom sendto recv_msg send_msg
name_bind</pre></devsite-code> |
| |
| 文件系統(tǒng) | <devsite-code><pre is-upgraded="">mount remount unmount getattr relabelfrom relabelto transition associate
quotamod quotaget</pre></devsite-code> |
| |
| 進程 | <devsite-code><pre is-upgraded="">fork transition sigchld sigkill sigstop signull signal ptrace getsched setsched
getsession getpgid setpgid getcap setcap share getattr setexec setfscreate
noatsecure siginh setrlimit rlimitinh dyntransition setcurrent execmem
execstack execheap setkeycreate setsockcreate</pre></devsite-code> |
| |
| 安全 | <devsite-code><pre is-upgraded="">compute_av compute_create compute_member check_context load_policy
compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot
read_policy</pre></devsite-code> |
| |
| 權(quán)能 | <devsite-code><pre is-upgraded="">chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap
linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock
ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin
sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write
audit_control setfcap</pre></devsite-code> |
| |
|
更多
|
還有更多
|
<devsite-heading text="neverallow 規(guī)則" for="neverallow" level="h2" link="" toc="" class="" back-to-top="">## neverallow 規(guī)則</devsite-heading> <devsite-heading text="neverallow 規(guī)則" for="neverallow" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
SELinux neverallow 規(guī)則用于禁止在任何情況下都不應(yīng)該發(fā)生的行為。通過執(zhí)行兼容性測試,現(xiàn)在各種設(shè)備上都會強制執(zhí)行 SELinux neverallow 規(guī)則。
以下準(zhǔn)則旨在協(xié)助制造商在自定義過程中避免出現(xiàn)與 neverallow 規(guī)則相關(guān)的錯誤。此處使用的規(guī)則編號與 Android 5.1 中使用的編號一致,并且會因版本而異。
規(guī)則 48:neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
請參閱 ptrace 的幫助頁面。sys_ptrace 權(quán)能用于授予對任何進程執(zhí)行 ptrace 命令的權(quán)限,擁有該權(quán)限的組件能夠?qū)ζ渌M程進行廣泛的控制。只有該規(guī)則中列出的指定系統(tǒng)組件才能享有該權(quán)限。如果需要該權(quán)能,則通常表明存在的某些內(nèi)容不適用于面向用戶的版本或存在不需要的功能。請移除不必要的組件。
規(guī)則 76:neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
該規(guī)則旨在防止執(zhí)行系統(tǒng)中的任意代碼。具體來說,該規(guī)則聲明僅執(zhí)行 /system 中的代碼,以便通過驗證啟動等機制實現(xiàn)安全保證。通常,在遇到與 neverallow 規(guī)則相關(guān)的問題時,最好的解決辦法是將違規(guī)代碼移到 /system 分區(qū)。
<devsite-heading text="在 Android 8.0 及更高版本中自定義 SEPolicy" for="android-o" level="h2" link="" toc="" class="" back-to-top="">## 在 Android 8.0 及更高版本中自定義 SEPolicy</devsite-heading> <devsite-heading text="在 Android 8.0 及更高版本中自定義 SEPolicy" for="android-o" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
此部分的指南適用于 Android 8.0 及更高版本中的供應(yīng)商 SELinux 政策,包括有關(guān) Android 開源項目 (AOSP) SEPolicy 和 SEPolicy 擴展的詳細(xì)信息。要詳細(xì)了解 SELinux 政策如何在各分區(qū)和 Android 版本中保持兼容,請參閱兼容性。
<devsite-heading text="政策的存放位置" for="policy-placement" level="h3" link="" toc="" class="">### 政策的存放位置</devsite-heading>
在 Android 7.0 及更低版本中,設(shè)備制造商可以將政策添加到 BOARD_SEPOLICY_DIRS,包括用來在不同設(shè)備類型之間增強 AOSP 政策的政策。在 Android 8.0 及更高版本中,將政策添加到 BOARD_SEPOLICY_DIRS 會將該政策僅存放在供應(yīng)商映像中。
在 Android 8.0 及更高版本中,政策位于 AOSP 中的以下位置:
-
system/sepolicy/public。其中包括所導(dǎo)出的用于供應(yīng)商特定政策的政策。所有內(nèi)容都會納入 Android 8.0 兼容性基礎(chǔ)架構(gòu)。公共政策會保留在不同版本上,因此您可以在自定義政策的
/public中添加任何內(nèi)容。正因如此,可存放在/public中的政策類型的限制性更強。將此目錄視為相應(yīng)平臺的已導(dǎo)出政策 API:處理/system與/vendor之間的接口的所有內(nèi)容都位于這里。 - system/sepolicy/private。包括系統(tǒng)映像正常運行所必需(但供應(yīng)商映像政策應(yīng)該不知道)的政策。
-
system/sepolicy/vendor。包括位于
/vendor但存在于核心平臺樹(非設(shè)備特定目錄)中的組件的相關(guān)政策。這是編譯系統(tǒng)區(qū)分設(shè)備和全局組件的軟件工件;從概念上講,這是下述設(shè)備專用政策的一部分。 - device/<var>manufacturer</var>/<var>device-name</var>/sepolicy。包含設(shè)備專用政策,以及對政策進行的設(shè)備自定義(在 Android 8.0 及更高版本中,該政策對應(yīng)于供應(yīng)商映像組件的相關(guān)政策)。
<devsite-heading text="支持的政策場景" for="supported-policy-scenarios" level="h3" link="" toc="" class="">### 支持的政策場景</devsite-heading>
在搭載 Android 8.0 及更高版本的設(shè)備上,供應(yīng)商映像必須使用 OEM 系統(tǒng)映像和 Google 提供的參考 AOSP 系統(tǒng)映像(并在此參考映像上傳遞 CTS),這樣可確??蚣芘c供應(yīng)商代碼完全分離開來。此類設(shè)備支持以下場景。
<devsite-heading text="僅含供應(yīng)商映像的擴展" for="vendor-image-only-extensions" level="h4" link="" class="">#### 僅含供應(yīng)商映像的擴展</devsite-heading>
示例:從支持相關(guān)進程的供應(yīng)商映像向 vndservicemanager 添加新服務(wù)。
與搭載舊版 Android 的設(shè)備一樣,請在 device/<var>manufacturer</var>/<var>device-name</var>/sepolicy 中添加針對特定設(shè)備的自定義配置。管控供應(yīng)商組件如何與其他供應(yīng)商組件(僅限這些組件)交互的新政策應(yīng)涉及僅存在于 device/<var>manufacturer</var>/<var>device-name</var>/sepolicy 中的類型。此處編寫的政策允許運行供應(yīng)商的代碼,不會在僅針對框架的 OTA 期間更新,并且將存在于具有參考 AOSP 系統(tǒng)映像的設(shè)備上的組合政策中。
<devsite-heading text="支持使用 AOSP 的供應(yīng)商映像" for="vendor-image-support-to-work-with-aosp" level="h4" link="" class="">#### 支持使用 AOSP 的供應(yīng)商映像</devsite-heading>
示例:添加用于實現(xiàn) AOSP 定義的 HAL 的新進程(通過供應(yīng)商映像中的 hwservicemanager 注冊)。
與搭載舊版 Android 的設(shè)備一樣,請在 device/<var>manufacturer</var>/<var>device-name</var>/sepolicy 中執(zhí)行針對特定設(shè)備的自定義配置。作為 system/sepolicy/public/ 的一部分導(dǎo)出的政策可供使用,并且包含在供應(yīng)商政策中。公共政策中的類型和屬性可以用在新規(guī)則中,指示與供應(yīng)商特有新位的互動,但要遵守所提供的 neverallow 限制。與 vendor-only 情形一樣,此處的新政策不會在僅針對框架的 OTA 期間更新,并且將存在于具有參考 AOSP 系統(tǒng)映像的設(shè)備上的組合政策中。
<devsite-heading text="僅含系統(tǒng)映像的擴展" for="system-image-only-extensions" level="h4" link="" class="">#### 僅含系統(tǒng)映像的擴展</devsite-heading>
示例:添加一種僅供系統(tǒng)映像中的其他進程訪問的新服務(wù)(通過 servicemanager 注冊)。
將此政策添加到 system/sepolicy/private。您可以添加額外的進程或?qū)ο笠栽诤献骰锇橄到y(tǒng)映像中啟用功能,前提是這些新位不需要與供應(yīng)商映像上的新組件互動(具體而言,即使沒有供應(yīng)商映像中的政策,此類進程或?qū)ο笠脖仨毮軌蛲耆_\行)。system/sepolicy/public 導(dǎo)出的政策在此處的提供方式與僅含供應(yīng)商映像的擴展相同。此政策包含在系統(tǒng)映像中,可以在僅針對框架的 OTA 中進行更新,但在使用參考 AOSP 系統(tǒng)映像時不會存在。
<devsite-heading text="提供擴展 AOSP 組件的供應(yīng)商映像擴展" for="vendor-image-extensions-that-serve-extended-aosp-components" level="h4" link="" class="">#### 提供擴展 AOSP 組件的供應(yīng)商映像擴展</devsite-heading>
示例:供同樣存在于 AOSP 系統(tǒng)映像中的擴展客戶端(例如擴展的 system_server)使用的新增非 AOSP HAL。
系統(tǒng)與供應(yīng)商之間的交互政策必須納入供應(yīng)商分區(qū)上的 device/<var>manufacturer</var>/<var>device-name</var>/sepolicy 目錄中。這類似于上述添加供應(yīng)商映像支持以使用參考 AOSP 映像的情景,不同之處在于修改后的 AOSP 組件可能還需要其他政策才能正確使用系統(tǒng)分區(qū)的其余部分(只要這些組件仍具有公開 AOSP 類型標(biāo)簽就可以)。
用于控制公開 AOSP 組件與僅含系統(tǒng)映像的擴展之間的互動的政策應(yīng)該位于 system/sepolicy/private 中。
<devsite-heading text="僅訪問 AOSP 接口的系統(tǒng)映像擴展" for="system-image-extensions-that-access-only-AOSP-interfaces" level="h4" link="" class="">#### 僅訪問 AOSP 接口的系統(tǒng)映像擴展</devsite-heading>
示例:新的非 AOSP 系統(tǒng)進程必須訪問 AOSP 所依賴的 HAL。
這與僅含系統(tǒng)映像的擴展示例類似,不同之處在于新的系統(tǒng)組件可能會通過 system/vendor 接口進行交互。新系統(tǒng)組件的相關(guān)政策必須位于 system/sepolicy/private,只要它是通過 AOSP 已在 system/sepolicy/public 中建立的接口發(fā)揮作用就可以接受(即,該目錄中包含功能正常運行所需的類型和屬性)。雖然可以在設(shè)備專用政策中添加政策,但無法在僅針對框架的更新中使用其他 system/sepolicy/private 類型或進行更改(以任何影響政策的方式)。此政策可以在僅針對框架的 OTA 中更改,但在使用 AOSP 系統(tǒng)映像時,此政策將不出現(xiàn)(也不會有新的系統(tǒng)組件)。
<devsite-heading text="提供新系統(tǒng)組件的供應(yīng)商映像擴展" for="vendor-image-extensions-that-serve-new-system-components" level="h4" link="" class="">#### 提供新系統(tǒng)組件的供應(yīng)商映像擴展</devsite-heading>
示例:添加新的非 AOSP HAL 以供無需 AOSP 模擬的客戶端進程使用(因此,該進程需要自己的域)。
與 AOSP 擴展示例類似,系統(tǒng)與供應(yīng)商之間的交互政策必須位于供應(yīng)商分區(qū)上的 device/<var>manufacturer</var>/<var>device-name</var>/sepolicy 目錄中(以確保系統(tǒng)政策不知道與供應(yīng)商相關(guān)的詳細(xì)信息)。您可以在 system/sepolicy/public 中添加新的用于擴展該政策的公共類型;只能在現(xiàn)有 AOSP 政策的基礎(chǔ)上進行添加,即不要移除 AOSP 公共政策。新的公共類型隨后可用于 system/sepolicy/private 和 device/<var>manufacturer</var>/<var>device-name</var>/sepolicy 中的政策。
請注意,每次向 system/sepolicy/public 添加內(nèi)容都會增加復(fù)雜程度,因為這會增加必須在映射文件中跟蹤的新兼容性保證(會受到其他限制的約束)。只有新類型和相關(guān)項允許在 system/sepolicy/public 中添加規(guī)則;屬性和其他政策聲明不受支持。此外,新的公共類型不能用于直接為 /vendor 政策中的對象添加標(biāo)簽。
<devsite-heading text="不受支持的政策場景" for="unsupported-policy-scenarios" level="h3" link="" toc="" class="">### 不受支持的政策場景</devsite-heading>
搭載 Android 8.0 及更高版本的設(shè)備不支持以下政策場景和示例。
<devsite-heading text="系統(tǒng)映像的其他擴展,這些擴展需要在僅支持框架的 OTA 之后獲得新供應(yīng)商映像組件的權(quán)限" for="additional-extensions" level="h4" link="" class="">#### 系統(tǒng)映像的其他擴展,這些擴展需要在僅支持框架的 OTA 之后獲得新供應(yīng)商映像組件的權(quán)限</devsite-heading>
示例:在下一個 Android 版本中添加新的非 AOSP 系統(tǒng)進程(需要自己的域),該進程需要訪問新的非 AOSP HAL。
與新(非 AOSP)系統(tǒng)和供應(yīng)商組件之間的交互類似,不同之處在于新的系統(tǒng)類型是在僅針對框架的 OTA 中引入的。雖然這個新類型可以添加到 system/sepolicy/public 中的政策里,但現(xiàn)有的供應(yīng)商政策不知道這個新類型,因為它僅跟蹤 Android 8.0 系統(tǒng)公共政策。AOSP 可通過某個屬性(例如 hal_foo 屬性)要求取得供應(yīng)商提供的資源,進而處理此情況,但由于屬性合作伙伴擴展在 system/sepolicy/public 中不受支持,因此供應(yīng)商政策無法使用此方法。訪問權(quán)限必須由之前存在的公共類型提供。
示例:對系統(tǒng)進程(AOSP 或非 AOSP)的更改必須更改它與新的非 AOSP 供應(yīng)商組件進行互動的方式。
在編寫系統(tǒng)映像上的政策時必須對供應(yīng)商獨有的自定義不知情。因此,系統(tǒng)會通過 system/sepolicy/public 中的屬性公開 AOSP 中涉及特定接口的政策,以便供應(yīng)商政策可以選擇啟用將來使用這些屬性的系統(tǒng)政策。不過,system/sepolicy/public 中的屬性擴展不受支持,因此用于指示系統(tǒng)組件如何與新供應(yīng)商組件交互的全部政策(該政策不由 AOSP system/sepolicy/public 中已存在的屬性進行處理)都必須位于 device/<var>manufacturer</var>/<var>device-name</var>/sepolicy 中。這意味著系統(tǒng)類型無法在僅針對框架的 OTA 中更改已為供應(yīng)商類型授予的訪問權(quán)限。