基于Android13的系统启动流程分析(一)之SeLinux权限介绍

这篇具有很好参考价值的文章主要介绍了基于Android13的系统启动流程分析(一)之SeLinux权限介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

学习Android系统启动流程之前先学习一下SeLinux权限系统,步入正题

本章讲解的方向和你将收获的知识:

  • 什么是SeLinux系统,SeLinux的简介和介绍
  • SeLinux系统的主要作用和存在的意义,是基于哪个版本开始推行该方案的
  • 如果遇到了SeLinux权限问题该如何解决,有几种解决方案
  • SeLinux详细内容知识分解,你将了解宽松模式和严格模式

一. SeLinux介绍

  1. SeLinux 全称 Security-Enhanced Linux 即安全增强型 Linux,基于MAC机制的一种实现,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统,这不是android特有的特性,而是由Linux衍生过来的SEAndroid。

  2. 在Android Q版本上就开始推行SeLinux机制且强行执行此机制(沙盒机制,只能获取到AOSP指定的对外的接口去获取),所以在之前很多应用在Android Q上会产生很多权限相关的问题。

  3. 如果在Android Q或以上的版本遇到权限问题,尝试命令:adb shell logcat | grep avc,如果有对应的avc log输出则大概率是受SeLinux权限影响

    avc: denied { read } for pid=1834 comm=“gps_location” name=“mmcblk0p17” dev=“tmpfs”
    scontext=u:r:gps_location:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0

  4. SeLinux关键字介绍
    MAC和DAC都隶属于访问控制类,分为自主和强制两种方式
    基于Android13的系统启动流程分析(一)之SeLinux权限介绍4.1 访问控制
    Linux 内核资源访问控制分为 DAC(Discretionary Access Control,自主访问控制)和 MAC(Mandatory
    Access Control,强制访问控制)两类
    4.2 DAC
    这是基于用户-用户组的读、写、执行的权限检查,该管理过于宽松,如果获得 root 权限,可以在 Linux 系统内做任何事情
    4.3 MAC
    SELinux是 MAC 机制的一种实现,基于安全上下文和安全策略的安全机制,用于补充 DAC 检查。访问系统资源时,会先进行 DAC 检查,DAC 检查通过,才能进行 MAC 检查,如果 MAC 检查通过,才能获得访问权限

二. SeLinux基础知识

SELinux 分为 Permissive 和 Enforcing 两种模式

  1. Permissive 宽容模式
    宽容模式,代表 SELinux 运作中,违反 SELinux 规则时只会有警告讯息(avc denied),而不会实际限制的访问.
    在 Permissive 模式中,SELinux 被启用,但安全策略规则并没有被强制执行。当安全策略规则应该拒绝访问时,访问仍然被允许。然而,此时会向日志文件发送一条消息,表示该访问应该被拒绝(avc).

  2. Enforcing 严格模式
    在 Enforcing 模式中, SELinux 被启动,并强制执行所有的安全策略规则,代表 SELinux 运作中,违反 SELinux 规则的行为将被阻止并记录到日志中(avc)

  3. 查看当前SELinux模式
    (1)通过adb命令行来查看:adb shell getenforce,输出结果—>Enforcing 或者 Permissive
    (2)通过adb logcat命令行来观察:adb logcat | grep avc

    avc:denied {write setter} for path=”/dev/…” dev=”tmpfs”
    scontext=u:r:system_server:s0 tcontext=u:object_r:file:s0 permissive=1
    (permissive=1,说明是 Permissive 模式。permissive=0,说明是 Enforcing 模式)

  4. avc权限语法介绍

    avc: denied { read } for pid=1834 comm=“system_server” name=“mmcblk0p17” dev=“tmpfs” ino=10268 [scontext=u:r:system_server:s0] [tcontext=u:object_r:block_device:s0] tclass=blk_file permissive=0

    (此 AVC log 说明 system_server(进程)缺少对标签为 block_device、类型为 blk_file 和名称为 mmcblk0p17 文件的 read 权限)
    (1). avc: denied:表示当前操作被拒绝。
    (2). { read }:表示被拒绝的操作,{ }中含有实际尝试的操作。
    (3). for pid=1834:当前发生 avc: denied 进程的 ID。
    (4). comm=“system_server”:当前发生 avc: denied 进程的名称,即主体进程名称。
    (5). name=“mmcblk0p17”:操作尝试的目标文件或目录的路径,即客体资源名称。
    (6). dev=“tmpfs”:含有这个文件系统的设备节点,客体资源在该文件系统中。
    (7). ino=10268:目标文件或目录的节点号。
    (8). scontext=u:r:system_server:s0:主体进程的安全上下文。
    (9). tcontext=u:object_r:block_device:s0:客体资源的安全上下文。
    (10). tclass=blk_file:访问资源所属类别。
    (11). permissive=0:当前是 Enforcing 模式,permissive=1 时为 Permissive 模式

