在做Android 系统OTA升级App时,需要在 ‘/cache
‘ 目录创建目录和脚本文件,App已经获取到system权限(安装到 /system/priv-app
目录),但是还是在/cache
目录下没有权限。
通过 adb
命令,用system身份执行命令都没有任何问题。
升级命令脚本是:
1 | "mkdir /cache/recovery" |
但建议调用Android的接口 RecoverySystem.installPackage(this,new File("/data/update.zip"));
执行(也是差不多这些命令)
通过 adb logcat
抓到关键日志:
1 | [ 436.020771] type=1400 audit(1590734406.224:28): avc: denied { write } for pid=7767 comm="com.github.test" name="recovery" dev="mmcblk0p23" ino=8197 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_file:s0 tclass=dir permissive=0 |
这就是SELinux拦截的日志。
进入 adb shell
看一下SELinux对cache目录拦截的属性
1 | root@la0920:/ # ls -Z | grep cache |
要确定是不是SELinux导致这个问题,简单测试一下,临时关闭SELinux
1 | adb shell setenforce 0 |
如果确定问题了,那就要根据报错日志,匹配一条记录
[ 436.020771] type=1400 audit(1590734406.224:28): avc: denied { write
} for pid=7767 comm=”com.github.test” name=”recovery” dev=”mmcblk0p23” ino=8197 scontext=u:r:system_app
:s0 tcontext=u:object_r:cache_file
:s0 tclass=dir
permissive=0
缺少什么权限: { execute}权限,
谁缺少权限: scontext = u:r:platform_app:s0
对哪个文件缺少权限:tcontext = u:object_r:app_data_file
什么类型的文件: tclass= file
avc: denied { write }
for pid=7767 comm=”com.github.test” name=”recovery” dev=”mmcblk0p23”
ino=8197
scontext=u:r:system_app:s0
tcontext=u:object_r:cache_file:s0
tclass=dir
根据
1 | allow scontext tcontext:tclass denied; |
得出一条记录
1 | allow system_app cache_file:dir write; |
在Android Framwork 源码路径: external/sepolicy/*.te
找了相关的scontext文件,如 system_app.te,在 external/sepolicy/system_app.te
这个文件加入这条记录。
重新编译。