一、前言
什么是SELinux?
安全增强型Linux (Security-Enhanced Linux),简称SELinux,是Linux的一个安全子系统(MAC),主要用来最大限度地减小系统中服务进程可访问的资源(最小权限原则)。有宽容和强制两种模式。
为什么要修补?
MAC提供了比传统DAC更精细的权限管理。安卓也在很早之前(应该是4.3+)就引入了SELinux,现如今的安卓系统更是离不开SELinux。有的软件在宽容模式下甚至不能正常工作。虽然已经有很多作业抄了,但在适配自定义ROM时,修补sepolicy(SELinux的策略)依然是必不可少的环节。
二、修补
修补sepolicy一般是在宽容模式下修好一些主要bug之后进行的,当然这全看开发者本人,想什么时候进行都是可以的。
SELinux的一般规则
一般规则语法
allow source target:class permissions;
allow
: 表示允许
source
: 谁发出的权限请求
target
: source
对谁发出的请求,特别地,如果source
和target
是同一个对象,则target
可以直接写成self
class
: target
的类型,如dir
,file
等
permission
: 请求的操作权限,如read
,write
或一组权限
- 一组权限时,须用一对
{}
将权限包起来,内部使用空格进行分隔,如: { read write }
- 此类型语句结尾必须加
;
- 规则一般写进
.te
文件,在文件结尾建议留一个空行
Selinux的报错
W binder:3431_2: type=1400 audit(0.0:207): avc: denied { call } for scontext=u:r:hal_tidaservice_default:s0 tcontext=u:r:servicemanager:s0 tclass=binder permissive=0
avc: denied
: 表示权限被拒绝,很正常
{ call }
: 被拒绝的权限,对应上面的permission
scontext
: 请求来源的上下文,其中hal_tidaservice_default
对应上面的source
tcontext
: 被请求对象的上下文,其中servicemanager
对应上面的target
tclass
: 被请求对象的类型,也就是target class
,对应上面的class
permissive
: 是否处于宽容模式,1
为宽容模式,0
为强制模式
修补
只需要根据报错内容对着语法写一下就行
如,对于上面的报错,只需以下内容:
allow hal_tidaservice_default servicemanager:binder call;
宏
为了简化规则定义,Android 提供了一组宏来处理最常见的情况。
例如
W touch-report: type=1400 audit(0.0:196): avc: denied { read } for name="abnormal_event" dev="sysfs" ino=114890 scontext=u:r:hal_touchfeature_xiaomi_default:s0 tcontext=u:object_r:sysfs_touch_hostprocess:s0 tclass=file permissive=0
W touch-report: type=1400 audit(0.0:195): avc: denied { write } for name="abnormal_event" dev="sysfs" ino=127401 scontext=u:r:hal_touchfeature_xiaomi_default:s0 tcontext=u:object_r:sysfs_touch_hostprocess:s0 tclass=file permissive=0
上述报错按照一般语法来修补的话需要写成如下形式:
allow hal_touchfeature_xiaomi_default sysfs_touch_hostprocess:file { read write };
但是利用宏,我们可以简写成以下形式:
allow hal_touchfeature_xiaomi_default sysfs_touch_hostprocess:file rw_file_perms;
这里的宏rw_file_perms
包含了r_file_perms
和 w_file_perms
两个宏,
而r_file_perms
包含了getattr open read ioctl lock map watch watch_reads
w_file_perms
包含了 open append write lock map
# 原文如下
define(`r_file_perms', `{ getattr open read ioctl lock map watch watch_reads }')
define(`w_file_perms', `{ open append write lock map }')
define(`rw_file_perms', `{ r_file_perms w_file_perms }')
更多宏定义请参阅 global_macros
和 te_macros
文件。
ps:合理利用宏,可以大幅减少我们的工作量。比如上面的报错,第一次只报了read
,补完之后再开机才报的 write
,类似的情况还有很多,所以要学会合理运用宏。
安全上下文
其实就是个相应的文件、服务之类的对象打上标签,然后selinux根据相应的标签对相应的权限进行管制。
其格式通常为:user:role:type:sensitivity[:categories]
,当然,一般情况下,可以直接忽略其他部分,只写type
部分。user
直接写成u
,role
直接写成object_r
,sensitivity
直接写成s0
,categories
直接忽略。详见此处
file_contexts
用于为文件分配标签,并且可供多种用户空间组件使用。
如
/sys/devices/virtual/touch/touch_dev/abnormal_event u:object_r:sysfs_touch_hostprocess:s0
就是给abnormal_event
分配了sysfs_touch_hostprocess
的标签。
genfs_contexts
用于为不支持扩展属性的文件系统(例如,proc
或 vfat
)分配标签。
如
genfscon proc "/tp_hal_version" u:object_r:proc_tp_file:s0
To be continued… 我去,按了下esc,写的东西都没了