详解Android Selinux 权限及问题
由于现做的是MTK平台,源码路径基于MTK,不过高通大同小异
说明
Android5.0以后完全引入了SEAndroid/SELinux安全机制,这样即使拥有root权限或chmod777,仍然无法再JNI以上访问内核节点。
其实在Android4.4就有限制的启用此安全机制了。后面内容都按照5.0以后介绍,4.4会有些许差异。
SELinuxMode
SELinux分为两种模式,Android5.0后所有进程都使用enforcingmode。
enforcingmode:限制访问 permissivemode:只审查权限,不限制
SELinuxPolicy文件路径
#Google原生目录 external/sepolicy #厂家目录,高通将mediatek换为qcom alps\device\mediatek\common\sepolicy alps\device\mediatek\\sepolicy
编译时将以合并的方式将厂家policy追加到Google原生。
Log
没有权限时可以在内核找到如下log:
#avc:denied{操作权限}forpid=7201comm=“进程名”scontext=u:r:源类型:s0tcontext=u:r:目标类型:s0tclass=访问类型permissive=0 avc:denied{getattrread}forpid=7201comm="xxx.xxx"scontext=u:r:system_app:s0tcontext=u:r:shell_data_file:s0tclass=dirpermissive=0 ``` ##权限修改 主要有三种方式,前两种只能用来测试,第三种是推荐的正式处理方式。 ###adb在线修改seLinux ```bash #Enforcing-表示已打开,Permissive-表示已关闭 getenforce;//获取当前seLinux状态 setenforce1;//打开seLinux setenforce0;//关闭seLinux
kernel中关闭
#alps\kernel-3.18\arch\arm64\configs\xxx_defconfig CONFIG_SECURITY_SELINUX=y//屏蔽此配置项
SELinuxSepolicy中添加权限
修改相应源类型.te文件(基本以源进程名命名),添加如下一行语句:
#格式 allow源类型目标类型:访问类型{操作权限};//注意分号 #实例,具体写法参考源码 allowsystem_appshell_data_file:dir{getattrreadwrite}; allowmediaservertfa9897_device:chr_file{openreadwrite}; allowsystem_servertfa9897_device:chr_filerw_file_perms; chr_file-字符设备file-普通文件dir-目录
通常很少修改Googledefault的policy,推荐更新mediatek下面的相关的policy.
新建节点
如果是自己新建的节点,需要在sepolicy路径下的file_contexts文件中做如下添加:
#参考已有的格式 /dev/goodix_fpu:object_r:goodixfp_device:s0
Android5.0修改的文件为device.te和file_contexts.be,而且device/mediatek/common/BoardConfig.mk中的BROAD_SEPOLICY_UNION增加对应的xxxx.te。
编译
#模块编译 mmmexternal/sepolicy make-j24ramdisk-nodeps&make-j24bootimage-nodeps #整编 make-j24
ps添加权限后的neverallowed冲突
编译报错:
libsepol.check_assertion_helper:neverallowonlinexxxofexternal/sepolicy/domain.te……
原因:
新添加的sepolicy项目违反了domain.te中规定的的总策略原则。所以该条权限策略不能添加,如果强行添加的话有CTS测试失败的风险。
解决方法:
1.从运行log中找到要访问的目标名称,一般是name字段后的名称
avc:denied{readwrite}forpid=303comm="mediaserver"name="tfa9890"dev="tmpfs"ino=3880scontext=u:r:mediaserver:s0tcontext=u:object_r:device:s0tclass=chr_filepermissive=0
2.找到相应的*_contexts文件。
一般有file_contexts,genfs_contexts, property_contexts, service_contexts等文件
在contexts文件中指定要访问的目标为一个“源类型”有权限访问的“目标类型”
如:在file_contexts中添加:/dev/tfa9890 u:object_r:audio_device:s0
举例
添加权限:
在mediaserver.te中添加allowmediaserverdevice:chr_file{readwriteopen};
编译报错:
libsepol.check_assertion_helper:neverallowonline258ofexternal/sepolicy/domain.te(orline5252ofpolicy.conf)violatedbyallowmediaserverdevice:chr_file{readwriteopen};
违反了domain.te258的:
neverallow{domain–unconfineddomain–ueventd}device:chr_file{openreadwrite}
运行Log:
avc:denied{readwrite}forpid=303comm="mediaserver"name="tfa9890"dev="tmpfs"ino=3880scontext=u:r:mediaserver:s0tcontext=u:object_r:device:s0tclass=chr_filepermissive=0
修改步骤:
1.目标名称是:tfa9890,其在系统中的路径是:/dev/tfa9890, 是audio相关的设备文件
2.源类型是mediaserver,在mediaserver.te文件中发现其具有audio_device目标类型的权限
3.所以在file_contexts中添加“/dev/tfa9890 u:object_r:audio_device:s0”可以解决问题
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。