三. 解决SeLinux权限问题

1.命令行修改权限模式

adb root;   
adb shell setenforce 0 --->设置为Permissive宽松模式,临时关闭SELinux,机器重启以后还是会恢复的

2.AndroidManifest.xml配置开关
需要注意targetSdkVersion 需要小于 30

android:requestLegacyExternalStorage="true"

3.修改init启动过程中的代码
这种方式比较简单—>修改 system/core/init/selinux.cpp 文件里的 IsEnforcing()函数,直接让它返回false即可

bool IsEnforcing() {
    // 直接返回false
    return false;
    if (ALLOW_PERMISSIVE_SELINUX) {
        return StatusFromProperty() == SELINUX_ENFORCING;
    }
    return true;
}

void SelinuxSetEnforcement() {
    // getenforce获取Enforcing模式
    bool kernel_enforcing = (security_getenforce() == 1);
    // 直接让is_enforcing返回false即关闭严格模式
    bool is_enforcing = IsEnforcing();
    if (kernel_enforcing != is_enforcing) {
        // 调用security_setenforce(false)设置为Permissive宽容模式
        if (security_setenforce(is_enforcing)) {
            PLOG(FATAL) << "security_setenforce(" << (is_enforcing ? "true" : "false")
                        << ") failed";
        }
    }

    if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result.ok()) {
        LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
    }
}

4.根据报错的权限添加SELinux权限
由于缺少 SELinux 权限导致如下“avc: denied”,需要根据 AVC log 信息添加相应权限。

avc: denied { read write } for pid=3483 comm=“batteryTest” name=“rtc0” 
dev=“tmpfs” scontext=u:r:system_server:s0 tcontext=u:object_r:custom_battery_device:s0 
tclass=chr_file permissive=0

system_server(进程)缺少对标签为 custom_battery_device、类型为 chr_file 和名称为 rtc0 文件节点的读写权限。
根据上面缺少的avc添加所需的读写权限:
(1). 打开/system/sepolicy/private/{scontext.te}(system_server.te)文件
(2). 添加如下代码:和上面的标签对应上:{allow scontext tcontext:tclass permission }
(3). 例如allow system_server custom_battery_device:chr_file {read write} ,编译源码并进行烧录即可

四. Neverallow问题

添加了selinux权限后,代码进行编译时,编译失败并报 neverallow 错误,例如添加`allow system_app sysfs:file {write};`权限后编译报错

原因是 Google 不允许应用进程写 sysfs 类型的文件,这是Google规范,安全考虑,部分权限不允许给,
当然也可以修改domain.te来修改Google的规范,虽然可以解决问题,但是这是不被允许的,在送测的时候会导致GMS测试失败。

例如domain.te拥有以下代码:
neverallow { appdomain -bluetooth -nfc }sysfs:dir_file_class_set write
那么则不允许给dir_file_class_set标签赋予write权限。

那又必须要这个权限怎么办?那就可以客制化SELiunx权限。

五. SELinux权限客制化(自定义权限)

