Linux學(xué)習(xí) - SELinux/SEAndroid

一、SELinux/SEAndroid簡(jiǎn)介

安全增強(qiáng)型 Linux(Security-Enhanced Linux)簡(jiǎn)稱 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)程可訪問(wèn)的資源(最小權(quán)限原則)。

三.安全模型介紹

DAC(Discretionary Access Control):自主訪問(wèn)控制。在沒(méi)有使用 SELinux 的操作系統(tǒng)中,決定一個(gè)資源是否能被訪問(wèn)的因素是:某個(gè)資源是否擁有對(duì)應(yīng)用戶的權(quán)限(讀、寫(xiě)、執(zhí)行)。只要訪問(wèn)這個(gè)資源的進(jìn)程符合以上的條件就可以被訪問(wèn)。而最致命問(wèn)題是,root 用戶不受任何管制,系統(tǒng)上任何資源都可以無(wú)限制地訪問(wèn)。這種權(quán)限管理機(jī)制的主體是用戶。

MAC(Mandatory Access Control): 強(qiáng)制訪問(wèn)控制。在使用了 SELinux 的操作系統(tǒng)中,決定一個(gè)資源是否能被訪問(wèn)的因素除了上述因素之外,還需要判斷每一類進(jìn)程是否擁有對(duì)某一類資源的訪問(wèn)權(quán)限。這樣一來(lái),即使進(jìn)程是以 root 身份運(yùn)行的,也需要判斷這個(gè)進(jìn)程的類型以及允許訪問(wèn)的資源類型才能決定是否允許訪問(wèn)某個(gè)資源。進(jìn)程的活動(dòng)空間也可以被壓縮到最小。即使是以 root 身份運(yùn)行的服務(wù)進(jìn)程,一般也只能訪問(wèn)到它所需要的資源。即使程序出了漏洞,影響范圍也只有在其允許訪問(wèn)的資源范圍內(nèi)。安全性大大增加。這種權(quán)限管理機(jī)制的主體是進(jìn)程。

可以看到,在 DAC 模式下,只要相應(yīng)目錄有相應(yīng)用戶的權(quán)限,就可以被訪問(wèn)。而在 MAC 模式下,還要受進(jìn)程允許訪問(wèn)目錄范圍的限制。

SELinux帶給Linux的主要價(jià)值是:提供了一個(gè)靈活的,可配置的MAC機(jī)制。

四、基本概念

SELinux 是通過(guò) MAC 的方式來(lái)控管程序,他控制的主體是程序(進(jìn)程), 而目標(biāo)則是該程序能否讀取的文件資源。

主體 (Subject):進(jìn)程

目標(biāo) (Object):被訪問(wèn)的資源(可以是文件、目錄、端口、設(shè)備等)。

政策 (Policy):訪問(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)程訪問(wèn)文件,若不匹配時(shí)則不被允許。
Security Context用冒號(hào)分為四個(gè)字段: user : role : type : level

字段 說(shuō)明
用戶(User) root:表示 root 的帳號(hào)身份。
system_u:表示系統(tǒng)程序方面的識(shí)別,通常就是程序。
user_u:代表的是一般使用者帳號(hào)相關(guān)的身份。 或者直接一個(gè) u 表示用戶
角色(Role) object_r:代表的是文件或目錄等文件資源,這應(yīng)該是最常見(jiàn)的。system_r/r:代表程序,但一般使用者也會(huì)被指定成為 system_r/r 。
類型(Type) type:在文件資源 (Object) 上面稱為類型 (Type)。
domain:在主體程序 (Subject) 則稱為領(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)限訪問(wèn)客體。SEAndroid安全機(jī)制主要是使用對(duì)象安全上下文中的類型來(lái)定義安全策略,這種安全策略就稱Type Enforcement,簡(jiǎn)稱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(訪問(wèn)控制規(guī)則) allow : 允許主體對(duì)客體進(jìn)行操作
neverallow :拒絕主體對(duì)客體進(jìn)行操作
dontaudit : 表示不記錄某條違反規(guī)則的決策信息
auditallow :記錄某項(xiàng)決策信息,通常SElinux只記錄失敗的信息,應(yīng)用這條規(guī)則后會(huì)記錄成功的決策信息。
source_type(訪問(wèn)者類型) 進(jìn)程 ,屬性為domain類型,代表主體。
target_type(目標(biāo)類型) 資源,(文件、目錄、端口等)屬性為type類型,代表客體,目標(biāo)類型可以指定多個(gè)。
class (客體類別) 允許訪問(wèn)的客體類別,是對(duì)目標(biāo)類型的限制。常見(jiàn)類別:
class filesystem
class file 普通文件
class dir 目錄
class fd 文件描述
class lnk_file 鏈接文件
class chr_file 字符設(shè)備文件
...
perm_set(權(quán)限) 指定主體可以對(duì)客體進(jìn)行操作的種類。常見(jiàn)權(quán)限操作如下:
ioctl、read、write、create、getattr、setattr、lock、relabelfrom、relabelto、append、link、rename、execute、swapon、quotaon、mounton

另外對(duì)SEAndroid app分類稍微做下總結(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類型為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 文件

  1. 首先要滿足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
  1. 然后走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
什么類型的文件: 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

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

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

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