当前位置:   article > 正文

安卓SELinux策略_android selinux

android selinux


前言

SELinux是一种加强文件安全的一种策略,用于访问系统资源时进行权限的检查,检查通过才能获得资源访问权限。

一、selinux的工作模式

名称作用
permissive宽容模式:权限拒绝事件会被记录下来,但不会被强制执行。
enforcing强制模式:权限拒绝事件会被记录下来并强制执行。

在强制模式下,非法操作会被阻止,并且尝试进行的所有违规行为都会被内核记录到 dmesg 和 logcat。

可以通过adb命令来来获取当前工作模式

adb shell getenforce
  • 1

也可以通过adb命令来设置当前模式

adb root
adb shell setenforce 01
  • 1
  • 2

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

二、Selinux的安全上下文

selinux使用安全上下文即SContext来描述资源与进程

user:role:type[:range]
  • 1

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的规则

selinux使用te文件来描述规则,根据这些规则来管理权限,同时te文件中根据访问规则即av规则来确定对应的访问权限

allow source target:class permissions;
  • 1

allow - 为AV规则,表示允许
Source - 规则主体的类型(或属性)。谁在请求访问,一般为进程SContext的type
Target - 对象的类型(或属性)。要求访问的是什么,一般为资源SContext的type
Class - 被访问对象的种类(如文件、套接字)
Permissions - 正在进行的操作(或一组操作)(例如,读、写)

AV规则包括:

allow - 表示允许主体对客体执行允许的操作。
dontaudit - 表示不记录违反规则的决策信息,且违反规则不影响运行。
auditallow - 表示允许操作并记录访问决策信息。
neverallow - 表示不允许主体对客体执行指定的操作。

例如:

allow location qtidataservices_app:binder {call};
  • 1

允许location这个type,对qtidataservices_app的binder进行call的操作。这一行通常添加到location.te文件中,因为很多模块都有自己的te文件进行管理。

allow netd proc:file write
  • 1

允许域名为netd的所有进程具有对资源文件proc的write权限

四、AVC日志

如果出现了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
  • 1

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策略

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
  • 1

之后,在/system/sepolicy/private下新增watchlssd.te文件:

typeattribute watchlssd coredomain;
init_daemon_domain(watchlssd)        //init_daemon_domain宏的功能是:init进程执行一个type为watchlssd_exec的文件,创建一个子进程。
  • 1
  • 2

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申请权限
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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
  • 1

最后源码编译与烧写


六、参考链接

SELinux策略语言–类型强制(编写TE规则)
selinux权限说明及问题解决
Selinux篇3 -TE规则
Android中SeLinux权限 .te文件编写
Android 系统添加SELinux权限
[SeLinux]audit2allow安装与使用
SELinux规则添加进阶
Android SELinux

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/961972
推荐阅读
相关标签
  

闽ICP备14008679号