Selinux-About简介
SELINUX是可以理解为一种android上面的安全机制,是有美国国家安全局和一些公司设计的一个针对linux的安全加强系统
我们可以通过配置SELINUX的相关policy,来定制自己的手机的一些权限,比如,我们可以完全让root用户没有任何的权限和user一样
Android-Selinux裁剪
在android中,只定义了一个user即为u. 另外,如果是进程的话,都会统一定义为r,如果是文件的话,会被定义为object_r.
第三个是这个进程type,在andorid里面,定义了100多个type.按照目前我的理解,这个是进程所属的>类型。第四个是s0,这个是一个安全的等级。
Android-Selinux-文件结构
首先要了解sepolicy的结构:
|
|
然后是一些特殊的配置文件:
- external/sepolicy/attributes -> 所有定义的attributes都在这个文件
- external/sepolicy/access_vectors -> 对应了每一个class可以被允许执行的命令
- external/sepolicy/roles -> Android中只定义了一个role,名字就是r,将r和attribute domain关联起来
- external/sepolicy/users -> 其实是将user与roles进行了关联,设置了user的安全级别,s0为最低级是默认的级别,mls_systemHigh是最高的级别
- external/sepolicy/security_classes -> 指的是上文命令中的class,个人认为这个class的内容是指在android运行过程中,程序或者系统可能用到的操作的模块
- external/sepolicy/te_macros -> 系统定义的宏全在te_macros文件
- external/sepolicy/*.te -> 一些配置的文件,包含了各种运行的规则
在te文件中,我们一般遇到的语法是这样的:
rule_name source_type target_type:class perm_set
解读为: 为source_type设置一个rule_name的规则,规则是对target_type的class 进行 perm_set的操作。
type的命令如下:
class命令的格式为:
在te文件中常见的四种命名的规则:
- allow:赋予某项权限。
- allowaudit:audit含义就是记录某项操作。默认情况下是SELinux只记录那些权限检查失败的操作。
allowaudit则使得权限检查成功的操作也被记录。注意,allowaudit只是允许记录,它和赋予权限没关系。赋予权限必须且只能使
- dontaudit:对那些权限检查失败的操作不做记录。
- neverallow:前面讲过,用来检查安全策略文件中是否有违反该项规则的allow语句。
语法举例
1type init, domain;
将init关联到domain,即将domain设置为init类型的属性
|
|
允许init类型对unlabeled类型的filesystem进行mount的操作
|
|
允许init类型对fotad类型的unix_stream_socket 进行bind和create的操作
|
|
首先appdomain是定义在te_macros里面的一个宏,很多的app规则会使用类似app_domain(shell)的命令将其添加进去
这两句话的意思是:
- 允许app去对anr_data_file类型的目录进行查找的操作
- 允许app对anr_data_file类型的file进行打开和添加操作 其实就是规定了出现anr时候,app往/data/anr/里面写入的权限限制
|
|
绝对不允许app(除了有unconfineddomain属性的app)对kmem_device类型的字符设备进行读写的操作
|
|
绝对不允许除了unconfineddomain以外的app对self类型的capability2进行任何的操作
|
|
声明一个httpd_user_content_t的类型,具有file_type和httpdcontent的属性
|
|
声明一个httpd_user_content_t的类型
定义httpd_user_content_t具有file_type, httpdcontent的属性
|
|
所有可以设置类型的地方其实都可以设置为属性。
比如这个例子,我们允许所有具有app属性的内容可以去对self属性的rawip_socket进行create的操作
|
|
允许user_t和domain属性的类对bin_t, file_type, sbin_t类型的file进行可执行的操作
|
|
这两条语句的表述其实是一致的,其实self指的是目标的类型和发起人的类型是一致的
所以不能声明一个类型或者属性叫做self
|
|
允许user_t对bin_t类型的file进行除了write setattr ioctl相关的操作
|
|
当一个类型为system的类别去进行wifi_data_file类型的sock_file访问时,类型默认切换到system_wpa_socket
如果下面这条语句想要执行成功
type_transition init_t apache_exec_t:process apache_t;
至少首先声明下面的三条规则:
type_transition和type_change的语法规则是一样的, type_change规则的影响不会在内核中生效,而是依赖于用户空间应用程序,如login或sshd
方法1: adb在线修改seLinux
Enforcing
(表示已打开),Permissive
(表示已关闭)
getenforce; //获取当前seLinux状态
setenforce 1; //打开seLinux
setenforce 0; //关闭seLinux
方法2: 从kernel中彻底关闭
修改LINUX/android/kernel/arch/arm64/configs/xxx_defconfig
文件(xxx一般为手机产品名), 去掉CONFIG_SECURITY_SELINUX=y
的配置项
方法3: sepolicy中添加权限
修改依据,通过指令
cat /proc/kmsg | grep denied
,或者kernel的Log中定位到标志性log。修改步骤
找相应的源类型.te文件,此文件可能的存放路径 (其中源类型见下方的标志性log格式) :
LINUX/android/external/sepolicy LINUX/android/device/qcom/sepolicy/common
标志性log 格式
avc: denied { 操作权限 } for pid=7201 comm=“进程名” scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=访问类型 permissive=0
在相应源类型.te文件,添加如下格式的一行语句:(结尾别忘了分号)
格式:allow 源类型 目标类型:访问类型 {操作权限};
实例
Kernel Log
avc: denied {getattr read} for pid=7201 comm="xxx.xxx" scontext=u:r:system_app:s0 tcontext=u:r:shell_data_file:s0 tclass=dir permissive=0
修改方案
在system_app.te文件中,添加下面语句: allow system_app shell_data_file:dir{getattr read};