SElinux 使用和配置

之前這篇文章AOSP安全策略SElinux_android以及問題排查思路過于繁瑣。因此直接來個(gè)相對(duì)實(shí)用的。

一、SElinux 規(guī)則修改

    SDK 中已經(jīng)配置有一套合理的 SElinux policy。在 SDK 開發(fā)過程中,可以根據(jù)需要,編輯規(guī)則文件,增加自定義規(guī)則。規(guī)則中由四個(gè)部分組成:**用戶**、**角色**、**類型**、**敏感度**。
  • 用戶:在 SEAndroid 中第一列安全上下文是用戶并且只有一個(gè) u。

  • 角色:在 SEAndroid 中第二列表示角色 ,分別為 r:主體(Subject)角色,object_r:客體(Object)角色。

    • u:r:type:s0(對(duì)進(jìn)程)及主動(dòng)實(shí)體。
    • u:object_r:type:s0(對(duì)文件/資源)及被動(dòng)資源。
  • 類型:第三列類型, SEAndroid 確定了上百項(xiàng)不同的策略類型,如設(shè)備類型、進(jìn)程類型文件系統(tǒng)類型、網(wǎng)絡(luò)類型IPC 類型等。

  • 安全級(jí)別:第四列專為多級(jí)安全功能(擴(kuò)展 MLS)而設(shè)計(jì), MLS 是一種訪問機(jī)制,可增加安全上下文和格式敏感度 [: 類別列表] [-敏感度 [: 類別列表]],例如 s0 - s15: c0 - c1023,而在當(dāng)前 Android 版本中不需要類別。敏感度和類別組合表示當(dāng)前的安全級(jí)別,數(shù)字根據(jù)最低和最高級(jí)別的安全功能進(jìn)行確定。此列參數(shù)被用于查看 MLS 限制,其中 “15” 和 “1023” 表示最大敏感度和類別。此參數(shù)范圍可以在 Android.mk 中進(jìn)行確定, Android 中默認(rèn)配置為 “1”和 “1024”,代表敏感度只定義了 s0,類別列表定義了 c0-c1023。

1.查看違反規(guī)則的方法
dmesg | grep avc #或者在串口 log 中查找關(guān)鍵字 denied,即可看到有違反規(guī)則的行為。
2.生成規(guī)則
  • 自動(dòng)生成規(guī)則:使用 linux 工具 audit2allow 可以將違反規(guī)則的 avc 記錄生成放行規(guī)則 (適合于 dmesg 所有輸出,初期的開發(fā)階段)。

  • 手動(dòng)生成規(guī)則: 比如違反 avc 記錄如下:

type=1400 audit(1386760471.880:7): avc: denied { entrypoint } for pid=1227 comm=“init” path=“/sbin/healthd” dev=“rootfs” ino=4396 scontext=u:r:healthd:s0 tcontext=u:object_r:rootfs:s0 tclass=file

關(guān)鍵字對(duì)應(yīng)的屬性名:

scontext_name: healthd tcontext_name: rootfs tclass_type: file rules: entrypoint

放行公式:

allow scontext_name tcontext_name:tclass_type rules;

生成 rule 如下:

allow healthd rootfs:file entrypoint;
3.添加規(guī)則
  • 編輯 device/{vendor-name}/common/sepolicy 目錄下面 TE 格式文件,添加 Step 2 中生成的 rule 到以 **scontext_name **命名的 TE 文件(例如:healthd.te)。
  • 重新編譯 Android 就可以生成新的 SElinux policy 固件。
  • 重新燒錄后可能會(huì)多出一些相關(guān)的權(quán)限警告,一點(diǎn)一點(diǎn)的添加直到?jīng)]有錯(cuò)誤警告為止。
  • 如在編譯過程出現(xiàn)類似如下錯(cuò)誤,說明添加的規(guī)則和 system/sepolicy 設(shè)置的規(guī)則沖突。
neverallow on line 269 of system/sepolicy/domain.te (or line 5193 of policy.conf)
violated by allow platform_app unlabeled:dir { create };
4.解決規(guī)則沖突
    system/sepolicy 定義通用規(guī)則,如果出現(xiàn) device 規(guī)則與其沖突的問題,即 system/sepolicy定義 neverallow 規(guī)則,但是 device 規(guī)則又要允許訪問。這種情況初學(xué)者本能的認(rèn)為需要在system/sepolicy 中的 neverallow 中增加例外規(guī)則,如下實(shí)例。
    實(shí)際上這種做法不妥,在添加 selinux 規(guī)則的時(shí)候盡量不要違背 system/sepolicy 的 neverallow, system/sepolicy 的neverallow 都是 google 工程師經(jīng)過深思熟慮設(shè)置的規(guī)則檢驗(yàn)關(guān)卡,違背了其規(guī)則,證明添加的device 規(guī)則不合理。這種情況下一般是沒有為 scontext 或者 tcontext 定制化標(biāo)簽導(dǎo)致的,請(qǐng)檢查 avc 報(bào)錯(cuò)中是否有 default 或者 unlabel 字樣。  