根据上面所说,Google规则需遵守,部分权限不允许通过,所以需要自定义权限规则.

  • type定义
    type分为了property.tefile.tesystem.te,有很多类型,不止这三种,使用哪个文件取决于avc权限中的tclass属性,目前只用file.te举例,打开file.te添加如下type

    /system/sepolicy/private/file.te
    # {parameter1,parameter2,parameter3}
    # type固定格式,custom_battery_file自定义的名称,file_type定义为文件类型
    # 逗号分割,后面可以继续跟类型 例如:data_file_type
    type custom_battery_file, file_type;
    
  • 配置安全上下文
    安全上下文分为了 genfs_contextsfile_contextsproperty_contexts ,当然不止这几种,例举了一些常用的
    打开 /system/sepolicy/private/file_contexts 文件,打开哪个文件取决于avc权限中的tclass属性
    (三个xxx_contexts,需要自行判断缺少的权限的客体资源是目录还是文件 或是 属性值):

    /system/sepolicy/private/file_contexts
    # 添加如下代码
    # 第一个参数写文件节点(读取这个文件节点没权限,就添加这个节点)
    # 第二个参数固定写法u:object_r:custom_battery_file(这里写file.te里定义的类型):s0(这些参数不做详细解释)
    /vendor/custom/product/battery	u:object_r:custom_battery_file:s0
    

    /xxx/xxx (目标文件路径或文件) u:object_r:file.te里面自定义的名称:s0

  • 配置原进程访问权限
    根据avc log中的scontext(主体进程)的值来决定在哪个文件下添加访问权限
    例如 scontext=u:r:system_server:s0,那则打开system_server.te即可

    /system/sepolicy/private/system_server.te
    # 1.allow固定格式 
    # 2.system_server固定格式取决于scontext的值  
    # 3.custom_battery_file(file.te里自定义的类型)
    # 4.冒号后面的file,取决于avc log中的tclass类型是什么(例如tclass=file)
    # 5.{要给的权限类型}
    allow system_server custom_battery_file:file {read open};
    

    这样就客制化好了一个节点的写权限

六. 补充知识(mls规则)

终端中查看安全上下文的方法
在终端中,可通过如下指令查看文件安全上下文:ls -lZ
在终端中,可通过如下指令查看属性安全上下文:getprop -Z
在终端中,可通过如下指令查看进程安全上下文:ps -Z

如果 te 文件已经添加 SELinux 权限,但没有生效,查看 AVC log 信息出现“s0:c512,c768”字眼,则可判
断是由于 mls 规则导致。说明主体和客体安全级别不同,
举例:已经在 platform_app.te 中添加了 SELinux 权限,但 log 中依然有如下报错:
avc: denied { write } for pid=2002 comm=“lightness”
scontext=u:r:platform_app:s0(主体):c512,c768 tcontext=u:r:custom_device_lightness:s0(客体资源) tclass=char_file(file类型,读取的文件节点属于file类型) permissive=0

主体: scontext=u:r:【platform_app】
客体: tcontext=u:r:【custom_device_lightness】
这是因为 Google 在文件 system/sepolicy/private/mls 中进行了安全级的限制,代码如下:
【mlsconstrain cahr_file { write } (l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);】
l1需要l2相等,或者l1等于mlstrustedsubject l2等于mlstrustedsubject ,才能允许SELiunx权限。

这种情况需要主体进程或者客体进程中的一个是 mlstrustedsubject,这里 platform_app(主体) 最好不要修改,所以要修改客体 slogmodem(客体)。

具体修改方法如下:

/system/sepolicy/private/platform_app.te(取决于主体进程)文件
添加如下代码:
type custom_device_lightness, domain, mlstrustedsubject;

七. 代码修改后烧录

1.如果只是修改 selinux 相关文件–通过编译命令:
(1)lunch 项目
(2)cd system/sepolicy
(3)mma
将编译产物 out/target/product/xxx/system/etc/selinux 和 out/target/product/xxx/vendor/etc/selinux 拷贝出来,推入手机查看是否生效,执行指令如下:
(1)cd out/target/product/xxx
(2)adb root
(3)adb remount
(4)adb push system/etc/selinux /system/etc/
(5)adb push vendor/etc/selinux /vendor/etc/
如果手机不能root && remount,可以考虑通过编译烧录的方式去验证

总结

至此SELinux权限系统基本上介绍完毕,如何解决权限问题,如何关闭权限和切换权限,自定义权限,配置权限,皆已教学完毕。不为别的,为了留下工作上的脚印

下一篇进入基于Android13的系统启动流程分析(一)之文件系统介绍(待补充)文章来源地址https://www.toymoban.com/news/detail-444650.html

