赞
踩
SELinux是一种加强文件安全的一种策略,用于访问系统资源时进行权限的检查,检查通过才能获得资源访问权限。
名称 | 作用 |
---|---|
permissive | 宽容模式:权限拒绝事件会被记录下来,但不会被强制执行。 |
enforcing | 强制模式:权限拒绝事件会被记录下来并强制执行。 |
在强制模式下,非法操作会被阻止,并且尝试进行的所有违规行为都会被内核记录到 dmesg 和 logcat。
可以通过adb命令来来获取当前工作模式
adb shell getenforce
也可以通过adb命令来设置当前模式
adb root
adb shell setenforce 0或1
setenforce 0设置当前模式为Permissive;setenforce 1设置当前模式为Enforcing
可以通过更改修改system/core/init/selinux.cpp文件里的IsEnforcing()函数,将该函数直接返回false值,来关闭selinux
bool IsEnforcing() {
/*if (ALLOW_PERMISSIVE_SELINUX) {
return StatusFromCmdline() == SELINUX_ENFORCING;
}
return true;*/
return false;
}
selinux使用安全上下文即SContext来描述资源与进程
user:role:type[:range]
user表示用户:SELinux中仅定义了一个SELinux用户,用u表示
role表示角色:可以理解为在SELinux用户可以有多个不同的role,不同role所具有的权限也不一样
type表示类型:不同的type所具有的权限也不一样,但跟role有本质的不同
range表示安全级别:通常为s0,不用怎么关注
可以通过命令ps -Z -A查询当前所有进程的安全属性:
最右边列表示进程名称,最左边列表示该进程对应的安全属性,进程的SContext的user值为u表示用户;
role值为r表示进程;
type字段代表该进程所属的Domain,对应于一类进程,即相同type的进程具有相同的访问权限
range值为s0;
在系统根目录执行ls -Z命令,能够查看根目录文件的SContext:
资源的SContext的user值为u代表用户;role值为object_r代表文件;range值为s0;跟进程SContext一样,有些资源的type相同,代表他们是同一类
selinux使用te文件来描述规则,根据这些规则来管理权限,同时te文件中根据访问规则即av规则来确定对应的访问权限
allow source target:class permissions;
allow - 为AV规则,表示允许
Source - 规则主体的类型(或属性)。谁在请求访问,一般为进程SContext的type
Target - 对象的类型(或属性)。要求访问的是什么,一般为资源SContext的type
Class - 被访问对象的种类(如文件、套接字)
Permissions - 正在进行的操作(或一组操作)(例如,读、写)
AV规则包括:
allow - 表示允许主体对客体执行允许的操作。
dontaudit - 表示不记录违反规则的决策信息,且违反规则不影响运行。
auditallow - 表示允许操作并记录访问决策信息。
neverallow - 表示不允许主体对客体执行指定的操作。
例如:
allow location qtidataservices_app:binder {call};
允许location这个type,对qtidataservices_app的binder进行call的操作。这一行通常添加到location.te文件中,因为很多模块都有自己的te文件进行管理。
或
allow netd proc:file write
允许域名为netd的所有进程具有对资源文件proc的write权限
如果出现了selinux的权限异常,会打印avc日志,如下,log的关键字为avc:
LocTimerMsgTask: type=1400 audit(0.0:8): avc: denied { call } for scontext=u:r:location:s0 tcontext=u:r:qtidataservices_app:s0:c56,c256,c512,c768 tclass=binder permissive=0
scontext=u:r:location:s0 请求访问者的selinux标签,scontext=主体上下文,即找到scontext字段,后面跟随的为主体安全上下文SContext,代表主体进程
tcontext=u:r:qtidataservices_app:s0 被请求者的selinux标签,tcontext=客体上下文,即找到tcontext字段,后面跟随的为客体安全上下文SContext,代表被访问单个资源或一系列资源的上下文
tclass=binder 被请求的类型是binder,tclass=客体类别,即找到的tclass字段,后面为客体类别
denied { call } 表示请求者对访问者请求被selinux拒绝的操作是call操作tclass=客体类别:找到tclass字段,后面为客体类别
permissive=0 selinux拒绝了这个访问
Selinux策略分成三种:
- Public公共策略:谷歌原生策略中的public部分以及开发人员自行添加策略中的public部分。
- Private私有策略:谷歌原生策略中的private部分以及开发人员自行添加策略中的private部分。
- Vendor供应商通用组件策略:谷歌原生策略中的vendor部分以及开发人员自行添加策略中的vendor部分。
对应策略的目录:
/system/sepolicy:谷歌原生策略,不要在此路径下进行修改
/system/sepolicy/private:谷歌原生system分区private sepolicy
/system/sepolicy/public:谷歌原生system分区public sepolicy
/system/sepolicy/vendor:谷歌原生vendor分区sepolicy
/system/sepolicy/prebuilts:版本兼容sepolicy
例如,从init进程启动的服务需要配置对应的selinux权限:
首先,定义对应的rc文件:
service watchlssd /system/bin/watchlssd
之后,在/system/sepolicy/private下新增watchlssd.te文件:
typeattribute watchlssd coredomain;
init_daemon_domain(watchlssd) //init_daemon_domain宏的功能是:init进程执行一个type为watchlssd_exec的文件,创建一个子进程。
typeattribute语句允许关联前面声明的类型和属性,在类型声明时,如果没有关联属性,就可以使用这个语句进行类型和属性的关联,此处即将属性coredomain与类型watchlssd相关联。coredomain和下面的domain一样,表示一组进程。
在/system/sepolicy/public目录下新增watchlssd.te文件:
type watchlssd, domain; //定义watchlssd,继承于domain,将代表某一组进程的域名。本进程domain是watchlssd。
type watchlssd_exec, exec_type, file_type; //定义watchlssd_exec,继承于exec_type和file_type,将代表某一资源,继承了执行权限
//watchlssd_exec将会设置为/system/bin/watchlssd的type,即/system/bin/watchlssd文件的安全上下文
//(这两种type可能不全,如果编译出错,在这两种type后加上编译报错中提示缺少的type再编译,逗号后有空格且最后分号结尾)。
//进程启动时,将该子进程的domain设置为watchlssd,而不是继承父进程的init。
allow watchlssd surfaceflinger_service:service_manager find; //为watchlssd申请权限
domain是专门用来修饰进程SContext的type,表示一个域(一组进程),自定义的进程叫watchlssd,因此用字符串watchlssd来表示这组进程,在后面的allow语句中都是allow watchlssd xxxx来实现安全策略。
file_type是用来修饰资源SContext的type,这里定义了一个watchlssd_exec,并继承于exec_type/file_type,其中exec_type表示可执行文件,因此只要有某资源安全属性的type字段就表示它能够被执行。在file_contexts中会把watchlssd_exec赋予/system/bin/watchlssd文件。
init_domain_domain(watchlssd)是一个宏,声明当一个domain为init的进程创建一个子进程执行一个type为watchlssd_exec的文件时,将该子进程的domain设置为watchlssd,而不是继承父进程(它的父进程就是init进程)的domain。
type相较与typeattribute,多了一个声明类型的作用。
- type aa, XX; #定义aa类型,并赋予aa给XX域
- typeattribute aa XX, YY; #把aa赋予XX域和YY域
在/system/sepolicy/private/file_contexts文件中赋予/system/bin/watchlssd可执行文件安全上下文,对该文件赋予可被执行的type
/system/bin/watchlssd u:object_r:watchlssd_exec:s0
最后源码编译与烧写
SELinux策略语言–类型强制(编写TE规则)
selinux权限说明及问题解决
Selinux篇3 -TE规则
Android中SeLinux权限 .te文件编写
Android 系统添加SELinux权限
[SeLinux]audit2allow安装与使用
SELinux规则添加进阶
Android SELinux
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。