详解Android Selinux 权限及问题
由于现做的是MTK平台,源码路径基于MTK, 不过高通大同小异
说明
Android 5.0以后完全引入了 SEAndroid/SELinux 安全机制,这样即使拥有 root 权限或 chmod 777 ,仍然无法再JNI以上访问内核节点。
其实在 Android 4.4 就有限制的启用此安全机制了。后面内容都按照 5.0 以后介绍,4.4 会有些许差异。
SELinux Mode
SELinux 分为两种模式,Android 5.0 后所有进程都使用 enforcing mode。
enforcing mode: 限制访问
permissive mode: 只审查权限,不限制
SELinux Policy文件路径
# Google 原生目录
external/sepolicy
# 厂家目录,高通将 mediatek 换为 qcom
alpsdevicemediatekcommonsepolicy
alpsdevicemediatek<platform sepolicy
编译时将以合并的方式将厂家policy追加到Google原生。
Log
没有权限时可以在内核找到如下 log :
# avc: denied { 操作权限 } for pid=7201 comm=“进程名” scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=访问类型 permissive=0
avc: denied {getattr read} for pid=7201 comm="xxx.xxx" scontext=u:r:system_app:s0 tcontext=u:r:shell_data_file:s0 tclass=dir permissive=0
```
## 权限修改
主要有三种方式,前两种只能用来测试,第三种是推荐的正式处理方式。
### adb在线修改seLinux
```bash
# Enforcing - 表示已打开 ,Permissive - 表示已关闭
getenforce; //获取当前seLinux状态
setenforce 1; //打开seLinux
setenforce 0; //关闭seLinux
kernel中关闭
# alpskernel-3.18archarm64configsxxx_defconfig
CONFIG_SECURITY_SELINUX=y // 屏蔽此配置项
SELinux Sepolicy中添加权限
修改相应源类型.te文件(基本以源进程名命名),添加如下一行语句:
# 格式
allow 源类型 目标类型:访问类型 {操作权限}; // 注意分号
# 实例,具体写法参考源码
allow system_app shell_data_file:dir{getattr read write};
allow mediaserver tfa9897_device:chr_file { open read write };
allow system_server tfa9897_device:chr_file rw_file_perms;
chr_file - 字符设备 file - 普通文件 dir - 目录
通常很少修改Google default 的policy, 推荐更新mediatek 下面的相关的policy.
新建节点
如果是自己新建的节点,需要在 sepolicy 路径下的 file_contexts 文件中做如下添加:
# 参考已有的格式
/dev/goodix_fp u:object_r:goodixfp_device:s0
Android 5.0 修改的文件为device.te 和 file_contexts.be,而且device/mediatek/common/BoardConfig.mk 中的 BROAD_SEPOLICY_UNION 增加对应的xxxx.te。
编译
# 模块编译
mmm external/sepolicy
make -j24 ramdisk-nodeps & make -j24 bootimage-nodeps
# 整编
make -j24
ps添加权限后的neverallowed冲突
编译报错:
libsepol.check_assertion_helper: neverallow on line xxx ofexternal/sepolicy/domain.te ……
原因:
新添加的sepolicy项目违反了domain.te 中规定的的总策略原则。所以该条权限策略不能添加,如果强行添加的话有CTS测试失败的风险。
解决方法:
1.从运行log中找到要访问的目标名称,一般是name字段后的名称 avc: denied { read write } for pid=303 comm=”mediaserver” name=”tfa9890″dev=”tmpfs” ino=3880 scontext=u:r:mediaserver:s0tcontext=u:object_r:device:s0tclass=chr_file permissive=0
2.找到相应的*_contexts文件。
一般有file_contexts, genfs_contexts, property_contexts, service_contexts 等文件
在contexts文件中指定要访问的目标为一个“源类型 ”有权限访问的“目标类型”
如:在file_contexts中添加: /dev/tfa9890 u:object_r:audio_device:s0
举例
添加权限:
在mediaserver.te中添加allow mediaserver device:chr_file { read write open};
编译报错: libsepol.check_assertion_helper: neverallow on line 258 ofexternal/sepolicy/domain.te (or line 5252 of policy.conf) violated byallow mediaserver device:chr_file { read write open};
违反了domain.te 258的: neverallow {domain –unconfineddomain –ueventd } device:chr_file { open read write}
运行Log: avc: denied { read write } for pid=303 comm=”mediaserver”name=”tfa9890″ dev=”tmpfs” ino=3880 scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0tclass=chr_file permissive=0
修改步骤:
1.目标名称是: tfa9890, 其在系统中的路径是: /dev/tfa9890, 是audio相关的设备文件 2.源类型是mediaserver, 在mediaserver.te 文件中发现其具有 audio_device 目标类型的权限 3.所以在file_contexts 中添加 “/dev/tfa9890 u:object_r:audio_device:s0” 可以解决问题
以上就是本文的全部内容,希望对大家的学习有所帮助。
- 补丁管理:不要以持续运行时间为自豪
- 微信小程序再次深夜放大招!竟然可以玩起直播来了?
- 上海设专项资金支持人工智能创新发展
- 监管下发145号文摸底互联网平台与交易所合作
- 条码支付确立规范引导金融创新趋利避害
- 百度Apollo自动驾驶组“国家队”,全线产品将在CES首度亮相
- Sass 基础(三)
- 2018年——霍金怎么样谈未来人工智能,地球还有多少时间
- Linux探秘之用户态与内核态
- 微信小游戏重磅上线,H5游戏和页游迎来新天地?
- 名为“闪电比特币”Lightning Bitcoin,LBTC的新型比特币硬叉被释放
- IDHub亮相区块链行业巅峰盛宴 分享网络生活的“进化论”
- 总结:如何加速你的 WordPress 站点?
- 百年老牌的创新之路:看可口可乐如何用AI、大数据颠覆传统营销
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Laravel-添加后台模板AdminLte的实现方法
- PHP7 安装event扩展的实现方法
- 在laravel框架中使用model层的方法
- 漂亮的thinkphp 跳转页封装示例
- thinkphp5框架前后端分离项目实现分页功能的方法分析
- laravel 根据不同组织加载不同视图的实现
- 详解将数据从Laravel传送到vue的四种方式
- Laravel实现ApiToken认证请求
- laravel 实现划分admin和home 模块分组
- laravel在中间件内生成参数并且传递到控制器中的2种姿势
- 在laravel框架中实现封装公共方法全局调用
- laravel通过a标签从视图向控制器实现传值
- 在Laravel 的 Blade 模版中实现定义变量
- 解决Laravel5.5下的toArray问题
- Laravel基础_关于view共享数据的示例讲解