Android/SELinux 添加 AVC 权限

背景

在Android应用层中编写c/c++应用时,发现接口调用出现问题,logcat才知道是因为:权限不够。

type=1400 audit(0.0:4): avc: denied { create } for scontext=u:r:bootanim:s0 tcontext=u:r:bootanim:s0 tclass=netlink_socket permissive=0

参考:

介绍

安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是 Linux 的一个安全子系统。SELinux 主要作用是最大限度地减小系统中服务进程可访问的资源(最小权限原则)。对资源的访问控制分为两类: DAC和MAC

SELinux工作模式

SELinux 有三种工作模式,分别为:

  • enforcing: 强制模式, 执行SELinux规则, 违反的行为会被阻止
  • permissive: 宽容模式, 执行SELinux规则, 违反的行不会被阻止
  • disabled: 关闭SELinux

avc denied

在Android系统开发中, 可能会遇到SELinux的权限不足而引起的各种问题;可以尝试将SELinux工作模式临时改为宽容模式看问题是否解决, 来判定是否是SELinux引起的问题

标志性 log: avc: denied { 操作权限 } for pid=7201 comm=“进程名” scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=访问类型 permissive=0

  • 源类型:授予访问的类型,通常是进程的域类型
  • 目标类型:客体的类型,它被授权可以访问的类型
  • 访问类型
  • 操作权限:表示主体对客体访问时允许的操作类型(也叫做访问向量)。

举例

打开三方apk出问题,其中错误log如下:

03-28 10:18:07.990 11883 11883 W re-initialized>: type=1400 audit(0.0:2918):
avc: denied { read } for name="u:object_r:mtk_amslog_prop:s0"
dev="tmpfs" ino=7544 scontext=u:r:system_app:s0
tcontext=u:object_r:mtk_amslog_prop:s0
tclass=file permissive=0

解释:

  • read:表示没有 read 权限
  • system_app:system_app 中缺少权限
  • mtk_amslog_prop:mtk_amslog_prop 文件系统缺少权限
  • file:file 类型的文件
  • 分析:adb shell setenforce 0。设置SELinux 成为permissive模式。若apk可正常使用,则进行规避此权限问题

修改selinux规则

type=1400 audit(0.0:4): avc: denied { create } for
scontext=u:r:bootanim:s0
tcontext=u:r:bootanim:s0
tclass=netlink_socket
permissive=0 type=1400 audit(0.0:41): avc: denied { read } for
name="u:object_r:media_prop:s0"
dev="tmpfs" ino=11511
scontext=u:r:mediacodec:s0
tcontext=u:object_r:media_prop:s0
tclass=file
permissive=0
节点 寻找点 结果
缺少的权限 denied { 权限 } create
谁(哪个进程)缺少权限 scontext=u:r:进程:s0 bootanim
对哪个节点缺少权限 tcontext=u:r:节点:s0 bootanimself
缺少要访问的对象 tclass=被访问对象 netlink_socket

技巧:

  • 如果tcontext中的节点与scontext中的进程名相同,则可以写成self
  • 因为有时候avc denied 的log不是一次性显示所有问题,要等解决一个权限问题后,才会显示另外一个权限问题,比如显示缺失某个目录的read权限。所以建议是先参考其他可能出现访问权限的问题的有关接口关键字,进行多次添加。
  • 要加入的权限很多时,可以用中括号,比如:allow untrusted_app vfat:dir { search write }

由于,scontext对应的是我们要修改的文件(这里是bootanim),根据type=1400 audit(0.0:4): avc: denied { create } for scontext=u:r:bootanim:s0 tcontext=u:r:bootanim:s0 tclass=netlink_socket permissive=0的提示;因此,需要在bootanim.te最后面中添加所对应的权限是:

# file : bootanim.te
allow bootanim self:netlink_socket {create};

再看一个例子:

# type=1400 audit(0.0:41): avc: denied { read } for
# name="u:object_r:media_prop:s0"
# dev="tmpfs" ino=11511
# scontext=u:r:mediacodec:s0
# tcontext=u:object_r:media_prop:s0
# tclass=file permissive=0 # file: mediacodec.te
allow mediacodec media_prop:file {read}

修改系统selinux模式

临时修改

adb shell setenforce 0 #设置SELinux 成为permissive模式
adb shell setenforce 1 #设置SELinux 成为enforcing模式
adb shell getenforce #获取SELinux状态(permissive,enforcing,disabled)