neverallow all_untrusted_apps {
  hwservice_manager_type
  -same_process_hwservice
  -coredomain_hwservice
  -hal_configstore_ISurfaceFlingerConfigs
  -hal_graphics_allocator_hwservice
  -hal_omx_hwservice
  -untrusted_app_visible_hwservice
  #相應(yīng)加一條?
}:hwservice_manager find;

二、添加 sepolicy 示例

下面舉例說明如何為 Android 的二進(jìn)制程序 pz制定 sepolicy 規(guī)則,相關(guān)規(guī)則見

device/{vendor-name}/common/sepolicy/pz.te
  1. type pz domain,domain_deprecated;為 pz進(jìn)程定義專屬 type pz,關(guān)聯(lián)屬性 domain。

  2. type pz_exec,exec_type,file_type;為 pz 的二進(jìn)制文件定義 type pz_exec。

  3. init_daemon_domain(pz);進(jìn)行進(jìn)程的 domain transition,當(dāng) init 進(jìn)程 fork 并執(zhí)行pz_exec 標(biāo)簽對(duì)應(yīng)的可執(zhí)行文件 pz 時(shí),進(jìn)程的 domain 轉(zhuǎn)為 pz。

  4. 在對(duì) pz 進(jìn)行 sepolicy 的策略配置時(shí),發(fā)現(xiàn) pz 會(huì)創(chuàng)建文件夾/dev/com.koushikdutta.superuser.daemon 和 sock:/dev/com.koushikdutta.superuser.daemon/server 用于通信。因此需要對(duì)這兩個(gè)對(duì)象打上自定義標(biāo)簽,防止發(fā)生 neverallow 規(guī)則沖突。

    • type pz_daemon_device,dev_type 在 device.te 中定義 pz_daemon_device 用于給文件夾打標(biāo)簽。

    • type pz_socket,file_type,mlstrustedobject; 在 pz.te 中定義 pz_sock 用于給 server打標(biāo)簽。

    • file_type_auto_trans(pz,device,pz_daemon_device); 當(dāng) pz 在/dev(context: device)目錄下創(chuàng)建文件夾 com.koushikdutta.superuser.daemon 時(shí),給該文件夾打上qw_daemon_device 標(biāo)簽。

    • file_type_atuo_trans(pz,pz_daemon_device,qw_socket); 當(dāng) pz 在/dev/com.koushikdutta.superuser.daemon/(context:qw_daemon_device) 下創(chuàng)建文件 server 時(shí),給server 打上 qw_socket 標(biāo)簽。

  5. 接下來編譯出固件,根據(jù) dmesg 中的一些 avc 報(bào)錯(cuò)添加一些 allow 規(guī)則,反復(fù)編譯幾次即可。

按照以上規(guī)則不出意外的話就可將 pz 的相關(guān) sepolicy 配置起來。但事與愿違,在添加策略進(jìn)行驗(yàn)證時(shí),發(fā)現(xiàn)一些規(guī)則,如: allow pz pz_socket:sock_file create_file_perms;。這些規(guī)則添加后:

  • 沒有編譯出錯(cuò)

  • 沒有 neverallow 沖突

  • 成功編譯進(jìn) policy.conf

但是在驗(yàn)證時(shí),仍然報(bào)出相關(guān)的 avc denied。經(jīng)過一番查找,發(fā)現(xiàn)該規(guī)則需要相應(yīng)的 mls 權(quán)限才可以被授予對(duì)應(yīng)權(quán)限。 mls 中:

mlsconstrain{sock_file} {write setattr...}(t2==app_data_file or l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject)

簡(jiǎn)單起見,在定義 pz 時(shí),加上 type qw,domain,domain_deprecated,mlstrustedsubject.注: mlstrustedsubject 和 mlstrustedobject 在 mls 權(quán)限控制中擁有至高無上的權(quán)利。

三、SElinux 中的特殊符號(hào)

  1. te 文件每行末尾以分號(hào) “;” 結(jié)束

  2. contexts 文件每行末尾沒有分號(hào) “;”

  3. 通配符? *:對(duì)應(yīng)集合內(nèi)的所有內(nèi)容。? -:表示集合 A 內(nèi)去除某項(xiàng)內(nèi)容 b? ~:表示 ~ 后元素所在集合去除 ~ 后元素剩余的子集

注意:想要在深入了解的請(qǐng)移步至AOSP安全策略SElinux_android以及問題排查思路

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容