news 2026/4/25 17:09:03

Selinux权限怎么加?Android开机脚本必备知识

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Selinux权限怎么加?Android开机脚本必备知识

Selinux权限怎么加?Android开机脚本必备知识

在Android系统开发中,让一个自定义shell脚本在开机时自动运行,看似简单,实则常被卡在Selinux权限这一关。很多开发者push脚本、修改init.rc、重启设备后发现脚本根本没执行——查logcat却只看到一串avc: denied的拒绝日志,无从下手。这不是脚本写错了,也不是init.rc语法有问题,而是Selinux在默默拦截。

本文不讲抽象理论,不堆砌SELinux术语,而是以“测试开机启动脚本”这个真实镜像为背景,带你从零走通一条可验证、可复现、可落地的完整路径:从写一个最简脚本开始,到定位权限错误、编写te规则、配置file_contexts、最终让脚本稳稳跑在开机阶段。所有步骤均基于Android 8.0+主流平台(含MTK)验证通过,适配预编译镜像环境,无需root手机、不依赖串口,用adb logcat就能完成全部调试。

1. 先写一个能跑起来的脚本

别急着改selinux,第一步永远是:确保脚本本身在手动执行时能正常工作。

1.1 脚本内容与存放位置

新建文件init.test.sh,内容如下:

#!/system/bin/sh # 设置一个测试属性,便于快速验证是否执行成功 setprop sys.test.boot 1 # 可选:写入日志便于追踪(需确保/data有写权限) echo "$(date): init.test.sh executed" >> /data/local/tmp/boot_log.txt

注意事项:

  • 第一行#!/system/bin/sh必须严格匹配Android系统实际shell路径。/system/bin/sh是AOSP标准路径;部分厂商(如高通)可能用/system/xbin/sh绝不能写成/bin/sh,否则init进程加载时会直接失败。
  • 脚本中避免创建新文件、修改系统分区等高风险操作。初期仅用setprop验证执行流,是最安全、最轻量的测试方式。
  • 建议将脚本存放在/system/bin/目录下(需remount system为可写),这是init进程默认信任的可执行路径之一。

1.2 手动验证脚本可用性

通过adb推送并手动执行,确认基础功能:

adb root adb remount adb push init.test.sh /system/bin/init.test.sh adb shell chmod 755 /system/bin/init.test.sh adb shell /system/bin/init.test.sh adb shell getprop sys.test.boot # 应输出 1

如果这一步失败,请先检查shell路径、权限、语法错误——Selinux问题永远排在功能验证之后

2. 在init.rc中注册服务

Android启动流程中,init进程读取init.rc及其包含的.rc文件来启动各类服务。我们要让脚本作为一项“服务”被init管理。

2.1 选择正确的.rc文件位置