永久修改

安卓7

路径:system/core/init/init.cpp

static selinux_enforcing_status selinux_status_from_cmdline() {
selinux_enforcing_status status = SELINUX_ENFORCING; // 强制模式, 执行SELinux规则, 违反的行为会被阻止
//selinux_enforcing_status status = SELINUX_PERMISSIVE;// 宽容模式, 执行SELinux规则, 违反的行不会被阻止
import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) {
if (key == "androidboot.selinux" && value == "permissive") {
status = SELINUX_PERMISSIVE;
}
}); return status;
}

安卓9/10

路径:system/core/init/selinux.cpp

EnforcingStatus StatusFromCmdline() {
// EnforcingStatus status = SELINUX_ENFORCING;// 强制模式, 执行SELinux规则, 违反的行为会被阻止
EnforcingStatus status = SELINUX_PERMISSIVE; // 宽容模式, 执行SELinux规则, 违反的行不会被阻止
import_kernel_cmdline(false,
[&](const std::string& key, const std::string& value, bool in_qemu) {
if (key == "androidboot.selinux" && value == "permissive") {
status = SELINUX_PERMISSIVE;
}
}); return status;
}

附录A:在permissive模式下,有些app仍然无法访问具体节点

敏感权限的特征:log中带有c512,c768字样

试着在untrusted_app.te 中添加了allow untrusted_app audio_device:chr_file { open write read };还是报如下权限错误:

[ 141.935275] type=1400 audit(1546939304.786:43): avc: denied { write } for
pid=1836 comm="Thread-4"
name="pcmC0D1c"
dev="tmpfs"
ino=11947
scontext=u:r:untrusted_app:s0:c512,c768
tcontext=u:object_r:audio_device:s0
tclass=chr_file
permissive=1

先确认需要访问的节点是否为audio_device,这个节点属于敏感权限,可以的话请修改访问的目录和文件,缩小audio_device的范围

方法为:

1、确定访问的节点位置,通过源码或者log确定到底访问的哪一个具体的节点, 例如 /dev/pcmc00xx

2、在相应的te文件中新声明一个节点名称, 如 file.te: type test_audio_device, dev_type;

3、在file_context中将具体节点绑定新的节点名称, 如: file_context: /dev/pcmc00xx test_audio_device

4、增加或修改需要的权限: allow untrusted_app test_audio_device:chr_file { open write read };

如果不过GMS认证,敏感权限(c512,c768)可以直接把对象关联mlstrustedobject, 但不推荐这样修改,会造成严重的安全问题。 例如: typeattribute audio_device mlstrustedobject;

附录B:DAC和MAC有什么区别?

DAC

DAC(Discretionary Access Control,自主访问控制)

  • DAC是传统的Linux的访问控制方式,DAC可以对文件、文件夹、共享资源等进行访问控制。
  • 在DAC这种模型中,文件客体的所有者(或者管理员)负责管理访问控制。
  • DAC使用了ACL(Access Control List,访问控制列表)来给非管理者用户提供不同的权限,而root用户对文件系统有完全自由的控制权。

MAC

MAC(Mandatory Access Control,强制访问控制)

  • SELinux在内核中使用MAC检查操作是否允许。
  • 在MAC这种模型中,系统管理员管理负责访问控制,用户不能直接改变强制访问控制属性。
  • MAC可以定义所有的进程(称为主体)对系统的其他部分(文件、设备、socket、端口和其它进程等,称为客体)进行操作的权限或许可。

DAC和MAC的其它区别

① DAC的主体是真实有效的用户和组ID,MAC的主体是安全上下文,两者的UID是各自独立的。

② DAC的访问控制模式是rwxrwxrwx,MAC的访问控制模式是user:role:type。

附录C:高通平台修改selinux权限路径

Android 7 :device/qcom/sepolicy/common/

Android 9:其中的某一个

  • device/qcom/sepolicy/vendor/common/
  • device/sprd/sharkl3/common/sepolicy/

Android 10:其中的某一个

  • device/qcom/sepolicy/vendor/common/
  • device/qcom/sepolicy/legacy/vendor/common/
  • device/sprd/sharkl3/common/sepolicy/