到了这里,关于基于Android13的系统启动流程分析(一)之SeLinux权限介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android SELinux 权限相关问题

    问题 再做OTA的时候,需要zip包放在data/ota_package下,再操作的时候,报错如下 提取 scontext: system_app tcontext: ota_package_file tclass: file denied: write 翻译过来就是 system_app 对于ota_package_file 目录缺少write 权限 我们只需要android/device/qcom/sepolicy_vndr/generic/vendor/common/目录下 的syste

    2023年04月08日
    浏览(38)
  • Android 修改 SELinux avc 权限的方法

    系统版本:Android 11.0     平         台:RK3568 在 Android 系统的开发及适配过程中,我们常常需要对 SELinux avc  权限进行修改,以下是我对 SELinux avc  权限修改总结的方法。 一、验证功能是否存在 selinux 权限问题 #进入Android终端 adb shell #获取root权限 su #查看系统当前 s

    2024年02月09日
    浏览(39)
  • MTK Android设置setprop的selinux权限

    自定义了个SystemProperties的属性,需要在system应用中修改它,介绍MTK及展锐的设置方法,可扩展到其他平台. 比如代码中要这么设置 默认会引发selinux无权限的报错. 修改方法是在对应的.te中添加对应的属性,注意不同的平台属性及修改目录可能不一样,比如展锐的与MTK的就

    2024年02月11日
    浏览(40)
  • Android 13 网络 Adb相关流程深入分析研究

    通过代码分析发现Android13 上对 网络adb 进行了限制! Android13原生代码要求:必现连接上某个wifi,才能进行adb ,并且切换wifi或者关闭wifi都是会停止adb。 并且Android13 上 wifi adb 端口号每次是变化的,这个也是很不方便的! 如果要做成Android11 或者之前一样,设备连接WiFi/有线网

    2024年02月09日
    浏览(54)
  • Android SystemServer 启动流程分析

    和你一起终身学 习,这里是程序员Android 经典好文推荐,通过阅读本文,您将收获以下知识点: 一、SystemServer 启动的服务有哪些 二、SystemServer启动总体流程概述 三、SystemServer 如何启动,是谁启动的? 四、 SystemServer 启动入门 main 方法 五、SystemServer Run 方法初始与启动 六、

    2024年02月13日
    浏览(47)
  • Android 13 骁龙相机点击拍照流程分析(二)——点击拍照到存入相册

            本篇是在Android 13 骁龙相机点击拍照流程分析(一)——点击拍照到更新到左下角缩略图文章的基础上进行延申的,前面的预览、点击拍照的过程参考第一篇:Android 13 骁龙相机点击拍照流程分析(一)——点击拍照到更新到左下角缩略图-CSDN博客         从第一篇的

    2024年02月06日
    浏览(51)
  • android framework之Applicataion启动流程分析

    Application启动流程框架分析 启动方式一:通过Launcher启动app 启动方式二:在某一个app里启动第二个app的Activity. 以上两种方式均可触发app进程的启动。但无论哪种方式,最终通过通过调用AMS的startActivity()来启动application的。    根据上图分析, 要启动一个Application,需要涉及五

    2024年02月11日
    浏览(46)
  • Android 13 骁龙相机点击拍照流程分析(一)——点击拍照到更新到左下角缩略图

    由于最近客户定制需要将文件挂载类型修改为sdcardfs,由于修改了文件挂载类型,导致了骁龙相机拍照后不能点击进入相册,故对骁龙相机从点击事件开始进行问题的排查,此处不介绍最终的sdcardfs挂载后的问题解决方案 拍照的流程大概分为几个阶段:打开相机进行预览、点

    2024年02月04日
    浏览(53)
  • Android系统启动流程概览

    Boot Rom —— Bootloader —— Linux Kernel —— init进程 —— Zygote进程(dalvik/ art)—— systemServer —— Apps init 进程是Linux系统中,用户空间启动的第一个进程。 创建并挂载一些文件目录 启动属性服务 解析 init.rc 配置文件,启动 Zygote 进程 挂载 seLinux 文件目录,创建seLinux,加载

    2024年02月06日
    浏览(44)
  • Android系统启动流程 源码解析

    本文链接:https://blog.csdn.net/feather_wch/article/details/132518105 有道云脑图:https://note.youdao.com/s/GZ9d8vzO 1、整体流程 Boot Room BootLoader idle kthread init init ServiceManager zygote zygote SystemServer app 1、kernel/common/init/main.c 2、andorid.mk-android.bp编译 3、init是用户空间鼻祖 属于C、C++ Framework 1.1 启动源

    2024年02月11日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包