Android SELinux安全策略主要使用对象安全上下文的基础进行描述,通过主体和客体的安全上下文去定义主体是否有权限访问客体,称为TypeEnforcement
安全上下文(Security Context)
SEAndroid中的安全上下文:共有4个部分组成分别为user、role、type、sensitivity level
以u:object_r:system_data_file:s0为例
user
:安全上下文的第一列为user,在SEAndroid中的user只有一个就是u。role
:第二列表示role,在SEAndroid中的role有两个,分别为r和object_r。type
:第三列为type,SEAndroid中共定义了139种不同的type。security level
:第四列是专为MLS访问机制所添加的安全上下文的扩展部分,
格式为sensitivity[:category list][- sensitivity[:category list]]
,例如s0 - s15:c0.c1023,
其中s0之后的内容可以不需要,冒号后面的内容是category,sensitivity和category组合一起声明了当前的安全级别(security level),“-”号左右分别标识了安全级别的最低和最高,这一列的参数将在MLS约束检查时用到,“15”、“1023”表示了sensitivity和category的最大值,这一参数可在Android.mk中定义。
安全上下文中最重要的部分就是第三列的type了,对于进程type被称为domain
,type是整个SEAndroid中最重要的一个参量,所有的policy都围绕这一参量展开,所以为系统中每个文件标记上合适的type就显得极为重要了。在SEAndroid中关于安全上下文配置的核心文件主要是file_contexts、seapp_contexts和property_contexts 文件。
sContext相关文件 | 表示的上下文 |
---|---|
file_contexts | 系统中所有file_contexts安全上下文 |
seapp_contexts | app安全上下文 |
property_contexts | 属性的安全上下文 |
service_contexts | service文件安全上下文 |
genfs_contexts | 虚拟文件系统安全上下文 |
类型强制TE(Type Enforcement)
TE强制访问方式是SEAndroid中的最主要的安全手段,所有关于TE的强制访问规则都被定义在了后缀为te的文件中
在te文件中基本能总结为完成如下操作:
(1)对type类型的定义和将type归到相应的attribute中
SEAndroid在te文件中定义了安全策略中最基本的参量type,同时将具有共性的type归在一起构成一个称为attribute的集合,policy的规则执行也能以attribute作为执行对象。
(2)通过allow语句制定主体客体强制访问规则(白名单规则,不再规则中的都默认为非法操作)
(3)通过type_transition语句制定tpye类型转换规则
(4)通过dontaudit语句声明对一些被安全策略拒绝的访问不再进行审核。
审核是对于发生了访问违规或出现了被系统安全规则拒绝的行为进行日志记录的过程,审核可以帮助系统管理员发现bug和可能的入侵尝试。
默认情况下,SEAndroid会记录被拒绝的访问检查,但策略语言dontaudit允许我们取消这些默认的预料之中的拒绝审核消息。
- SEAndroid为所有type共定义了17个attribute:
attribute | 含义 |
---|---|
dev_type: | 包含了所有关于设备的type |
domain: | 包含了如下所列的所有关于进程的type,通常策略中的访问主体也就是进程所在的domain都包含在了这一attribute中。 |
fs_type: | 包含了所有与文件系统相关的type。如下所列,大多是虚拟文件系统。 |
file_type: | 包含了所有存在于非伪文件系统的相关文件的type,数量过多不再列举。 |
exec_type: | 包含了所有关于domian接入点的type,多被用在domain transition中 |
data_file_type: | 包含了所有在/data目录下的文件type |
sysfs_type: | 包含了在sysfs文件系统下的所有文件的type,在SEAndroid中只有sysfs_writable包含在这个attribute中。 |
node_type: | 所有与nodes/hosts有关的type,在SEAndroid中只有node包含在这个attribute中。 |
netif_type: | |
port_type: | 包含了所有与网络端口相关的type,在SEAndroid中只有port包含在这个attribute中。包含了所有与网络接口相关的type,在SEAndroid中只有netif包含在这个attribute中。 |
mlstrustedsubject: | 包含了所有能越过MLS检查的主体domain。 |
mlstrustedobject: | 包含了所有能越过MLS检查的客体type。 |
unconfineddomain: | 包含了所有拥有无限权限的type。 |
appdomain: | 包含了所有与app相关的type |
netdomain: | 包含了所有与需要访问网络的app相关的type |
bluetoothdomain: | 包含了所有与需要访问bluetooth的app相关的type |
binderservicedomain: | 包含了所有与binder服务相关的type |
SEAndroid中共定义了三个拥有巨大权限的attribute,分别是mlstrustedsubject、mlstrustedobject、unconfineddomain
mlstrustedsubject的type:在充当主体domain是可以越过MLS检查,
mlstrustedobject的type:在充当客体时可以越过MLS检查,
unconfineddomain的type:则拥有所有权限可对客体进行任意操作。
- SEAndroid为系统定义了33个te策略文件,这33个策略文件是:
adbd.te、file.te、su.te、app.te、gpsd.te、netd.te、system.te、bluetoothd.te、init.te、net.te、ueventd.te、bluetooth.te、installd.te、nfc.te、unconfined.te、cts.te、kernel.te、qemud.te、vold.te、dbusd.te、keystore.te、radio.te、wpa_supplicant.te、debuggerd.te、mediaserver.te、rild.te、zygote.te、device.te、servicemanager.te、domain.te、shell.te、drmserver.te、surfaceflinger.te
TE一般放在device/qcom/sepolicy/
和system/sepolicy
中,所有.te后缀的文件通过编译之后,都会生成一个sepolicy文件
常见te | 含义 |
---|---|
file.te | 针对属性file的策略 |
init.te | 在这一文件中声明了init拥有无限权限 |
rild.te | 针对daemon domain的策略 |
system.te | 这一文件主要针对的是系统app和system server进程。对系统app访问binder、systemdata files、dalvikcatch、keystone等进行权限控制,对system server访问网络、bluetooth、netlink、app、binder、device、data files、socket、cache files等进行权限控制 |
app.te | 在这一文件里将安装在系统上的第三方app分类为受信任的app和不受信任的app,分别用不同的type表示,再分别为这两种app在访问网络,bluetooth,sdcard,数据,缓存,binder等等名感位置时设置相应权限 |
AVC LOG的抓取
1.提取所有的avc
adb shell “cat /proc/kmsg | grep avc” > avc_log.txt
或者
logcat -b events | grep avc
2.使用 audit2allow tool 直接生成policy
sudo apt install policycoreutils
audit2allow -i avc_log.txt 即可自动输出生成的policy
selinux权限添加相关: 将所有avc相关log拷贝到avc.txt中,将avc.txt拷贝到相关项目根目录下,执行 audit2allow -i avc.txt
会生成相应的权限语句;
3.查看安全上下文scontext:属于什么te
查看进程(APP):ps -Z
查看文件:ls -Z
AVC LOG分析
- 示例:
I auditd : type=1400 audit(0.0:4720): avc: denied { write } for comm="sh" name="export" dev="sysfs" ino=10547 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0
- avc参数分析:
denied
后面{}里的是要执行的动作,比如append,open,execmod,link等等scontext
指的是域,对应的是te文件 上面报错这条对应te文件是untrusted_app.te,scontext全写是source_type context;tcontext
指的是目标类型,上面报错这条对应的是目标类型system_file,tcontext全写是target_type context;tclass
指的是类别,上面报错这条对应的是类别是file
- 添加对应TE
allow untrusted_app sysfs:file write;
TE表达式格式:
rule_name
:规则名称,除了有allow还有dontaudit,auditallow和neverallowsource_type
:源类型,对应一个很重要的概念--------域(domain)tartget_type
:目标的类型,即安全上下文,SELinux一个重要的判断对象class
:类别,目标(客体)是哪种类别,主要有File,Dir,Socket,SEAndroid还有Binder等,在这些基础上又细分出设备字符类型(chr_file),链接文件(lnk_file)等。可以通过ls -l查看文件类型perm_set
:动作集
- 验证
重新编译bootimage:make bootimage
相关示例
- SEAndroid为APP层读写sys设备节点
自定义类型
开放访问权限方法(如:sys/class/leds/red_aux/brightness)
1.添加设备节点读写权限
system/core/rootdir/init.rc
//开放节点让系统进程可以访问
chown system system /sys/class/leds/red_aux/brightness
//修改设备节点可读可写
chmod 0666 /sys/class/leds/red_aux/brightness
2.修改file.te,加入类型声明,定义selinux type
device/qcom/sepolicy/common/file.te
//表示sysfs_ledred_leds 节点具有fs_type和sysfs_type属性
type sysfs_ledred_leds, fs_type, sysfs_type;
3.修改file_contexts
device/qcom/sepolicy/common/file_contexts
//绑定sysfs_ledred_leds到对应的实际节点
/sys/devices/soc/75b5000.i2c/i2c-7/7-0045/leds/red_aux/brightness u:object_r:sysfs_ledred_leds:s0
4.修改sysetem_app.te文件,加入权限声明
device/qcom/sepolicy/common/file_contexts
//表示允许system_app进程能够拥有对sysfs_ledred_leds的这个字符设备的读写权限,rw_file_perms代表读写权限
allow system_app sysfs_ledred_leds:file rw_file_perms;
注意:以上的sysfs_ledred_leds必须与file.te文件中声明的文件类型、名称必须一致
5.APP需配置为系统APP
在AndroidMainefest.xml中配置android:sharedUserId="android.uid.system"
- 新增allow xxx权限,编译报错neverallow的处理方式示例
allow radio vendor_data_file:file { read };
- 国内版本可适当注释掉原生相关neverallow进行规避,
不推荐方式
根据报错信息 在918行 system/sepolicy/public/domain.te加上 -radio
- CTS版本不能有任何neverallow,只能去掉添加的权限,自定义类型,绕过neverallow限制,
推荐方式
这是因为我们添加的SELinux权限违反了google的neverallow规则,google不允许名为radio源类型访问标签名为vendor_data_file的目标类型,
解决方案是修改我们要访问的文件的标签名vendor_data_file,如何修改呢?我们要访问的目录是/data/vendor/time_code/,先看一下这个目录的信息
ls -Z data/vendor/time_code/
需要修改的标签属于文件类型,另外还有属性类型和程序类型,对于文件类型标签的修改就是自定义一个新的标签,在file.te中定义,在file_contexts中使用
file.te中添加如下语句:
type tct_time_data_file, file_type, data_file_type, mlstrustedobject;
file_contexts中添加如下语句:
/data/vendor/time_code(/.*)? u:object_r:tct_time_data_file:s0
标签就被修改为了tct_time_data_file,然后再修改radio.te中的目标类型
allow radio tct_time_data_file:dir rw_dir_perms;
再进行编译
相关拓展
- 常用文件
属性相关:property.te
property_contexts
文件相关:file.te
file_contexts
第三方应用配置:untrusted_app.te
platform系统应用配置:platform_app.te
- 动作集
dir:
create_dir_perms、search、r_dir_perms、rw_dir_perms、ra_dir_perms
file:
create_file_perms、r_file_perms、rx_file_perms、x_file_perms、rw_file_perms
这里的rw_file_perms是一个包含所有的读写权限
define(r_file_perms’,{ getattr open read ioctl lock }‘)
define(w_file_perms’,{ open append write }‘)
define(rw_file_perms’,{ r_file_perms w_file_perms }')
相关参考
Android SELinux avc dennied权限问题解决方法
一文彻底明白linux中的selinux到底是什么
https://www.cnblogs.com/linhaostudy/p/8662534.html
https://blog.csdn.net/weixin_43835637/article/details/86508214
https://www.jb51.net/article/128214.htm
https://www.jianshu.com/p/88a92d101532
https://www.freesion.com/article/3645654781
https://www.pianshen.com/article/85991051081
https://www.jianshu.com/p/8b0e72776118
https://blog.csdn.net/gbmaotai/article/details/82415614