Android/SELinux 添加 AVC 权限的更多相关文章

  1. Android 系统添加SELinux权限

    本文为博主原创文章,转载请注明出处:https://i.cnblogs.com/EditPosts.aspx?postid=11185476 CPU:RK3288 系统:Android 5.1 SEL ...

  2. Android动态添加Device Admin权限

    /********************************************************************** * Android动态添加Device Admin权限 ...

  3. Android 添加网络权限

    [Android 添加网络权限] <uses-permission Android:name="android.permission.INTERNET"></us ...

  4. Android : SELinux 简析&修改

    一 SELinux背景知识 SELinux出现之前,Linux上的安全模型叫DAC,全称是Discretionary Access Control,翻译为自主访问控制.DAC的核心思想很简单,就是: ...

  5. [Android][Framework] 添加系统服务

    新博客地址 http://wossoneri.github.io/2018/09/15/[Android][Framework]create-system-service/ 做系统开发,有时候需要自己 ...

  6. Android M(6.0) 权限相关

    原文链接:http://jijiaxin89.com/2015/08/30/Android-s-Runtime-Permission/ Android M 新的运行时权限开发者需要知道的一切   an ...

  7. Android 6.0 - 动态权限管理的解决方案

    Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...

  8. Android之动态申请权限(API23以上需求)

    API 23之前的版本都是自动获取权限,而从 Android 6.0 开始添加了权限申请的需求,更加安全. 这里以单个存储权限为例: · 在 Manifest 中添加访问权限:(只需设置可写,因为可写 ...

  9. 【转】Android M(6.0) 权限爬坑之旅

    原文网址:https://yanlu.me/android-m6-0-permission-chasm/ 有一篇全面介绍Android M 运行时权限文章写的非常全面:Android M 新的运行时权 ...

  10. Android开发之深入理解Android 7.0系统权限更改相关文档

    http://www.cnblogs.com/dazhao/p/6547811.html 摘要: Android 6.0之后的版本增加了运行时权限,应用程序在执行每个需要系统权限的功能时,需要添加权限 ...

随机推荐

  1. SpringBoot序列化、反序列化空字符串为null的三种方式

    一.需求:接收前端传入的""空字符串参数,有时候我们需要把它转为null SpringBoot项目 方式:①Jackson(推荐).②切面+反射.③注解+切面+反射 后两种方式,未 ...

  2. Java中HTTP下载文件——并解决跨域

    1.常用的需要设置的MIME类型 任何文件(二进制文件) application/octet-stream .doc application/msword .dot application/mswor ...

  3. 都2024年了,你还不知道git worktree么?

    三年前 python 大佬吉多·范罗苏姆(为 Python 程序设计语言的最初设计者及主要架构师)才知道 git worktree ,我现在才知道,我觉得没啥丢人的. 应用场景 如果你正在 featu ...

  4. 十、Doris操作参考手册

    1.SQL参考 1.1  用户账户管理 1.2  集群管理 1.3  DDL 1.4  DML 2.函数参考 2.1  日期函数 2.2  字符串函数 2.3  聚合函数 2.4  Cast转换函数 ...

  5. homebrew的安装和使用

    目录 背景 安装xcode 安装homebrew 有关报错解决 卸载脚本 homebrew软件搜索 brew 常用命令 brew redis安装 PhpWebStudy安装 安装php 背景 最近用b ...

  6. tomcat(3)- tomcat部署zrlog

    目录 1. Tomcat单独部署 2. nginx+tomcat部署 1. Tomcat单独部署 部署场景为: 客户端:192.168.20.1 tomcat:主机名:tomcat01,地址:192. ...

  7. Js使用面向对象和面向过程的方法实现拖拽物体的效果

    1.面向过程的拖拽实现代码: <!DOCTYPE html> <html> <head> <title>drag Div</title> & ...

  8. Oracle数据库下的DDL、DML、DQL、TCL、DCL

    首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1 ...

  9. kubernetes ingress网站发布

    ingress网站发布 单域名 # 1.创建nginx pod 名称: nginx-nodeport.yaml cat nginx-nodeport.yaml apiVersion: v1 kind: ...

  10. 音视频学习--H264解析渲染

    一.H264文件获取 下载一段MP4文件,通过FFMPEG转换成MP4 ffmpeg -i Gravity.mp4 -vcodec h264 out_2.264 二.通过解析H264成帧,然后刷新 这 ...