不建议直接修改/system/etc/init.rc(易被OTA覆盖,且违反分层设计)。主流方案是:

  • 芯片平台侧:在device/<vendor>/<platform>/sepolicy/对应目录下,查找类似init.<platform>.rc的文件(如init.mt6765.rc
  • 项目侧:在device/<vendor>/<project>/下新建init.<project>.rc
  • 通用推荐:若镜像已预置init.vendor.rcinit.custom.rc,优先使用它

在选定的.rc文件末尾添加以下服务定义:

service test_boot /system/bin/init.test.sh class main user root group root oneshot seclabel u:object_r:test_service_exec:s0

关键字段说明:

  • oneshot:表示脚本执行完即退出,不常驻。适合一次性初始化任务。
  • seclabel:此处填写的是目标安全上下文标签,即我们即将为该脚本定义的SELinux类型。现在先占位,后续补全。
  • class main:确保该服务随main类服务一同启动(通常在early-init之后、late-init之前)

2.2 验证init.rc语法

修改后需重新编译bootimage或使用adb shell动态加载(部分设备支持):

adb shell stop adb shell start

但更可靠的方式是:重启设备后,立即执行:

adb shell cat /proc/1/cmdline # 确认init进程已重启 adb shell ls -Z /system/bin/init.test.sh # 查看当前文件SELinux上下文(此时应为u:object_r:shell_exec:s0或类似,尚未是我们定义的)

3. 定位Selinux拒绝日志

这是最关键的一步。没有日志,就等于在黑暗中调试。

3.1 开机后抓取avc拒绝记录

重启设备,在开机过程中(或开机完成后10秒内),立即执行:

adb logcat -b events | grep avc # 或更精准地过滤 adb logcat | grep -i "avc.*denied"

你大概率会看到类似这样的日志:

avc: denied { execute } for path="/system/bin/init.test.sh" dev="mmcblk0p42" ino=123456 scontext=u:r:init:s0 tcontext=u:object_r:shell_exec:s0 tclass=file permissive=0

日志解读(逐字段):

  • scontext=u:r:init:s0:源上下文 —— 发起操作的主体是init进程,类型为init
  • tcontext=u:object_r:shell_exec:s0:目标上下文 —— 被操作对象(脚本文件)当前的类型是shell_exec
  • tclass=file:操作对象类别是文件
  • { execute }:被拒绝的操作是“执行”
  • permissive=0:当前处于enforcing模式(严格模式),不是宽容模式

这条日志明确告诉我们:init进程想以execute方式访问一个类型为shell_exec的文件,但策略不允许。

3.2 理解为什么需要新类型

shell_exec是系统shell的默认类型,用于/system/bin/sh自身。但我们的自定义脚本不应共享此类型,原因有二:

  • 安全隔离:防止其他拥有shell_exec权限的进程误执行该脚本
  • 策略可控:为init访问该脚本单独授权,权限最小化

因此,我们必须为脚本定义一个专属类型(如test_service_exec),并告诉SELinux:“允许init执行这个新类型的文件”。

4. 编写并集成SELinux策略文件

策略文件由三部分组成:类型定义(.te)、文件上下文映射(file_contexts)、策略规则(.te中的allow语句)。缺一不可。

4.1 创建te策略文件

在设备厂商SELinux策略目录中(如device/mediatek/sepolicy/basic/non_plat/),新建文件test_service.te,内容如下:

# 定义服务域类型(domain type) type test_service, domain; # 定义脚本文件类型(file type) type test_service_exec, file_type, vendor_file_type, exec_type; # 声明该服务属于init守护进程域(关键!) init_daemon_domain(test_service); # 允许init域执行该脚本文件 allow init test_service_exec:file { read open execute }; # 允许test_service域读取/写入属性(因为脚本里用了setprop) allow test_service property_type:property_service { set };

关键点解析:

  • init_daemon_domain(test_service):这是核心宏。它自动为test_service域赋予init守护进程所需的基础权限(如访问/dev、/sys等),省去大量手动allow。
  • allow init ...:明确授权init进程对test_service_exec类型文件的readopenexecute权限。注意主语是init(不是test_service),因为init是启动者。
  • allow test_service property_service { set }:因脚本调用setprop,必须授权其向property_service发送set请求。

4.2 配置file_contexts映射

在同目录下的file_contexts文件(如device/mediatek/sepolicy/basic/non_plat/file_contexts)中,添加一行:

/system/bin/init\.test\.sh u:object_r:test_service_exec:s0

注意:

  • 路径需使用正则转义.写成\.),确保精确匹配文件名,避免误匹配其他脚本。
  • 上下文格式必须严格为u:object_r:<type>:s0,其中<type>必须与.te文件中定义的类型名完全一致(test_service_exec)。

4.3 策略编译与生效

  • 若使用完整AOSP编译:mm sepolicy即可,策略会自动打包进vendor.imgboot.img
  • 若使用预编译镜像(如本文“测试开机启动脚本”镜像):策略文件需提前集成到镜像中。开发者只需确认该镜像的sepolicy目录已包含上述两个文件,并在编译时被正确引用。

验证映射是否生效:

adb shell ls -Z /system/bin/init.test.sh # 正常输出应为:u:object_r:test_service_exec:s0

5. 验证与常见问题排查

完成以上步骤后,重启设备,用最简方式验证效果。

5.1 快速验证方法

# 1. 检查属性是否设置成功 adb shell getprop sys.test.boot # 应返回 1 # 2. 检查服务是否被init启动(查看进程列表) adb shell ps | grep test_boot # 可能看不到,因为oneshot会退出;可改用start命令临时触发 adb shell start test_boot adb shell getprop sys.test.boot # 再次确认 # 3. 检查日志中是否还有avc拒绝 adb logcat | grep -i "avc.*denied" | grep test # 理想状态:无任何相关拒绝日志

5.2 高频问题与解决方案

