Platform: RK3368
OS: Android 6.0
Kernel: 3.10.0
在做OTA增量更新时遇到更新失败,recovery中显示"Package expects build fingerprint of xxx"的错误信息.后来查看日志发现是之前的完整包更新时recovery分区没有升级成功,导致后来的版本增量更新时recovery的sha1与增量升级包中的不一致.
在recovery模式中升级完OTA更新包后,系统重启logcat中发现有升级recover分区失败的信息:
recovery: Installing new recovery image: failed
同时有selinux的权限警告日志:
01-21 14:24:40.330 216 216 W applypatch: type=1400 audit(0.0:8): avc: denied { read } for name="rknand_recovery" dev="tmpfs" ino=5621 scontext=u:r:install_recovery:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0
01-21 14:24:41.360 218 218 W applypatch: type=1400 audit(0.0:9): avc: denied { read } for name="rknand_recovery" dev="tmpfs" ino=5621 scontext=u:r:install_recovery:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0
01-21 14:24:41.360 218 218 W applypatch: type=1400 audit(0.0:10): avc: denied { read } for name="rknand_boot" dev="tmpfs" ino=5620 scontext=u:r:install_recovery:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0
原来在Recovery模式下OTA升级,只是更新了/system和/boot两个最核心的分区,Recovery自身并没有在那个时候得到更新。Recovery分区的更新是在重启进入Android系统时由flash_recovery服务执行install-recovery.sh来更新的。这样可以保证即使升级失败,Recovery模式也不会受到影响,仍然可以手动进入Recovery模式。
flash_recovery服务定义在init.rc中:
service flash_recovery /system/bin/install-recovery.sh
class main
oneshot
脚本内容是由Python脚本build/tools/releasetools/common.py在生成OTA更新包时生成的:
#!/system/bin/sh
if ! applypatch -c MTD:recovery:18464768:b8241d452c63a207fd807204ae995c13f4689aec; then
applypatch -b /system/etc/recovery-resource.dat MTD:boot:14680064:c47fa95673129794eca9c3f88b95dd861111334f MTD:recovery b8241d452c63a207fd807204ae995c13f4689aec 18464768 c47fa95673129794eca9c3f88b95dd861111334f:/system/recovery-from-boot.p && log -t recovery "Installing new recovery image: succeeded" || log -t recovery "Installing new recovery image: failed"
else
log -t recovery "Recovery image already installed"
fi
看脚本就知道,正真干活的是applypatch,代码位于bootable/recovery/applypatch
不扯远了,说重点.解决方法就是在sepolicy的file_contexts中添加对应的权限规则,
这样install_recovery就有权限访问boot_block_device和recovery_block_device:
/dev/block/rknand_boot u:object_r:boot_block_device:s0
/dev/block/rknand_recovery u:object_r:recovery_block_device:s0
/dev/block/platform/ff0f0000.rksdmmc/by-name/boot u:object_r:boot_block_device:s0
/dev/block/platform/ff0f0000.rksdmmc/by-name/recovery u:object_r:recovery_block_device:s0
不要根据audit的警告直接在sepolicy/install_recovery.te中添加allow权限:
allow install_recovery block_device:blk_file r_file_perms;
这样会编译不过的,因为在sepolicy/domain.te中定义了
neverallow { domain -kernel -init -recovery -vold -uncrypt } block_device:blk_file { open read write };

在使用RK3368平台,Android 6.0系统和3.10.0内核进行OTA增量更新时,遇到了recovery分区升级失败的问题,错误提示为'Package expects build fingerprint of xxx'。问题源于之前完整包更新时recovery分区未成功升级,导致后续增量更新匹配失败。升级过程中,selinux权限警告显示install-recovery.sh无法访问recovery_block_device。解决方案在于修改sepolicy的file_contexts,添加允许install-recovery访问boot_block_device和recovery_block_device的权限规则,而非直接在install_recovery.te中添加allow权限,因为这会导致编译错误。
2039

被折叠的 条评论
为什么被折叠?



