什么是avc权限
AVC权限通常指的是 Android 中的权限控制,其中 AVC 是 Access Vector Cache(访问向量缓存)的缩写。Android 使用了 Linux 内核,而 AVC 是 Linux 内核中用于强制访问控制(MAC)的一部分。Android 使用了 SELinux(Security-Enhanced Linux)来实现 MAC。
在 Android 中,AVC 权限用于限制应用程序对系统资源的访问。这包括文件、网络、硬件等资源。每个应用程序都有一个特定的安全上下文,AVC 权限通过安全上下文来控制应用程序对系统资源的访问权限。
AVC 权限的实现有助于提高 Android 系统的安全性,防止应用程序越权访问敏感信息或系统资源。开发人员在编写应用程序时需要遵循这些权限,以确保其应用程序在运行时能够按照设定的规则进行访问控制。
这里又提到了SELinux,那什么是SELinux呢?
SELinux(Security-Enhanced Linux)是一个为 Linux 内核提供强化的安全性机制的项目。它通过实施强制访问控制(MAC)来增强系统的安全性。传统的 Linux 安全模型使用的是基于用户和组的自愿访问控制(DAC),而 SELinux 引入了基于策略的强制访问控制。
在 SELinux 中,每个进程、文件和系统资源都有一个安全上下文,其中包含了关于其访问权限的详细信息。这种访问控制的强制性意味着即使用户具有访问某个资源的权限,SELinux 策略也可以限制对该资源的访问。
SELinux 主要有以下几个核心概念:
- 安全上下文(Security Context): 每个对象(如进程、文件、套接字等)都有一个关联的安全上下文,它包含了 SELinux 策略中定义的有关该对象的信息。
- 策略(Policy): SELinux 使用一个策略来定义系统中的安全规则。这个策略规定了哪些对象可以访问哪些资源,以及以何种方式进行访问。
- 强制访问控制(MAC): SELinux 引入了强制访问控制,这意味着即使在传统的自愿访问控制机制下具有访问权限的用户也受到 SELinux 策略的限制。
SELinux 在一些 Linux 发行版中已经被默认启用,它提供了额外的安全层,有助于防止未经授权的访问、减缓攻击传播和提高系统的整体安全性。
实际上就是你在某些地方访问某些东西时,权限被拒绝了,然后Log中有提示avc的警告,这个时候就需要进行添加avc权限来进行访问。
log:
2024-02-05 07:33:17.600 516-516 binder:516_6 android.system.suspend@1.0-service W type=1400 audit(0.0:197): avc: denied { read } for name="wakeup20" dev="sysfs" ino=31414 scontext=u:r:system_suspend:s0 tcontext=u:object_r:sysfs_ab_wakeup:s0 tclass=dir permissive=0
2024-02-05 07:35:30.580 516-516 binder:516_3 android.system.suspend@1.0-service W type=1400 audit(0.0:198): avc: denied { read } for name="wakeup20" dev="sysfs" ino=31414 scontext=u:r:system_suspend:s0 tcontext=u:object_r:sysfs_ab_wakeup:s0 tclass=dir permissive=0
类似于上述这种日志,就可以根据日志来进行添加对应的。
type=1400
: 这是 SELinux 审计消息的类型代码,表示 AVC(Access Vector Cache)。audit(0.0:198)
: 提供了关于审计事件的时间戳和事件序列号。avc: denied { read }
: 表明 SELinux 拒绝了一个读取操作。name="wakeup20"
: 这是触发 AVC 错误的文件或目录的名称。dev="sysfs"
: 指定了设备类型,这里是 sysfs。ino=31414
: 提供了文件或目录的 inode 号。scontext=u:r:system_suspend:s0
: 这是源(或发起)上下文,表示触发 AVC 事件的进程的安全上下文。tcontext=u:object_r:sysfs_ab_wakeup:s0
: 这是目标上下文,表示被访问对象的安全上下文。tclass=dir
: 这是目标类别,表示被访问对象的类型,这里是一个目录。permissive=0
: 表明 SELinux 不是在宽容(Permissive)模式下运行,即它是强制执行的。
整理一下,就是:需要在system_suspend.te
文件中添加
#类似于下面这种形式
allow system_suspend dumpstate:fifo_file write;
#下面是根据上述log进行添加
allow system_suspend sysfs_ab_wakeup:dir { read };
下面在举一个例子;
Log如下:
2024-02-05 03:18:14.243 13126-13126 e.myapplication com.example.myapplication W type=1400 audit(0.0:248): avc: denied { read } for name="version" dev="proc" ino=4026532087 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:proc_version:s0 tclass=file permissive=0 app=com.example.myapplication
分析结果为:需要在platform_app.te文件中。给proc_version添加对应的权限。此时有一个巧妙的看他是否还缺其他的权限的方法,因为在被权限拒绝后,后面的访问不会进行,所以只会提示一种报错。因此:
SELinux权限
场景:avc问题快速调试
1)adb shell getenforce //查询selinux运行模式
2)adb shell setenforce 0 //切换成permissive(宽容模式),需先adb root
3)adb shell setenforce 1 //切换成enforcing(强制模式)
这里可以改成宽容模式,然后查看info类型的日志来查看是否还需要添加权限。
Log如下:
2024-02-05 03:23:04.555 13126-13126 e.myapplication com.example.myapplication I type=1400 audit(0.0:250): avc: denied { read } for name="version" dev="proc" ino=4026532087 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:proc_version:s0 tclass=file permissive=1 app=com.example.myapplication
2024-02-05 03:23:04.555 13126-13126 e.myapplication com.example.myapplication I type=1400 audit(0.0:251): avc: denied { open } for path="/proc/version" dev="proc" ino=4026532087 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:proc_version:s0 tclass=file permissive=1 app=com.example.myapplication
2024-02-05 03:23:04.555 13126-13126 e.myapplication com.example.myapplication I type=1400 audit(0.0:252): avc: denied { getattr } for path="/proc/version" dev="proc" ino=4026532087 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:proc_version:s0 tclass=file permissive=1 app=com.example.myapplication
这里就看到提示了三种所需要的权限,因此添加如下:
allow platform_app proc_version:file { read open getattr};
添加方式和上面是一致的,添加完成编译即可。