Android的妈咪谷歌为了解决Android系统一直让人诟病的安全问题,在Android 4.4以后强制引入了SELinux安全管理。SELinux虽然可以将安全提升一个层级,但是有时候的实际效果确实杀敌一千,自损八百给开开发造成许多的困难。今天要讲的是Android开启SELinux后不允许部分进程访问data目录而造成的功能谦容性问题,本篇将带领读者一起看看怎么在不关闭SELinux的前提下,破解该限制(这么操作可能会导致GMS的测试通过不了)。
注意:这里的实际操作是在Android 8版本上面进行的。
该章节将会从整体上来描述发生此问题时候的表象及其解决模板方案,在后续章节会以一个具体案例来进行讲解。
Android 8 版本开启SELinux以后后进程无法访问直接访问data导致一些操作无法正常进行。
此时当进程在没有添加SELinux的rule规则下操作data目录,通过logcat -b events可以看到日志里面会有许多的avc denied的日志,那么此时说明你的操作被SELinux拦截处理了。
Google 在android M 版本后, 通过SELinux 的neverallow 语法强制性限制了普通进程访问data 目录的权限. 严禁除init system_server installd system_app 之外的其他进程直接操作/data 目录比如在data 目录下面创建文件,写文件,重命名文件等等.
有很多客户都会在data 目录下创建文件, 保存资讯, 在M 版本上这个操作会被SELinux 直接拦截下来,并且没法直接添加访问system_data_file 的权限, 需要按下面的流程操作:
mkdir /data/xxxx 0770 root system
type xxxx_data_file, file_type, data_file_type;
/data/xxxx(/.*)? u:object_r:xxxx_data_file:s0
allow yyyy xxxx_data_file:dir create dir_perms;
allow yyyy xxxx_data_file:file create_file_perms;
这样你才能绕过Google 的设置. 这个xxxx 目录随你定义。
出于历史原因,项目需要对/data/resource目录下面的目录文件进行访问,在没有开启SELinux检测之前,只需要对目录开启相应的读写访问权限即可,可是开启SELinux之后就不同了。通过SELinux 的neverallow 语法强制性限制了普通进程访问data 目录的权限. 严禁除init system_server installd system_app 之外的其他进程直接操作/data 目录比如在data 目录下面创建文件,写文件,重命名文件等等.在O版本上面有很多客户都会在data 目录下创建文件, 保存资讯, 这个操作会被SELinux 直接拦截下来,并且没法直接添加访问system_data_file 和data_file_type的权限, 需要按下面的流程操作:
1. 在system/sepolicy/public/file.te和system/sepolicy/prebuilts/api/26.0/public/file.te添加添加如下定义
type xxxxroid_share_file, file_type, data_file_type, mlstrustedobject;#其中mlstrustedobject这个很重要后面会重点强调
2. 在system/sepolicy/prebuilts/api/26.0/private/file_contexts和system/sepolicy/private/file_contexts添加如下规则
/data/resource(/.*)? u:object_r:xxxxroid_share_file:s0
3. 在system/sepolicy/prebuilts/api/26.0/private/app_neverallows.te和system/seplicy/private/app_neverallows.te下面做如下修改
#neverallow all_untrusted_apps file_type:file link;
#不允许all_untrusted_apps对file_type进行访问,除开xxxdroid_share_file
neverallow {all_untrusted_apps} {file_type -xxxxroid_share_file}:file link;
#同上
neverallow { all_untrusted_apps -mediaprovider } {
fs_type
-fuse # sdcard
-sdcardfs # sdcard
-vfat
file_type
-app_data_file # The apps sandbox itself
-media_rw_data_file # Internal storage. Known that apps can
# leave artfacts here after uninstall.
-user_profile_data_file # Access to profile files
userdebug_or_eng(`
-method_trace_data_file # only on ro.debuggable=1
-coredump_file # userdebug/eng only
')
-xxxxroid_share_file
}:dir_file_class_set { create unlink };
4. 然后在device/sprd/sharkle/common/sepolicy/xxxdroid_share_file.te增加该文件,然后增加相关的权限,这里可以根据实际开发平台进行相关的处理。
allow system_app xxxxroid_share_file:file {create write setattr relabelfrom relabelto append unlink link rename open getattr read lock };
allow untrusted_app xxxxroid_share_file:dir { search write create add_name remove_name setattr relabelfrom relabelto append unlink link rename getattr};
allow untrusted_app xxxxroid_share_file:file {create write setattr relabelfrom relabelto append unlink link rename open getattr read lock };
allow untrusted_app_25 xxxxroid_share_file:dir {search write create add_name remove_name setattr relabelfrom relabelto append unlink link rename getattr};
allow untrusted_app_25 xxxxroid_share_file:file {create write setattr relabelfrom relabelto append unlink link rename open getattr read lock };
allow platform_app xxxxroid_share_file:dir { search write create add_name remove_name setattr relabelfrom relabelto append unlink link rename getattr};
allow platform_app xxxxroid_share_file:file { create write setattr relabelfrom relabelto append rename open getattr read lock };
allow xxxservice xxxxroid_share_file:dir { search write create add_name remove_name setattr relabelfrom relabelto append unlink link rename getattr};
allow xxxservice xxxxroid_share_file:file { create write setattr relabelfrom relabelto append rename open getattr read lock };
5. 重点来了,后面发现怎么修改都untrusted_app_25都不能对该文件进行修改,后面发现了是由于mls规则导致,错误类似如下:
type=1400 avc: denied { connectto } for pid=6884 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socket permissive=0
在system/sepolicy/private/mls存在如下的规则,所以就需要对xxxdroid_share_file加上 mlstrustedobject才可以:
mlsconstrain dir { write setattr rename add_name remove_name reparent rmdir }
(t2 == app_data_file or l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
mlsconstrain { file lnk_file sock_file chr_file blk_file } { write setattr append unlink link rename }
(t2 == app_data_file or l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
关于MLC规则具体可以参考如下的博客文章:SELinux中的MLC规则约束。
最后重新编译systemimage和bootimage到终端,验证此时你就可以畅通无阻的访问data目录了,爽不爽。
修行至此,恭喜读者你已经开启了Android SELinux开发入门指南之正确姿势解决访问data目录权限问题征程,此时的你行走于Android data目录应该木有任何问题了,畅通无阻,来去无踪影了。此时的你可以一剑走天下了,为师的必杀器已经倾囊相授了。各位江湖见。
各位读者看官朋友们,Android SELinux开发入门指南之正确姿势解决访问data目录权限问题已经全部完毕,希望能吸引你,激活发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。