一始藕、SELinux/SEAndroid簡(jiǎn)介
安全增強(qiáng)型 Linux(Security-Enhanced Linux)簡(jiǎn)稱(chēng) SELinux,它是一個(gè) Linux 內(nèi)核模塊捉捅,也是 Linux 的一個(gè)安全子系統(tǒng)佛掖。2.6 及以上版本的 Linux 內(nèi)核都已經(jīng)集成了 SELinux 模塊。
Android底層是基于linux架構(gòu)的忽肛,SEAndroid是Google在Android 4.4上正式推出的一套以SELinux為基礎(chǔ)于核心的系統(tǒng)安全機(jī)制。
二烂斋、設(shè)計(jì)目的
最大限度地減小系統(tǒng)中服務(wù)進(jìn)程可訪(fǎng)問(wèn)的資源(最小權(quán)限原則)屹逛。
三.安全模型介紹
DAC(Discretionary Access Control):自主訪(fǎng)問(wèn)控制础废。在沒(méi)有使用 SELinux 的操作系統(tǒng)中,決定一個(gè)資源是否能被訪(fǎng)問(wèn)的因素是:某個(gè)資源是否擁有對(duì)應(yīng)用戶(hù)的權(quán)限(讀罕模、寫(xiě)评腺、執(zhí)行)。只要訪(fǎng)問(wèn)這個(gè)資源的進(jìn)程符合以上的條件就可以被訪(fǎng)問(wèn)淑掌。而最致命問(wèn)題是蒿讥,root 用戶(hù)不受任何管制,系統(tǒng)上任何資源都可以無(wú)限制地訪(fǎng)問(wèn)抛腕。這種權(quán)限管理機(jī)制的主體是用戶(hù)芋绸。
MAC(Mandatory Access Control): 強(qiáng)制訪(fǎng)問(wèn)控制。在使用了 SELinux 的操作系統(tǒng)中担敌,決定一個(gè)資源是否能被訪(fǎng)問(wèn)的因素除了上述因素之外摔敛,還需要判斷每一類(lèi)進(jìn)程是否擁有對(duì)某一類(lèi)資源的訪(fǎng)問(wèn)權(quán)限。這樣一來(lái)全封,即使進(jìn)程是以 root 身份運(yùn)行的马昙,也需要判斷這個(gè)進(jìn)程的類(lèi)型以及允許訪(fǎng)問(wèn)的資源類(lèi)型才能決定是否允許訪(fǎng)問(wèn)某個(gè)資源。進(jìn)程的活動(dòng)空間也可以被壓縮到最小售貌。即使是以 root 身份運(yùn)行的服務(wù)進(jìn)程给猾,一般也只能訪(fǎng)問(wèn)到它所需要的資源。即使程序出了漏洞颂跨,影響范圍也只有在其允許訪(fǎng)問(wèn)的資源范圍內(nèi)敢伸。安全性大大增加。這種權(quán)限管理機(jī)制的主體是進(jìn)程恒削。
可以看到池颈,在 DAC 模式下,只要相應(yīng)目錄有相應(yīng)用戶(hù)的權(quán)限钓丰,就可以被訪(fǎng)問(wèn)躯砰。而在 MAC 模式下,還要受進(jìn)程允許訪(fǎng)問(wèn)目錄范圍的限制携丁。
SELinux帶給Linux的主要價(jià)值是:提供了一個(gè)靈活的琢歇,可配置的MAC機(jī)制。
四李茫、基本概念
SELinux 是通過(guò) MAC 的方式來(lái)控管程序肥橙,他控制的主體是程序(進(jìn)程), 而目標(biāo)則是該程序能否讀取的文件資源存筏。
主體 (Subject):進(jìn)程
目標(biāo) (Object):被訪(fǎng)問(wèn)的資源(可以是文件宠互、目錄味榛、端口予跌、設(shè)備等)。
政策 (Policy):訪(fǎng)問(wèn)限制條件
- targeted:針對(duì)網(wǎng)絡(luò)服務(wù)限制較多匕得,針對(duì)本機(jī)限制較少继榆,是默認(rèn)的政策巾表;
- strict:完整的 SELinux 限制,限制方面較為嚴(yán)格集币。
- 其他策略
一般使用默認(rèn)的 targeted 政策即可。
安全上下文 (Security Context):
主體能不能存取目標(biāo)除了政策指定之外乞榨,主體與目標(biāo)的安全性本文必須一致才能夠順利存取当娱。
SELinux驗(yàn)證整體流程:
DAC MAC的驗(yàn)證順序是:
Linux系統(tǒng)先做DAC檢查跨细,如果沒(méi)有通過(guò)直接失敗,如果通過(guò)了震叙,再做MAC權(quán)限檢查散休。
五、SELinux 工作模式
SELinux 有三種工作模式戚丸,分別是:
1. enforcing:強(qiáng)制模式限府。違反 SELinux 規(guī)則的行為將被阻止并記錄到日志中。
2. permissive:寬容模式拂共。違反 SELinux 規(guī)則的行為只會(huì)記錄到日志中姻几。一般為調(diào)試用势告。
3. disabled:關(guān)閉 SELinux抚恒。
adb shell getenforce 查看模式。
adb shell setenforce 0|1 分別對(duì)應(yīng)切換 permissve | enforcing 模式
三種工作模式的驗(yàn)證過(guò)程:
六回溺、Security Context詳解
SELinux中遗遵,每種東西都賦予一個(gè)安全屬性逸嘀,官方叫:Security Context 直譯就是安全上下文。它是一個(gè)字符串崭倘。
Scontext分為:進(jìn)程的scontext 和 文件的tcontext司光。兩者匹配時(shí),才會(huì)允許進(jìn)程訪(fǎng)問(wèn)文件榆俺,若不匹配時(shí)則不被允許跪削。
Security Context用冒號(hào)分為四個(gè)字段: user : role : type : level
字段 | 說(shuō)明 |
---|---|
用戶(hù)(User) | root:表示 root 的帳號(hào)身份。 system_u:表示系統(tǒng)程序方面的識(shí)別晃跺,通常就是程序毫玖。 user_u:代表的是一般使用者帳號(hào)相關(guān)的身份。 或者直接一個(gè) u 表示用戶(hù) |
角色(Role) | object_r:代表的是文件或目錄等文件資源烹玉,這應(yīng)該是最常見(jiàn)的阐滩。system_r/r:代表程序,但一般使用者也會(huì)被指定成為 system_r/r 继效。 |
類(lèi)型(Type) | type:在文件資源 (Object) 上面稱(chēng)為類(lèi)型 (Type)。 domain:在主體程序 (Subject) 則稱(chēng)為領(lǐng)域 (domain) 厉颤。 domain 需要與 type 搭配凡简,則該程序才能夠順利的讀取文件資源 |
級(jí)別(Level) | MSL安全級(jí)別 |
SEAndroid下舉例:
查看文件的tcontext: adb shell ls -Z
dr-xr-xr-x 69 root root u:object_r:cgroup:s0 0 1971-03-14 07:23 acct
查看進(jìn)程的scontext: adb shell ps -Z
u:r:init:s0 root 1 0 16204 1284 SyS_epoll_ 00004c7df8 S /init
七秤涩、安全策略-TE介紹
安全策略是在安全上下文的基礎(chǔ)上進(jìn)行描述的,也就是說(shuō)溉仑,它通過(guò)主體和客體的安全上下文浊竟,定義主體是否有權(quán)限訪(fǎng)問(wèn)客體津畸。SEAndroid安全機(jī)制主要是使用對(duì)象安全上下文中的類(lèi)型來(lái)定義安全策略,這種安全策略就稱(chēng)Type Enforcement后频,簡(jiǎn)稱(chēng)TE暖途。所有以.te為后綴的文件經(jīng)過(guò)編譯之后,就會(huì)生成一個(gè)sepolicy文件露久。這個(gè)sepolicy文件會(huì)打包在ROM中欺栗,并且保存在設(shè)備上。
根據(jù)SELinux規(guī)范消请,完整的allow相關(guān)的語(yǔ)句格式為:
rule_name source_type target_type : class perm_set
source_type 和 target_type 都是查看進(jìn)程和文件對(duì)應(yīng)的安全上下文得來(lái)的类腮。
具體字段說(shuō)明如下:
字段 | 描述 |
---|---|
rule_name(訪(fǎng)問(wèn)控制規(guī)則) | allow : 允許主體對(duì)客體進(jìn)行操作 neverallow :拒絕主體對(duì)客體進(jìn)行操作 dontaudit : 表示不記錄某條違反規(guī)則的決策信息 auditallow :記錄某項(xiàng)決策信息蚜枢,通常SElinux只記錄失敗的信息七婴,應(yīng)用這條規(guī)則后會(huì)記錄成功的決策信息察滑。 |
source_type(訪(fǎng)問(wèn)者類(lèi)型) | 進(jìn)程 ,屬性為domain類(lèi)型户盯,代表主體饲化。 |
target_type(目標(biāo)類(lèi)型) | 資源,(文件硫眨、目錄巢块、端口等)屬性為type類(lèi)型族奢,代表客體,目標(biāo)類(lèi)型可以指定多個(gè)越走。 |
class (客體類(lèi)別) | 允許訪(fǎng)問(wèn)的客體類(lèi)別廊敌,是對(duì)目標(biāo)類(lèi)型的限制。常見(jiàn)類(lèi)別: class filesystem class file 普通文件 class dir 目錄 class fd 文件描述 class lnk_file 鏈接文件 class chr_file 字符設(shè)備文件 ... |
perm_set(權(quán)限) | 指定主體可以對(duì)客體進(jìn)行操作的種類(lèi)锅纺。常見(jiàn)權(quán)限操作如下: ioctl秧廉、read、write嚼锄、create蔽豺、getattr、setattr沧侥、lock、relabelfrom癣朗、relabelto旺罢、append、link正卧、rename跪解、execute、swapon窘行、quotaon节吮、mounton |
另外對(duì)SEAndroid app分類(lèi)稍微做下總結(jié):
platform_app.te(具有android platform簽名,沒(méi)有system權(quán)限的app)
system_app.te(具有android platform簽名與system權(quán)限的app)
untrusted_app.te(第三方app, 不具有android platform簽名和system權(quán)限)
看看allow語(yǔ)句的例子:
1.允許zygote domain中的進(jìn)程向init type的進(jìn)程(Object Class為process)發(fā)送sigchld信號(hào)
allow zygote init:process sigchld;
2.允許zygote域中的進(jìn)程search或getattr類(lèi)型為appdomain的目錄。注意帚豪,多個(gè)perm_set, 可用{}括起來(lái)
allow zygote appdomain:dir { getattr search };
當(dāng)然語(yǔ)法還有很多草丧,這部分可以自行去系統(tǒng)學(xué)習(xí)昌执,本文只是介紹基本的。
八懂拾、實(shí)戰(zhàn)演習(xí)
例如一個(gè)需求:在AMS 中寫(xiě) /d/rtmm/reclaim/objectfile 文件
- 首先要滿(mǎn)足DAC驗(yàn)證:首先確認(rèn)system system是否有objectfile文件的寫(xiě)權(quán)限岖赋,如果沒(méi)有,修改.rc文件选脊。具體對(duì)應(yīng)是哪個(gè)文件,得去看mk了
假設(shè)system沒(méi)權(quán)限偏灿,那修改owner 和 group:
on boot
chown system system /d/rtmm/reclaim/objectfile
- 然后走M(jìn)AC驗(yàn)證:
首先AMS是在system_server進(jìn)程钝的,看看system_server的安全上下文:
mido:/d/rtmm/reclaim # ps -Z | grep "system_server"
u:r:system_server:s0 system 1533 719 2717140 357292 SyS_epoll_ 7fb57e5540 S system_server
再看看目標(biāo)文件objectfile的安全上下文:
mido:/d/rtmm/reclaim # ls -Z
-rw-rw---- 1 system system u:object_r:debugfs_rtmm:s0 0 2018-10-25 18:19 objectfile
找到對(duì)應(yīng)的te文件:system_server.te
allow system_server debugfs:file w_file_perms;
w_file_perms 是定義的一個(gè)宏扁藕,比純write要好,包括了后續(xù)一些寫(xiě)完的收尾處理工作亿柑。
九望薄、錯(cuò)誤分析和解決
很多情況下,我碰到的問(wèn)題是通過(guò)報(bào)錯(cuò)來(lái)看缺少什么權(quán)限颁虐,原則是"缺什么補(bǔ)什么". 看兩個(gè)案例:
案例一:
audit(0.0:67):avc: denied {write } forpath="/dev/block/vold/93:96" dev="tmpfs" ino=1263scontext=u:r:kernel:s0tcontext=u:object_r:block_device:s0tclass=blk_filepermissive=0
分析過(guò)程:
缺少什么權(quán)限: { write }權(quán)限卧须,
誰(shuí)缺少權(quán)限: scontext=u:r:kernel:s0,
對(duì)哪個(gè)文件缺少權(quán)限:tcontext=u:object_r:block_device
什么類(lèi)型的文件: tclass=blk_file
解決方法:kernel.te
allow kernel block_device:blk_file write;
案例二:
03-23 10:15:40.290 1422 1422 W Pipe_Write_Hand:type=1400 audit(0.0:79): avc: denied { ioctl } forpath="socket:[19308]" dev="sockfs" ino=19308scontext=u:r:system_app:s0 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socketpermissive=0
03-23 10:15:40.301 1280 1422 W System.err: Java.io.IOException: Permission denie
解決方法:
在system_app.te里添加 bluetooth_domain(system_app)
原因: bluetooth.te中對(duì)bluetooth_domain屬性賦予了權(quán)限
allow bluetoothdomain bluetooth:unix_stream_socket { getopt setopt getattr read write ioctl shutdown};
參考:
https://blog.csdn.net/innost/article/details/19299937#comments
https://blog.csdn.net/ztguang/article/details/62834072?utm_source=blogxgwz0
https://blog.csdn.net/hanmengaidudu/article/details/60766591
http://cn.linux.vbird.org/linux_basic/0440processcontrol_5.php