Android 系统运维:解决 update_engine 读取自定义路径 OTA 包报 Permission Denied (错误 -9)
完整文档指引,百度分享: pan.baidu.com/s/1cKttZc6E… 提取码:unvz
在 Android 系统定制开发中,我们经常需要修改 OTA 升级包的存放路径(例如将其下载到 /data/ 的自定义子目录下)。然而,在 User 版本的设备上进行系统升级时,可能会遇到升级失败并返回错误码 -9(通常代表 kDownloadStateInitializationError 或权限引发的初始化失败)的问题。
本文将记录如何通过分析 adb bugreport 日志,定位并修复由 SELinux 权限缺失导致的 update_engine 读取本地 OTA 包失败的问题。
一、 问题现象与日志分析
在 User 版本设备上触发 OTA 本地升级后,系统提示失败。为了排查根本原因,我们首先使用以下标准命令抓取设备的完整日志:
adb bugreport ota_bugreport.zip 解压并打开 bugreport 文件夹,定位到系统的 update_engine 核心日志文件(通常位于 /data/misc/update_engine_log)。在日志中发现了以下关键报错信息: [0622/113819.031671] [ERROR:file_stream.cc(-1)] unknown(...): Domain=system, code=EACCES, Message=Permission denied [0622/113819.032008] [ERROR:file_fetcher.cc(87)] Couldn't open /data/ 原因分析 从日志中可以看出,系统报了 EACCES (Permission denied) 错误。由于 update_engine 是一个拥有独立域(Domain)的高权限系统服务,即使用户层将升级包目录的 Linux 文件权限修改为了 777,如果没有在 SELinux 策略中显式放行,update_engine 依然无法打开并读取该路径下的大文件。 二、 解决方案:修正 SELinux 策略 针对此类自定义路径的权限阻断,我们需要在对应的厂商或者平台 sepolicy 策略中,为 update_engine 补齐相应的访问权限。 通过分析 update_engine 在高版本 Android 系统(如 Android 10+ 及更高版本)中的文件操作行为,它在读取本地 OTA 包(通常以 file 形式存在)时,不仅需要基础的 read、open 权限,还需要 map(内存映射)和 ioctl 权限来执行流式解析和块校验。 修改方案 找到你项目对应的设备或厂商 sepolicy 安全策略目录,修改 update_engine.te 文件:
在对应的 update_engine.te 配置文件中修改或补充
允许 update_engine 检索、打开并完全读取自定义 OTA 目录及文件
💡 关键点提示: • map 权限:高版本 Android 编译和运行策略中,update_engine 解析 zip 压缩包需要通过内核对文件进行内存映射,缺失 map 会直接引发 EACCES。 • ioctl 权限:用于保障文件流读取过程中的底层控制。
修改完成后重新编译系统并烧录system ,再次测试本地系统升级,update_engine 即可正常打开大包,升级顺利完成。
本文完。谢谢阅读!