问题现象可能原因解决方案
getprop返回空,且logcat无avc日志脚本未被init启动检查.rc文件是否被正确加载(adb shell cat /proc/1/cmdline看init参数)、服务名拼写、class是否匹配当前启动类
avc denied { execute }依然存在file_contexts未生效或类型名不一致adb shell ls -Z确认文件上下文;核对.tefile_contexts中类型名是否完全相同(大小写、下划线)
avc denied { set }新出现缺少property_service授权.te中补充allow test_service property_type:property_service { set };
脚本执行但/data/local/tmp/boot_log.txt未生成/data分区SELinux上下文限制改用log -p i -t TEST "msg"写入logcat,或授权test_servicedata_file_typewrite权限(不推荐,违背最小权限原则)

6. 总结:Selinux加权限的本质逻辑

加Selinux权限,从来不是盲目堆砌allow语句,而是一场清晰的“角色-动作-对象”建模:

  • 角色(Domain):谁在操作?是init(启动者)还是test_service(脚本执行后的新进程)?本文中,启动阶段的权限由init发起,故主语是init
  • 动作(Permission):要做什么?execute(执行文件)、set(设置属性)、read(读取)… 动作必须精确到最小粒度。
  • 对象(Type):对什么做?文件类型(test_service_exec)、属性类型(property_type)、设备节点类型(dev_type)… 类型必须唯一且语义明确。

当你下次再遇到avc denied,请记住这个三步法:

  1. 看日志scontexttcontexttclass{ perm }四要素缺一不可;
  2. 定角色:判断是哪个进程(domain)需要什么权限;
  3. 写规则:用allow <domain> <type>:<class> { <perm> };补全,辅以init_daemon_domain()等宏简化。

权限不是障碍,而是系统为你画出的安全边界。理解它,才能真正掌控Android的启动过程。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 7:25:47

OFA视觉蕴含模型应用场景:跨境电商多语言商品图文一致性验证

OFA视觉蕴含模型应用场景&#xff1a;跨境电商多语言商品图文一致性验证 1. 项目背景与核心价值 跨境电商平台面临一个普遍挑战&#xff1a;商品图片与描述文字不一致的问题。当卖家使用多语言描述商品时&#xff0c;人工审核成本高且效率低下。OFA视觉蕴含模型为解决这一问题…

作者头像 李华
网站建设 2026/4/25 9:28:58

GLM-4V-9B惊艳效果集锦:15组高难度图问图答真实截图

GLM-4V-9B惊艳效果集锦&#xff1a;15组高难度图问图答真实截图 1. 多模态大模型的视觉理解新高度 GLM-4V-9B作为当前最先进的多模态大模型之一&#xff0c;在视觉理解能力上实现了重大突破。这个基于Streamlit构建的本地部署方案&#xff0c;不仅解决了官方示例在特定环境下…

作者头像 李华
网站建设 2026/4/24 3:44:12

零门槛全平台资源获取工具:打破数字壁垒的媒体资源管理解决方案

零门槛全平台资源获取工具&#xff1a;打破数字壁垒的媒体资源管理解决方案 【免费下载链接】res-downloader 资源下载器、网络资源嗅探&#xff0c;支持微信视频号下载、网页抖音无水印下载、网页快手无水印视频下载、酷狗音乐下载等网络资源拦截下载! 项目地址: https://gi…

作者头像 李华
网站建设 2026/4/24 5:17:09

YOLO11官方文档之外的实用技巧汇总

YOLO11官方文档之外的实用技巧汇总 在YOLO11正式发布后&#xff0c;大量开发者迅速上手训练和部署&#xff0c;但很快发现——官方文档讲得清楚&#xff0c;却未必覆盖真实工程中那些“卡住你一整天”的细节。比如&#xff1a;为什么训练时显存突然爆掉&#xff1f;为什么标注…

作者头像 李华
网站建设 2026/4/24 5:17:16

新手必看:从0开始玩转阿里开源Live Avatar数字人

新手必看&#xff1a;从0开始玩转阿里开源Live Avatar数字人 1. 这不是“另一个数字人”&#xff0c;而是能跑起来的实时数字人 你可能已经见过太多“数字人”概念——PPT里的炫酷演示、视频里几秒的惊艳片段、论文中复杂的架构图。但真正能让你在本地服务器上一键启动、上传…

作者头像 李华