SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统。NSA是在Linux社区的帮助下开发了一种访问控制体系,在这种访问控制体系的限制下,进程只能访问那些在他的任务中所须要文件linux
在 SELinux 出现以前,Linux 上的安全模型叫 DAC,全称是 Discretionary Access Control,翻译为自主访问控制。 DAC 的核心思想很简单,就是:进程理论上所拥有的权限与执行它的用户的权限相同。好比,以 root 用户启动 Browser,那么 Browser 就有 root 用户的权限,DAC 管理太过宽松,不够灵活因此有了SELinux。android
在这种访问控制体系的限制下,进程只能访问那些在他的任务中所须要文件。shell
SELinux使用类型强制来改进强制访问控制。全部的主体(程序进程)对客体(文件/socket等资源)的访问都有一条TE规则来许可。当程序访问一个资源的时候,系统会搜索全部的TE规则集,并根据结果进行处理。这个规则集是由访问向量规则(AV, Access Vector)来描述的。安全
内核向外部暴露容许访问的资源权限,由TE来描述主体拥有什么样的访问权。SELinux定义了30个不一样的客体类别:app
security process system capability filesystem file dir fd lnk_file chr_file blk_file socket_file ...
socket
每一个客体类别都定义了操做许可,好比针对file有19个操做许可:测试
`ioctl read write create getattr setattr lock relablefrom relableto append unlink link rename execute swapon quotaon mounton execute_no_trans entrypointui
在 SELinux 中,每种东西都会被赋予一个安全属性,官方说法叫作 Security Context,Security Context 是一个字符串,主要由三个部分组成,例如 SEAndroid 中,进程的 Security Context 可经过 ps -Z 命令查看:翻译
rk3288:/ $ ps -AZ u:r:hal_wifi_supplicant_default:s0 wifi 1816 1 11388 6972 0 0 S wpa_supplicant u:r:platform_app:s0:c512,c768 u0_a14 1388 228 1612844 57396 0 0 S android.ext.services u:r:system_app:s0 system 1531 228 1669680 119364 0 0 S com.android.gallery3d u:r:kernel:s0 root 582 2 0 0 0 0 S [kworker/1:2] u:r:radio:s0 radio 594 228 1634876 89296 0 0 S com.android.phone u:r:system_app:s0 system 672 228 1686204 141716 0 0 S com.android.settings u:r:platform_app:s0:c512,c768 u0_a18 522 223 1721656 152116 0 0 S com.android.systemui
上面的最左边的一列就是进程的 Security Context,以第一个进程 wpa_supplicant 为例debug
u:r:hal_wifi_supplicant_default:s0
AV用来描述主体对客体的访问许可。一般有四类AV规则:
allow:表示容许主体对客体执行许可的操做.
neverallow:表示不容许主体对客体执行制定的操做。
auditallow: 表示容许操做并记录访问决策信息。
dontaudit:表示不记录违反规则的决策信息,切违反规则不影响运行`
通用的类型规则语法位:
1 allow platform_app debugfs:file { read ioctl };
表示类别为platform_app的程序进程,对debugfs类型的文件执行read和ioctl操做。
SELINUX有「disabled」「permissive」,「enforcing」3种选择。
Disabled就不用说了。
permissive就是Selinux有效,可是即便你违反了策略的话它让你继续操做,可是把你的违反的内容记录下来。在咱们开发策略的时候很是的有用,是UserDebug的默认模式。
Enforcing就是你违反了策略,你就没法继续操做下去。
经过如下命令能够切换系统的SElinux模式 adb shell setenforce 0
0--表明Permissive
1--表明Enforcing
adb shell getenforce---查看状态
在android系统开发中,由于selinux权限问题通常会在user版本出现,但咱们在userdebug版本经过如下方式能够验证
1、第一步先肯定问题是否由selinux权限问题引发
经过命令: adb shell getenforce //查看当前SePolicy权限状态(Enforcing 表示打开 Permissive表示关闭)
userdebug版本处于permissive关闭状态 settenforce 1 //更改状态到Enforcing,0表示Permissive 进行测试,若是此时问题会出现,那么就是selinux权限问题
二、解决方法
1.adb shell dmesg----抓kernel log
(特别说明:adb shell "cat /proc/kmsg | grep avc" > avc_log.txt 能够直接提出avc的log)
2.adb logcat –b events
关键字:
avc: denied
如图:
这是一个selinux权限问题,咱们只关注denied{} 、scontext 、tcontext 和 tclass 四个关键字就能够
denied{}括号内的内容表示被拒的权限动做
scontext的值表示须要在哪一个te文件添加
tcontext 表示须要赋予权限的目标
tclass 表示权限问题的类型
这个问题的修改方式是在system_app.te文件添加以下代码: allow system_app sysfs_thermal:dir search;
注意:有时在Enforcing模式时不能看到全部缺乏的权限日志,例如:
这个日志因为FileNotFoundException问题致使程序不会继续执行到代码终点,因此没有执行的代码所缺乏的权限日志就不能获得,可是在Permissive模式全部权限问题会打印出来,因此建议抓log在Permissive模式下或者两种模式都抓