当前位置: 首页 > news >正文

【Android】【底层原理】深入解析SELinux模块

SELinux模块不仅是一个安全功能,更是Android安全架构的基石。理解SELinux对于处理系统级问题、进行深度定制和应对安全挑战至关重要。


1. SELinux 概述:从“自由放任”到“强制管控”

什么是SELinux?

SELinux最初由美国国家安全局开发,是一种强制访问控制 系统。它内置于Linux内核中,用于补充传统的自主访问控制。

Android的安全演进
  • Android 4.3及以前:宽容模式
    • 传统的Linux权限模型(DAC)是主力。只要进程拥有正确的UID/GID,它就可以访问对应文件。
    • 问题:如果一个应用被提升到root权限,它就可以为所欲为,访问整个系统。root滥用是主要安全隐患。
  • Android 4.4:引入SELinux,但处于宽容模式
    • 开始引入SELinux策略,但默认设置为permissive。在此模式下,SELinux会记录违规访问,但不会实际阻止。主要用于收集策略和调试。
  • Android 5.0及以后:全面强制执行
    • 默认设置为enforcing模式。任何违反SELinux策略的操作都会被直接拒绝并记录。这标志着Android安全模型的质的飞跃。

2. 核心原理:主体、客体和策略

想象一下一个高度机密的政府大楼:

  • 主体:大楼里的人员(例如:进程/system/bin/surfaceflinger, com.android.phone)。
  • 客体:被访问的资源(例如:文件/dev/gpu/fb0, 套接字, 属性sys.powerctl)。
  • 策略:一套极其详细的安保规则,规定了哪个身份的人,在什么角色下,可以访问哪个区域的哪个资源

SELinux不是简单地看你的“工作证”(UID),而是看你所在的“安全许可级别”和“部门”,并严格规定你能做什么。

核心概念
  1. 标签

    • 系统中的每个主体客体都被打上了一个SELinux标签(也称为安全上下文)。
    • 格式:user:role:type:level(在Android中,最常用和最重要的是type)。
    • 示例
      • 一个进程:system_u:system_r:system_server_t:s0
      • 一个文件:system_u:object_r:system_file_t:s0
      • 一个设备节点:u:object_r:gpu_device_t:s0
  2. 策略

    • 策略是一组预定义的规则,明确规定了source_type能否对target_type执行class上的permission
    • 规则语法
      allow source_type target_type : class { permission_set };
      
    • 实例解析
      # 允许 surfaceflinger 进程(source_type)对 framebuffer 设备(target_type)进行读写和打开操作
      allow surfaceflinger gpu_device : chr_file { read write open };
      
      • surfaceflinger:进程的type上下文。
      • gpu_device:文件(设备节点)的type上下文。
      • chr_file:客体类别,代表字符设备文件。
      • { read write open }:允许的操作权限集合。
  3. 域转换

    • 一个进程如何从一个不受限制的域(如init)转换到一个受限制的域(如system_server_t)。
    • 通常通过可执行文件的标签和策略规则实现。当init(PID 1)进程执行/system/bin/app_process时,由于这个二进制文件被打上了zygote_exec的标签,策略规则允许它自动切换到zygote域。
    # init 进程可以执行被打上 zygote_exec 标签的文件
    allow init zygote_exec : file execute;
    # 当执行 zygote_exec 文件时,进程可以从 init 域转换到 zygote 域
    domain_auto_trans(init, zygote_exec, zygote)
    

3. Android中的SELinux工作模式

模式
  • enforcing:强制模式。违反策略的操作被拒绝。这是生产环境的默认设置。
  • permissive:宽容模式。违反策略的操作被允许,但会记录到日志中。用于开发和调试。
  • disabled:完全禁用。不加载SELinux。
查看和设置模式
# 查看当前模式
getenforce
# 输出:Enforcing# 临时切换到宽容模式(需要root权限)
setenforce 0
# 临时切换回强制模式
setenforce 1# 查看内核启动参数中的设置(决定初始模式)
cat /proc/cmdline | grep androidboot.selinux

4. Android SELinux策略的架构

Android的策略不是单一文件,而是一个复杂的集合,主要位于/system/etc/selinux/vendor/etc/selinux

  1. 分割的策略

    • 平台策略:AOSP通用策略,位于/system/etc/selinux
    • 供应商策略:SoC厂商(如Qualcomm)提供的策略,位于/vendor/etc/selinux
    • ODM策略:设备制造商(如Samsung, Xiaomi)提供的策略,位于/odm/etc/selinux
    • 这种分割是Project Treble的要求,使得系统框架和硬件相关的策略可以独立更新。
  2. 策略文件

    • *.te:类型强制文件,是策略的核心,包含了所有的allow规则。
    • file_contexts:定义了文件系统上的文件、目录、设备节点的安全上下文。
    • property_contexts:定义了Android系统属性(sys., ctl., persist.等)的安全上下文。
    • service_contexts:定义了Binder服务的安全上下文。
    • seapp_contexts:定义了应用进程和数据目录的安全上下文。
    • mac_permissions.xml:与seapp_contexts配合,根据应用签名或包名为其分配SELinux上下文。

5. 实战:如何分析和解决SELinux问题

这是作为开发者和定制ROM维护者的核心技能。

步骤1:抓取日志

当遇到权限问题时,首先检查SELinux是否拒绝。

# 使用 logcat 并 grep avc 信息
adb logcat | grep -i "avc:"# 或者使用 dmesg
adb shell dmesg | grep -i "avc:"

一条典型的AVC拒绝日志如下:

[   12.345678] type=1400 audit(0.0:123): avc: denied { read } for pid=1234 comm="my_daemon" name="my_device" dev="tmpfs" ino=5678 scontext=u:r:my_daemon_t:s0 tcontext=u:object_r:unlabeled:s0 tclass=chr_file permissive=0
步骤2:解析日志

让我们解剖这条日志:

  • avc: denied { read }:SELinux拒绝了操作。
  • pid=1234 comm="my_daemon":肇事者是进程my_daemon,PID为1234。
  • scontext=u:r:my_daemon_t:s0源上下文,即进程的安全标签。它是my_daemon_t域。
  • tcontext=u:object_r:unlabeled:s0目标上下文,即要访问的客体的安全标签。目前是unlabeled,说明这个设备节点还没有被正确标记。
  • tclass=chr_file目标类别,这是一个字符设备文件。

结论:策略不允许在my_daemon_t域中的进程读取标签为unlabeled的字符设备文件。

步骤3:制定解决方案

方案A(推荐,遵循最小权限原则):如果my_device是一个新的自定义设备节点。

  1. 定义新的Type
    device/your_company/your_device/sepolicy/vendor/my_device.te中:
    # 定义 my_device 的类型
    type my_device, dev_type;
    
  2. 标记设备节点
    device/.../sepolicy/vendor/file_contexts中:
    # /dev/my_device 被打上 my_device 的标签
    /dev/my_device u:object_r:my_device_device:s0
    
  3. 编写允许规则
    my_device.te文件中添加:
    # 允许 my_daemon_t 域对 my_device 设备进行必要的操作
    allow my_daemon_t my_device_device:chr_file { open read write ioctl };
    

方案B(快速但危险,仅用于调试):临时放宽策略。

# 非常宽泛的规则:允许 my_daemon_t 域访问任何字符设备(危险!)
allow my_daemon_t dev_type:chr_file { open read write };

永远不要在产品中使用这种宽泛规则,它破坏了SELinux的安全边界。

步骤4:编译和验证
  • 将修改的策略文件放入设备源码的相应位置。
  • 重新编译bootimagevendorimage并刷入。
  • 将设备切换到permissive模式进行测试,确保新的策略能正常工作且没有新的拒绝日志。
  • 最后,切换回enforcing模式进行最终验证。

6. Neverallow规则:策略的“防火墙”

SELinux策略本身也受到保护。neverallow规则是策略的“元规则”,它禁止在策略中出现某些危险的授权。

示例

# 绝不允许任何应用域(appdomain)直接访问 GPU 设备
neverallow appdomain gpu_device:chr_file { open read write };

如果有人(包括设备制造商)在.te文件中添加了违反neverallow的规则,在编译时就会报错,无法通过。这确保了策略基础的安全性底线。


总结:为什么SELinux对Android如此重要?

  1. 遏制漏洞:即使一个应用通过漏洞获得了root权限,SELinux策略也会将其限制在其域内,防止其对系统其他部分进行横向攻击。
  2. 最小权限原则:每个进程只能拥有完成其本职工作所必需的最少权限,别无其他。
  3. 防御纵深:SELinux与Linux DAC、Capabilities、App Sandbox等共同构成了Android的纵深防御体系。
  4. 审计能力:详细的AVC日志为安全审计和问题排查提供了宝贵信息。

对于开发者而言,掌握SELinux意味着你能够:

  • 深入理解Android系统的安全模型。
  • 自信地进行系统级开发和定制。
  • 快速定位和解决那些看似“神秘”的权限拒绝问题。
  • 为你的设备或产品构建更安全、更健壮的软件。
http://www.dtcms.com/a/532020.html

相关文章:

  • 阮一峰《TypeScript 教程》学习笔记——注释指令
  • 最好的开发网站建设价格app免费制作平台下载
  • 供应链进销存源码uniapp全开源ERP多仓库管理系统pc+app手机端
  • 生物化学Learning Track(15)酶活性的调节
  • 站酷设计网站官网入口下载国外手机设计网站
  • Rust 泛型与特性
  • GPT-1 技术报告
  • 中英双语 网站 模板wordpress返佣
  • 机器学习库的决策树绘制
  • k8s的calico出现ipset报错解决方法
  • SimpleDateFormat
  • 网站后期的维护和更新池州网站建设推广
  • 低空经济的实时神经系统:空地一体化音视频架构的技术演进
  • 更换MacbookAir固态硬盘,并用U盘安装MacOS操作系统
  • 创建一个简单的SpringBoot
  • 硅基计划2.0 学习总结 玖 图书管理系统 2.0复盘版(文字末尾源码可复制)
  • 河北省建设信息网站十种营销方法
  • qt调用摄像头进行yolo的实时检测
  • 网站备案通过什么可以备案wordpress熊掌号插件
  • IntelliJ IDEA 使用 Lombok 报错:“Lombok requires enabled annotation processing” 解决方案
  • qtmqtt: 一个开源且好用的mqtt开源客户端
  • 数据仓库——总线架构详解
  • 软件中锁机制全解析:从线程到分布式锁
  • 郴州网站设计做外墙资料的网站
  • 【Swift】LeetCode 238.除自身以外数组的乘积
  • GitLab
  • GitHub等平台形成的开源文化正在重塑继任者
  • 【区块链学习笔记】17:以太坊中的GHOST协议
  • 【SpringAI】10.结构化输出
  • 递归经典例题