说明:本文是篇学习SELinux的笔记,未涵盖的内容待以后用到再补充
目录
[一、SELinux 问题排查](#一、SELinux 问题排查)
[二、SELinux 添加权限](#二、SELinux 添加权限)
[2.1 audit2allow 关于权限问题](#2.1 audit2allow 关于权限问题)
[三、SELinux 语法](#三、SELinux 语法)
[5.1 rule_name](#5.1 rule_name)
[5.2 class](#5.2 class)
[5.3 perm_set](#5.3 perm_set)
一、SELinux 问题排查
首先排查是不是SELinux权限引发的问题,通过 setenforce 命令关闭SELinux
cpp
# getenforce #查看SELinux开关状态。Enforcing:执行,Permissive:许可
Enforcing
# setenforce 0 #关闭SELinux - 设置为 Permissive
# getenforce
Permissive
关闭SELinux (Permissive)后, 功能正常了,说明就是权限问题
二、SELinux 添加权限
查看 avc: denied 相关日志,宗旨缺啥补啥。
注意:通过操作应用程序不断的获取权限日志,一步步配置,权限并不是一下子全部报出来的
cpp
# logcat | grep avc
# dmesg | grep avc
1、安装audit2allow
cpp
$ sudo apt install policycoreutils
2、selinux问题debug
在终端中输入dmesg | grep avc,如果出现下面的情况:

就说明缺少selinux权限,将上面的log信息 dmesg | grep avc > a.txt (log信息导入到a.txt)中。
命令输入 audit2allow -i a.txt,会解析出来如下结果。

将该解析出来的信息放到对应的.te文件当中。
grep -nR "allow vendor_ais_v4l2_proxy" * 搜索需要添加到哪个文件
cpp
$ grep -nR "allow vendor_ais_v4l2_proxy" *
sepolicy_vndr/generic/vendor/kalama/ais_v4l2_proxy.te:12:allow vendor_ais_v4l2_proxy su:unix_dgram_socket sendto;
sepolicy_vndr/generic/vendor/kalama/ais_v4l2_proxy.te:16:allow vendor_ais_v4l2_proxy video_device:chr_file rw_file_perms;
sepolicy_vndr/generic/vendor/kalama/ais_v4l2_proxy.te:17:allow vendor_ais_v4l2_proxy ion_device:chr_file r_file_perms;
... ...
可知,这里的路径是 device/qcom/sepolicy_vndr/generic/vendor/kalama/ais_v4l2_proxy.te
在set_prop后进行添加

添加完毕之后保存,再编译。
2.1 audit2allow 关于权限问题
在服务器里面输入audit2allow -i a.txt,出现下面的情况

解决办法:
在终端中输入sudo vim /usr/bin/audit2allow,找到def main,将如下几行注释掉。

以下就是运行成功的结果。

三、SELinux 语法
1、安全上下文
SELinux中,进程和文件都会被赋予一个安全属性,官方说法为Security Context,也即安全上下文。安全上下文定于语法:user:role:type:sensitivity[:category]
cpp
字段 含义
----------------------------------
user 用户,Android中只定义了一个SELinux用户和角色,其值为"u".
role 角色,Android中主体的角色为"r",客体的角色为"object_r"
type 类型,将主体和客体划分为不同的组,用于在安全策略中授予权限的标识。
sensitivity[:category] 安全等级,包括敏感度和类别,用于军用和教育行业的多级安全策略(MLS)。
2、主体和客体
- 主体(subject):指进程,是活的,是安全行为的发起者,使用 "ps -Z" 命令查看进程的安全上下文。
- 客体(object),也可称对象,所有可读取的对象,是死的,比如文件、目录、属性、套接字等,使用 "ls -Z" 命令查看文件的安全上下文。
3、权限命令
- allow:表示允许主体对客体执行允许的操作
- neverallow:表示不允许主体对客体执行指定的操作。当遇到了 neverallow 冲突时,可改主体或客体来绕过。
- dontaudit : 对那些权限检查失败的操作不做记录
- auditallow: audit含义就是记录某项操作。默认SELinux只记录那些权限检查失败的操作。 auditallow则使得权限检查成功的操作也被记录。
4、常用通配符
- "-"表示去除某项内容
- "*"表示所有内容
- "~"表示取反,除了~之外的
例如:
cpp
neverallow appdomain fs_type:filesystem ~getattr; #表示不允许 appdomain 域的进程对类型为 fs_type 的文件系统除了 getattr 之外的操作。
neverallow {appdomain -init -gsid } gsi_data_file:dir*; #表示不允许 appdomain 域中除了init、gsid外的,对类型为 gsi_data_file 的目录做任何操作。
neverallow {domain -vold} vold_data_file:dir *; #表示除了 vold 外的进程都不允许操作 vold_data_file 类型的目录
5、安全策略语法
SELinux安全策略用于描述、授予主体对客体的一些操作行为,是以.te为后缀的文本文件。定义语法:rule_name source_type target_type:class perm_set;
cpp
字段 含义
---------------------------------------
rule_name allow, dontaudit, auditallow, neverallow 等关键字
source_type 源类型,主体的类型,一个进程或一组进程的标签
target_type 目标类型,一个客体或一组客体的类型标签
class 客体类别,表示要操作的客体的类型,文件,套接字等
perm_set 许可,要执行的操作,读,写等
5.1 rule_name
其中 rule_name 下的 allow 表示允许某个进程执行某个操作, dontaudit 表示对那些权限检查失败的操作不做记录, auditallow 表示即使权限检查成功的操作也被记录,它只是记录,和授予权限无关,要授予权限必须使用 allow, neverallow 表示没有被 allow 的动作就不被允许执行,neverallow 只是显示地指出某个操作不被允许,强行添加 allow 会导致编译出错。
rule_name 字段中最常用的是allow,表示授予权限,当授予多条同类型权限时可用 {} 括起来
例1:allow system_server rootfs:dir{open read}
含义:表示允许 system_server 域中的进程 open 和 read 类型为 rootfs 的目录。
5.2 class
查看客体类别(class)的方法:system/sepolicy/private/security_classes 中定义了Android中所有的客体类别。
cpp
class filesystem
class file
class dir
...
5.3 perm_set
查看某种类别的客体的操作(perm_set)的方法:system/sepolicy/private/access_vectors 中定义了Android中所有的操作类别。
cpp
common file
{
ioctl
read
...
}
...
common ipc
{
create
destroy
...
}
6、安全策略语句支持通配符,常用的有如下几个:
- "-" 表示去除某项内容
- "*" 表示所有内容
- "~" 表示取反,除了~之外的
例2:neverallow appdomain fs_type:filesystem ~getattr;
含义:表示不允许 appdomain 域中的进程对类型为 fs_type 文件系统做除了 getattr 之外的操作。
例3:neverallow {domain -init -gsid} gsi_data_file:dir *;
含义:表示不允许 domain 域中除了 init、gsid 域外,对类型为 gsi_data_file 的目录做任何操作。
7、宏定义
安全策略语句支持宏定义,即定义的一种类似函数的模板以方便编写策略,编译时M4工具会自动将其展开。
例:r_dir_file(ueventd, sysfs_type)
r_dir_file 是个宏,定义在 te_macros 文件中,如下,其中 1, 2 表示传入的参数
cpp
# system/sepolicy/public/te_macros
# r_dir_file(domain, type)
# Allow the specified domain to read directories, files and symbolic links of the specified type.
define(`r_dir_file', `
allow $1 $2:dir r_dir_perms;
allow $1 $2:{ file lnk_file } r_file_perms;
')
# 策略展开后为:
allow ueventd sysfs_type:dir r_dir_perms;
allow ueventd sysfs_type:{ file lnk_file } r_file_perms;
而 r_dir_perms 和 r_file_perms 又属于 perm_set 宏,定义在 global_macros 中,如下:
cpp
# system/sepolicy/public/global_macros
define(`r_dir_perms', `{ open getattr read search ioctl lock watch watch_reads }')
define(`r_file_perms', `{ getattr open read ioctl lock map watch watch_reads }')
# 策略展开后为:
allow ueventd sysfs_type:dir { open getattr read search ioctl lock watch watch_reads };
allow ueventd sysfs_type:{ file lnk_file } { getattr open read ioctl lock map watch watch_reads };
参考链接: