SeLinux问题解决方法

SeLinux问题解决方法

1、确认SeLinux导致的权限问题
1.1 SeLinux的三种状态
SeLinux有三种状态,分别如下:
1、Enforcing:强制模式,表示SeLinux运作当中,所有违反其规则的操作都会被阻止执行;
2、Permissive:宽容模式, 表示SeLinux运作当中,但不会限制违反其规则的操作,只会给出警告信息;
3、Disable:关闭,SeLinux并没有实际运行。
1.2 如何设置SeLinux模式
adb shell进入到手机shell内,通过getenforce命令查看当前SeLinux的状态,一般都为Enforcing模式,可以通过如下命令设置SeLinux模式为Permissive或Enforce(手机须有root权限)。
设置为Permissive模式:setenforce 0
设置为Enforcing模式:setenforce 1
1.3 如何确认为SeLinux导致的问题
手机连接电脑,adb logcat | grep avc抓取log,手机执行相关操作,如果有avc相关的log出现,说明与SeLinux相关,此时可以通过1.2小节中的方法将SeLinux模式设置为Permissive模式,再重新执行一次操作,如果成功,则可判断为SeLinux导致的权限问题。
2、通过SeLinux log添加相应规则
2.1 标志性SeLinux的log
如下log是通过avc过滤得到的SeLinux的log:
avc: denied { add_name } for name=“22_X_50_Y_20_OK_36666.bmp” scontext=u:r:hal_fingerprint_default:s0 tcontext=u:object_r:oxi_hal_image_file:s0 tclass=dir permissive=0
如下是各个字段代表的意思,按颜色背景一致对应。
avc: denied { 操作权限 } scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=访问类别 permissive=0
知道SeLinux的log中个字段的含义后,我们才知道如果去给这样一条SeLinux限制的log添加对应的SeLinux规则,好让手机可以执行此操作。
2.2 在sepolicy中添加相应权限
MTK的权限文件有如下两个目录
Android N及之前:
路径一:device/mediatek/common/sepolicy
路径二:system/sepolicy/
Android O、P:
路径一:device/mediatek/sepolicy
路径二:system/sepolicy/
一般都在如下的目录中添加相应的权限:
Android N及之前:device/mediatek/common/sepolicy/basic
Android O、P:device/mediatek/sepolicy/basic/non_plat
注:也可视情况而定。
按2.1小节中所述,我们需要找到 源类型.te的te文件,在此文件内加入对应的权限。
添加的格式如下:
allow 源类型 目标类型:访问类别 { 权限操作 };
按此格式,对于2.1小节中的限制,我们需要在hal_fingerprint_default.te文件中加入如下权限:
allow hal_fingerprint_default oxi_hal_image_file:dir add_name;
当SeLinux相关的log很多时,此方法需要你逐条添加,因此在第三章节中我会提供一种懒汉式的方法,一次性解析所有的log并得到对于的权限。
3、audit2allow工具介绍
3.1 安装audit2allow工具
通过如下命令安装audit2allow工具:
sudo apt-get install policycoreutils
sudo apt-get install audit2allow
3.2 通过audit2allow工具解析SeLinux的log
通过如下命令抓取SeLinux的log:
adb logcat | grep avc > SeLinux.log
通过如下命令解析log文件:
sudo audit2allow -i SeLinux.log
在电脑端输出的结果如下:
SeLinux问题解决方法_第1张图片
按照输出结果所示,可以在对应的hal_fingerprint_default.te和tkcore.te文件中添加对应的权限。
注:用此方法需注意,SeLinux为Enforcing时,当碰到一条SeLinux权限不符时就会停止操作,相应其它的SeLinux的log也不会打印,因此,我们可以先将SeLinux状态设为Permissive,在此状态下,SeLinux的警告信息依然会打印,但是不会限制你的操作,这样就可以一次性打印出所有与此操作相关的SeLinux的log,再通过此工具进行解析。
关于 audit2allow的其它用法请自行百度。
4、添加权限后的neverallow冲突
当我们添加权限之后,编译是有可能会碰到neverallow的问题,此时会编译报错,原因是因为新添加的sepolicy项目违反了domain.te 中规定的的总策略原则。如果这时直接修改neverallow规则,可以通过编译,但是可能会导致CTS测试失败,所以这时就要想办法绕过neverallow规则。
以下绕过neverallow规则的方法仅适合用于HCT自己创建的文件,并不适用于Android的源文件,因为此方法需要修改目标的SeLinux类型,如果是我们自己创建的文件,我们很清除的知道有哪些地方会用到它。而Android的源文件,我们不清楚会有哪些进程会此文件进行操作,如果为某一类进程而对此文件进行修改,会造成其它的进程无法对此文件进行操作的后果。
4.1 AndroidP工程模式闪光灯问题
以在AndroidP上工程模式闪光灯测试项问题为例,讲述此方法的一个流程。
闪光灯测试项以对闪光灯节点进行置1和置0来打开和关闭闪光灯。
闪光灯节点路径:sys/devices/virtual/flashlight_core/flashlight/flashlight_contrl
其SeLinux类型为:
-rwxrwxrwx 1 system radio u:object_r:sysfs:s0 4096 2018-11-12 02:56 flashlight_contrl
查看某一文件的SeLinux类型的命令如下:
ls -alZ
按照此前介绍的方法,我们需要在em_svr.te和radio.te文件中分别加入如下权限:
allow em_svr sysfs:file { open read write };
allow radio sysfs:file { open read write };
但是编译时就会发现,sysfs类型的文件是不允许em_svr、radio类型的进程对其进行write的操作的。
解决方法如下:
(1)在file.te中增加一种类型
type sysfs_hct_file, fs_type, sysfs_type;
(2) 在file_context中重新定义闪光灯节点的文件类型
/sys/devices/virtual/flashlight_core/flashlight/flashlight_contrl u:object_r:sysfs_hct_file:s0
(3) 在em_svr.te和radio.te文件分别加入权限
allow em_svr sysfs_hct_file:file { open read write };
allow radio sysfs_hct_file:file { open read write };
按上述流程之后,查看闪光灯节点的文件类型如下:
-rwxrwxrwx 1 system radio u:object_r:sysfs_hct_file:s0 4096 2018-11-13 14:49 flashlight_contrl
其类型已变为我们定义的类型。
5、AndroidP上SeLinux的修改
1、system和vendor下的进程不能通过磁盘文件进行通讯;
2、若未被重新定义文件类型,system下的文件类型为:system_data_file,vendor下的文件类型为:vendor_data_file。
Neverallow rule: https://android-review.googlesource.com/c/platform/system/sepolicy/+/530023/
3、关于以上修改,Google提供的解决方案如下:
3.1) 如果一个文件只是被vendor下的进程使用,可以将此文件设为vendor_data_file,存放于/data/vendor目录下;
3.2) 如果一个文件既被system下的进程也被vendor下的进程使用,并且是Android系统原生的文件,vendor的进程移动到system下,或者通过HIDL的方式解决;
3.3) 如果一个文件既被system下的进程也被vendor下的进程使用,并且是MTK增加的文件,需要将system的进程移动到vendor下,vendor进程移动到system下,或者通过HIDL的方式解决。

你可能感兴趣的:(SeLinux问题解决方法)