2026/5/14 9:05:01
网站建设
项目流程
做网站制作要多少费用,PHP 网站开发 重点知识,河池市网站建设,成都设计网站建设开机脚本写好了却没执行#xff1f;可能是SELinux权限问题
你是否遇到过这样的情况#xff1a;精心编写了开机启动脚本#xff0c;也按规范添加到了 init.rc 或 init.xxx.rc 中#xff0c;系统重启后却毫无反应#xff1f;logcat 和 dmesg 里找不到任何执行痕迹#xff…开机脚本写好了却没执行可能是SELinux权限问题你是否遇到过这样的情况精心编写了开机启动脚本也按规范添加到了init.rc或init.xxx.rc中系统重启后却毫无反应logcat和dmesg里找不到任何执行痕迹手动执行脚本却一切正常——脚本语法没问题、路径没问题、权限chmod 755也加了……那问题很可能出在 SELinux 上。在 Android 8.0 及之后的版本中SELinux 已默认启用并运行于enforcing模式。这意味着即使脚本本身完全合法只要它的执行过程违反了 SELinux 策略比如进程域无权访问该脚本文件、无权设置属性、无权调用某些系统服务内核就会静默拒绝脚本根本不会被 fork 和 exec自然也就“没执行”。本文不讲抽象理论只聚焦一个真实可复现的场景如何让一个简单的init.test.sh在 Android 8.0 设备上真正开机自启。我们将从脚本编写、策略定义、上下文标注、服务声明到排错验证全程实操每一步都对应实际报错和解决逻辑帮你绕过那些隐藏极深的 SELinux 坑。1. 脚本本身开头、路径、测试三要素缺一不可很多问题其实在第一步就埋下了伏笔。一个看似普通的 shell 脚本在 Android init 环境下有严格约束。1.1 正确的解释器路径是前提Android 的 init 进程不使用标准 Linux 的/bin/sh它依赖的是系统分区中的特定 shell#!/system/bin/sh # 或 #!/system/xbin/sh # 某些定制 ROM 使用注意写成#!/bin/sh或#!/usr/bin/env sh在大多数 Android 设备上会直接失败init 不会识别该解释器#后面的注释行不能干扰解释器识别第一行必须是纯净的#!行如果你把脚本放在/vendor/bin/下也要确保该路径下存在对应 shell通常需 symlink 到/system/bin/sh。1.2 脚本内容建议“轻量且可观测”避免一上来就操作文件、挂载设备或调用复杂命令。初期验证阶段推荐用最易观测的方式确认执行成功#!/system/bin/sh # 设置一个系统属性重启后可用 getprop 验证 setprop sys.boot.test_script 1 # 记录时间戳到临时日志需确保 /data/local/tmp 可写 echo [date] test script executed /data/local/tmp/init_test.log # 可选触发一个 logcat tag便于快速 grep log -t INIT_TEST script ran successfully验证方法重启前务必做adb push init.test.sh /data/local/tmp/ adb shell chmod 755 /data/local/tmp/init.test.sh adb shell /data/local/tmp/init.test.sh adb shell getprop sys.boot.test_script # 应输出 1 adb shell cat /data/local/tmp/init_test.log # 应有时间戳记录 adb logcat -b main -t INIT_TEST # 应看到日志只有手动执行通过才能进入下一步——否则问题在脚本本身与 SELinux 无关。2. SELinux 策略为什么必须写.te文件当脚本被 init 启动时它不再以shell域运行而是以你为它单独定义的domain域运行。这个新 domain 默认没有任何权限连读取自己脚本文件都不被允许。这就是为什么“关闭 SELinux 就能跑通”的根本原因——setenforce 0绕过了所有策略检查。因此.te文件不是可选项而是强制要求。它的作用是明确定义这个新服务进程能做什么、能访问哪些资源。2.1 定义服务域与可执行文件类型新建test_service.te命名建议与服务名一致便于追踪# 定义服务进程的 domain执行时的上下文类型 type test_service, domain; # 定义脚本文件的 type文件被加载时的上下文类型 type test_service_exec, file_type, vendor_file_type, exec_type; # 允许 init 以该 domain 启动此服务关键 init_daemon_domain(test_service); # 允许 test_service 域读取、打开、获取属性、执行 test_service_exec 类型的文件 allow test_service test_service_exec:file { read open getattr execute }; # 允许 test_service 向 property_service 发送请求用于 setprop allow test_service property_service:property_service { set }; # 允许 test_service 向 logd 发送日志用于 log -t allow test_service logd:fd use; allow test_service logd:socket { connectto };关键说明init_daemon_domain(test_service)是宏它自动赋予test_service域基本 init 子进程能力如sys_ptrace,dac_override等省去大量手动 allowallow ... set是setprop必需的权限漏掉则属性设置失败且无提示logd权限非必需但强烈建议加上方便调试不要盲目取消注释permissive test_service;—— 它会让该域所有拒绝变为警告avc denied 日志仍会打印仅用于调试绝不可合入正式代码。2.2 将.te文件纳入编译体系不同平台存放位置略有差异常见路径如下平台推荐路径高通QCOMdevice/qcom/sepolicy/vendor/test_service.te联发科MTKdevice/mediatek/sepolicy/basic/non_plat/test_service.te通用 AOSPdevice/vendor/product/sepolicy/vendor/test_service.te验证是否生效编译后检查out/target/product/product/root/sepolicy是否包含test_service相关规则可用sesearch -A -s test_service检查。3. 文件上下文标注让系统知道“这是谁的文件”SELinux 不仅看进程域还看文件的security context安全上下文。即使策略写了allow test_service test_service_exec:file ...如果脚本文件本身的 context 不是test_service_exec这条规则也匹配不上。3.1 编辑file_contexts在对应平台的file_contexts文件中添加一行路径同.te文件所在目录/(system|vendor)/bin/init\.test\.sh u:object_r:test_service_exec:s0注意细节正则表达式需转义点号\., 否则init.test.sh会被误匹配为initXtestXsh路径前缀/system/bin/或/vendor/bin/必须与你实际存放脚本的位置一致s0是 MLS 级别Android 通常用s0无需修改即使你setenforce 0这行也必须加——因为 init 启动服务时仍会读取file_contexts来设置进程初始上下文。3.2 验证上下文是否正确刷机后用 adb 检查adb shell ls -Z /vendor/bin/init.test.sh # 正确输出应类似 # u:object_r:test_service_exec:s0 /vendor/bin/init.test.sh如果显示u:object_r:vendor_file:s0或其他类型说明file_contexts未生效或路径不匹配需重新编译或检查正则。4. init.rc 服务声明四要素一个都不能少init.rc中的服务声明是连接脚本、策略、上下文的最终一环。格式必须严格。4.1 标准 service 块写法service test_service /vendor/bin/init.test.sh class main user root group root oneshot seclabel u:object_r:test_service_exec:s0四要素解析service name path服务名与脚本绝对路径路径必须与file_contexts中标注的一致seclabel明确指定该服务以test_service_exec类型启动init 会据此查找test_service域策略user/group root确保有足够权限执行setprop等操作非 root 可能因 DAC 权限失败oneshot脚本执行完即退出适合一次性任务若需常驻请用disabledstart name触发。4.2 放在哪别动init.rc主文件芯片厂商通常提供扩展入口MTKinit.mtXXX.rc或init.project.rcQCOMinit.qcom.rc或init.vendor.rc通用init.product.rc正确做法将 service 块追加到对应扩展 rc 文件末尾。❌ 错误做法直接修改system/etc/init.rc会被 OTA 覆盖且违反分层设计。5. 排错实战从 avc denied 日志定位问题根源当脚本仍不执行时不要猜要看日志。SELinux 拒绝会生成avc denied记录它是唯一真相来源。5.1 抓取并过滤关键日志# 重启后立即执行越早越好避免日志被冲刷 adb shell dmesg | grep avc # 或持续监听 adb shell dmesg -w | grep avc典型错误日志示例及对应修复日志片段问题原因修复方案avc: denied { execute } for path/vendor/bin/init.test.sh devsda3 ino123456 scontextu:r:init:s0 tcontextu:object_r:vendor_file:s0 tclassfile permissive0脚本文件 context 错误应为test_service_exec检查file_contexts正则与路径重新刷机avc: denied { set } for propertysys.boot.test_script scontextu:r:test_service:s0 tcontextu:object_r:shell_prop:s0 tclassproperty_service缺少allow test_service property_service:property_service { set };在.te文件中补全该行avc: denied { open } for path/data/local/tmp/init_test.log ... tcontextu:object_r:shell_data_file:s0脚本试图写入/data/local/tmp但test_service域无权限添加allow test_service shell_data_file:dir { add_name };和allow test_service shell_data_file:file { create write append };avc: denied { getattr } for path/system/bin/sh ... tcontextu:object_r:shell_exec:s0解释器文件 context 不匹配或缺少对/system/bin/sh的读取权限添加allow test_service shell_exec:file { read open getattr execute };提示用audit2allow工具可半自动转换日志为策略语句需在 Linux 主机上运行adb shell dmesg | grep avc avc_log.txt # 传到电脑执行 audit2allow -i avc_log.txt -p out/target/product/product/root/sepolicy但请勿直接复制粘贴结果——理解每条 allow 的含义再精简加入.te文件。6. 最终验证清单五步确认法完成全部配置后按顺序执行以下五步任一环节失败即回溯对应章节手动执行验证adb shell /vendor/bin/init.test.sh→getprop sys.boot.test_script应返回1上下文验证adb shell ls -Z /vendor/bin/init.test.sh→ context 必须为test_service_exec策略验证adb shell sesearch -A -s test_service | grep -E (execute|set|property_service)→ 应看到对应 allow 规则服务状态验证adb shell getenforce→ 必须为Enforcing非Permissive重启后验证adb rebootadb wait-for-deviceadb shell getprop sys.boot.test_script→必须为1adb shell cat /data/local/tmp/init_test.log→应有重启后的时间戳只有全部通过才算真正解决了 SELinux 权限问题。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。