Android P recovery upgrade Map of '@ /cache/recovery/block Map 'failed problem analysis guide

Adnroid Precovery upgrade map of'@/cache/recovery/block Map 'failed problem analysis guide



preface

   since SELinux was added to Android in Android 4.4, although it is said to be secure, it often encounters some inexplicable problems in development. Today, this article is about the map of'@/cache/recovery/block Map 'failed cannot upgrade the problem.

Note: the code explained in this article is on the Android P Qualcomm 8953 platform.



I Problem replay

   with the android version upgrade, the upgrade package becomes larger and larger. When the upgrade package cannot be stored in the cache partition, the upgrade package will be downloaded to the data partition, and then upgraded from the data partition. Recently, when the upgrade package is loaded from the data partition, the following errors are encountered. This error can be found in /cache/recovery/last after the upgrade fails_ Log. The specific logs are as follows:

[    0.000179] __bionic_open_tzdata: couldn't find any tzdata when looking for Asia/Shanghai!
[    0.000238] Starting recovery (pid 387) on Thu Jan  1 05:28:26 1970
[    0.001760] recovery filesystem table
[    0.001783] =========================
[    0.001789]   0 /vendor ext4 /dev/block/platform/soc/7824900.sdhci/by-name/vendor 0
[    0.001794]   1 / ext4 /dev/block/bootdevice/by-name/system 0
[    0.001799]   2 /cache ext4 /dev/block/bootdevice/by-name/cache 0
[    0.001804]   3 /vendor ext4 /dev/block/bootdevice/by-name/vendor 0
[    0.001809]   4 /data ext4 /dev/block/bootdevice/by-name/userdata 0
[    0.001814]   5 /sdcard vfat /dev/block/mmcblk1p1 0
[    0.001819]   6 /boot emmc /dev/block/bootdevice/by-name/boot 0
[    0.001823]   7 /recovery emmc /dev/block/bootdevice/by-name/recovery 0
[    0.001828]   8 /misc emmc /dev/block/bootdevice/by-name/misc 0
[    0.001833]   9 /tmp ramdisk ramdisk 0
[    0.001837]
[    0.003088] I:Boot command: boot-recovery
[    0.003104] I:Got 3 arguments from boot message
[    0.047245] locale is [zh-CN]
[    0.047297] stage is []
[    0.047321] reason is [(null)]
[    0.047981] W:Failed to read max brightness: No such file or directory
[    0.048017] I:Screensaver disabled
[    0.049631] cannot find/open a drm device: No such file or directory
[    0.050030] fb0 reports (possibly inaccurate):
[    0.050049]   vi.bits_per_pixel = 32
[    0.050055]   vi.red.offset   =   0   .length =   8
[    0.050060]   vi.green.offset =   8   .length =   8
[    0.050065]   vi.blue.offset  =  16   .length =   8
[    0.064662] framebuffer: 0 (1920 x 1080)
[    0.515251]           erasing_text: zh (81 x 38 @ 5031)
[    0.527722]        no_command_text: zh (111 x 38 @ 5031)
[    0.538287]             error_text: zh (65 x 38 @ 5031)
[    0.993697]        installing_text: zh (222 x 38 @ 5922)
[    1.023212] SELinux: Loaded file_contexts
[    1.023333] Command: "/sbin/recovery" "--update_package=@/cache/recovery/block.map" "--locale=zh-CN"
[    1.152498] I:Update location: @/cache/recovery/block.map
[    1.152563] Opening update package...
[    1.185800] E:Failed to read /cache/recovery/block.map: No such file or directory
[    1.202350] E:Map of '@/cache/recovery/block.map' failed
[    1.235591] E:failed to map file
[    1.280567] W:Failed to read /sys/class/thermal/thermal_zone53/temp: Invalid argument
[    1.280665] W:Failed to read /sys/class/thermal/thermal_zone52/temp: Invalid argument
[    1.280730] W:Failed to read /sys/class/thermal/thermal_zone51/temp: Invalid argument
[    1.280872] W:Failed to read /sys/class/thermal/thermal_zone49/temp: No such device
[    1.280936] W:Failed to read /sys/class/thermal/thermal_zone48/temp: No such device
[    1.281001] W:Failed to read /sys/class/thermal/thermal_zone47/temp: No such device
[    1.281064] W:Failed to read /sys/class/thermal/thermal_zone46/temp: Invalid argument
[    1.281127] W:Failed to read /sys/class/thermal/thermal_zone45/temp: Invalid argument
[    1.287659] I:current maximum temperature: 90000
[    1.287840] I:@/cache/recovery/block.map
[    1.287866] I:0
[    1.287889] I:time_total: 0
[    1.287911] I:retry: 0
[    1.287933] I:error: 26
[    1.287955] I:uncrypt_time: 0
[    1.287977] I:uncrypt_error: 117
[    1.287999] I:temperature_start: 90000
[    1.288021] I:temperature_end: 90000
[    1.288043] I:temperature_max: 90000
[    1.288065] I:
[    1.288093] Installation aborted.
[    1.303354] Mounted /cache/xxx-recovery
[    1.336868] mkdir /cache/xxx-recovery error[File exists]
[    1.356593] Recovery install reason=update_package result=fail on Thu Jan  1 05:28:27 1970
[    1.356622]  !
[    6.421470] I:Saving locale "zh-CN"

The key points are as follows:

[    1.185800] E:Failed to read /cache/recovery/block.map: No such file or directory
[    1.202350] E:Map of '@/cache/recovery/block.map' failed
[    1.235591] E:failed to map file

Check whether the file exists in the terminal cache partition according to the key point information. The results are as follows:

130|msm8953_64:/cache/recovery # ls -l
total 448
-rw------- 1 root   root      277 2020-05-12 17:48 block.map
-rw-r--r-- 1 root   root      271 1970-01-02 15:42 last_install
-rw------- 1 system system 368240 1970-01-02 15:42 last_kmsg
-rw------- 1 root   root        5 1970-01-02 15:42 last_locale
-rw------- 1 system system     38 2020-05-12 17:47 uncrypt_file

If it does not exist, this is the key to the problem.



II Problem solving

   we trace the log information before restarting and entering recovery, and view it through logcat -b events | grep avc. The log is as follows:

[ 1212.869820@3] type=1400 audit(1209.144:3355): avc: denied { setattr } for pid=4433 comm="Thread-3" name="uncrypt_file" dev="mmcblk0p32" ino=13 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_recovery_file:s0 tclass=file permissive=0
[ 1212.885402@3] type=1400 audit(1212.820:3356): avc: denied { getattr } for pid=4501 comm="uncrypt" path="/data/cache" dev="mmcblk0p65" ino=19 scontext=u:r:uncrypt:s0 tcontext=u:object_r:cache_file:s0 tclass=dir permissive=0
[ 1212.906032@2] watchdogd: watchdogd started (interval 10, margin 20)!
[ 1212.906143@2] watchdogd: Failed to open /dev/watchdog: No such file or directory

It is obvious from the log that SELinux permissions are encountered when processing /data and /cache partitions. (mmcblk0p32 and mmcblk0p65 correspond to cache and data partitions respectively). The corresponding relationship can be queried in the following ways under the terminal:

130|msm8953_64:/dev/block/by-name # ls  -l | grep cache
lrwxrwxrwx 1 root root 21 1970-01-01 08:00 cache -> /dev/block/mmcblk0p32
msm8953_64:/dev/block/by-name # ls  -l | grep data
lrwxrwxrwx 1 root root 21 1970-01-01 08:00 userdata -> /dev/block/mmcblk0p65
msm8953_64:/dev/block/by-name #

It's easy to find the root cause of the problem. We only need to give the corresponding SELinux permission to the upgraded application and recovery. However, when we encounter the SELinux permission above, we don't continue. We need to know all the required SELinux permissions. Then we set SELinux to the permission state, and then upgrade it again. We observe the log state:

[   98.295965@1] type=1400 audit(84.812:43): avc: denied { open } for pid=2890 comm="HwBinder:2890_1" path="/sys/module/tvin_hdmirx/parameters/en_4k_2_2k" dev="sysfs" ino=6874 scontext=u:r:system_control:s0 tcontext=u:object_r:sysfs_cec:s0 tclass=file permissive=1
[   98.313718@1] type=1400 audit(98.244:44): avc: denied { remove_name } for pid=4076 comm="Thread-4" name="update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_file:s0 tclass=dir permissive=1
[   98.333696@1] type=1400 audit(98.244:44): avc: denied { remove_name } for pid=4076 comm="Thread-4" name="update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_file:s0 tclass=dir permissive=1
[   98.353378@1] type=1400 audit(98.244:45): avc: denied { unlink } for pid=4076 comm="Thread-4" name="update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[   98.373096@1] type=1400 audit(98.244:45): avc: denied { unlink } for pid=4076 comm="Thread-4" name="update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[   98.392458@1] type=1400 audit(98.304:46): avc: denied { read } for pid=4076 comm="Thread-4" path="/data/cache/update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[   98.618368@2] success set parent gpu_p1_composite rate to 500000000
[   99.302385@1] success set parent gpu_p0_composite rate to 400000000
[  100.074360@1] success set parent gpu_p1_composite rate to 285714285
[  101.234329@3] success set parent gpu_p0_composite rate to 125000000
[  101.344037@0] aml_snd_card_tv aml_snd_tv: I2S playback disable
[  101.344244@0] aml_snd_card_tv aml_snd_tv: IEC958 playback disable
[  120.075238@1] type=1400 audit(98.304:46): avc: denied { read } for pid=4076 comm="Thread-4" path="/data/cache/update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[  120.090346@1] type=1400 audit(120.024:47): avc: denied { setattr } for pid=4076 comm="Thread-4" name="uncrypt_file" dev="mmcblk0p32" ino=13 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_recovery_file:s0 tclass=file permissive=1
[  121.326417@0] success set parent gpu_p1_composite rate to 666666666
[  121.734307@0] success set parent gpu_p0_composite rate to 500000000
[  121.897440@1] BT_RADIO going: off
[  121.897470@1] BCM_BT: going OFF
[  122.342361@2] success set parent gpu_p1_composite rate to 400000000
[  123.438484@0] success set parent gpu_p0_composite rate to 285714285
[  123.556904@1] type=1400 audit(120.024:47): avc: denied { setattr } for pid=4076 comm="Thread-4" name="uncrypt_file" dev="mmcblk0p32" ino=13 scontext=u:r:system_app:s0 tcontext=u:object_r:cache_recovery_file:s0 tclass=file permissive=1
[  123.572107@1] type=1400 audit(123.508:48): avc: denied { getattr } for pid=4211 comm="uncrypt" path="/data/cache" dev="mmcblk0p65" ino=19 scontext=u:r:uncrypt:s0 tcontext=u:object_r:cache_file:s0 tclass=dir permissive=1
[  123.591568@1] type=1400 audit(123.508:48): avc: denied { getattr } for pid=4211 comm="uncrypt" path="/data/cache" dev="mmcblk0p65" ino=19 scontext=u:r:uncrypt:s0 tcontext=u:object_r:cache_file:s0 tclass=dir permissive=1
[  123.610598@1] type=1400 audit(123.508:49): avc: denied { getattr } for pid=4211 comm="uncrypt" path="/data/cache/update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:uncrypt:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[  123.631453@1] type=1400 audit(123.508:49): avc: denied { getattr } for pid=4211 comm="uncrypt" path="/data/cache/update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:uncrypt:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[  123.652217@1] type=1400 audit(123.512:50): avc: denied { read } for pid=4211 comm="uncrypt" name="update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:uncrypt:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[  123.672583@1] type=1400 audit(123.512:50): avc: denied { read } for pid=4211 comm="uncrypt" name="update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:uncrypt:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[  123.689809@1] type=1400 audit(123.512:51): avc: denied { open } for pid=4211 comm="uncrypt" path="/data/cache/update.zip" dev="mmcblk0p65" ino=316 scontext=u:r:uncrypt:s0 tcontext=u:object_r:cache_file:s0 tclass=file permissive=1
[  124.950389@3] success set parent gpu_p1_composite rate to 125000000

   this is simple. You can add the corresponding SELinux rules. For learning about SELinux, please refer to the blog Getting started with Android SELinux Development Guide , the rules of SELinux will not be described in detail here. The modified git submission record is attached:

diff --git a/device/qcom/sepolicy/private/xxxdroid_share_file.te b/device/qcom/sepolicy/private/xxxdroid_share_file.te
index ea24edb..72f043d 100755
--- a/device/qcom/sepolicy/private/xxxdroid_share_file.te
+++ b/device/qcom/sepolicy/private/xxxdroid_share_file.te
@@ -31,5 +31,11 @@ allow PortPlugInit11 xxxdroid_share_file:file { create write setattr relabelfrom
 allow { auth_bpadownload posprintupdate} xxxdroid_share_file:dir { open search write create add_name remove_name setattr relabelfrom relabelto append unlink link rename getattr};
 allow { auth_bpadownload posprintupdate} xxxdroid_share_file:file { create write setattr relabelfrom relabelto append  rename open getattr read lock };
 
-allow {zygote bluetooth} xxxdroid_share_file:file {rw_file_perms};
-allow {zygote bluetooth} xxxdroid_share_file:dir {rw_dir_perms};
+allow {zygote bluetooth uncrypt} xxxdroid_share_file:file {rw_file_perms};
+allow {zygote bluetooth uncrypt} xxxdroid_share_file:dir {rw_dir_perms};
+
+allow system_app cache_file:dir { search add_name remove_name write };
+allow system_app cache_file:file { create getattr open write unlink read };
+
+allow uncrypt cache_file:dir getattr;
+allow uncrypt cache_file:file { open read getattr };

Where xxxdroid_ Share_ File Te is the policy file we added. If children's boots really encounter this problem, please add the policy according to the actual situation. OK, compile the policy file and try again. OK. See the successful upgrade records of recovery as follows. In /cache/recovery/last_log. There are too many contents. I only intercepted some.

[    0.000181] __bionic_open_tzdata: couldn't find any tzdata when looking for Asia/Shanghai!
[    0.000238] Starting recovery (pid 383) on Fri Jan  2 07:41:18 1970
[    0.001824] recovery filesystem table
[    0.001851] =========================
[    0.001857]   0 /vendor ext4 /dev/block/platform/soc/7824900.sdhci/by-name/vendor 0
[    0.001862]   1 / ext4 /dev/block/bootdevice/by-name/system 0
[    0.001867]   2 /cache ext4 /dev/block/bootdevice/by-name/cache 0
[    0.001872]   3 /vendor ext4 /dev/block/bootdevice/by-name/vendor 0
[    0.001877]   4 /data ext4 /dev/block/bootdevice/by-name/userdata 0
[    0.001882]   5 /sdcard vfat /dev/block/mmcblk1p1 0
[    0.001886]   6 /boot emmc /dev/block/bootdevice/by-name/boot 0
[    0.001891]   7 /recovery emmc /dev/block/bootdevice/by-name/recovery 0
[    0.001896]   8 /misc emmc /dev/block/bootdevice/by-name/misc 0
[    0.001901]   9 /tmp ramdisk ramdisk 0
[    0.001905]
[    0.003103] I:Boot command: boot-recovery
[    0.003121] I:Got 3 arguments from boot message
[    0.057346] locale is [zh-CN]
[    0.057379] stage is []
[    0.057385] reason is [(null)]
[    0.057390] W:Failed to read max brightness: No such file or directory
[    0.057395] I:Screensaver disabled
[    0.058859] cannot find/open a drm device: No such file or directory
[    0.059139] fb0 reports (possibly inaccurate):
[    0.059150]   vi.bits_per_pixel = 32
[    0.059156]   vi.red.offset   =   0   .length =   8
[    0.059161]   vi.green.offset =   8   .length =   8
[    0.059166]   vi.blue.offset  =  16   .length =   8
[    0.072937] framebuffer: 0 (1920 x 1080)
[    0.521428]           erasing_text: zh (81 x 38 @ 5031)
[    0.533880]        no_command_text: zh (111 x 38 @ 5031)
[    0.544223]             error_text: zh (65 x 38 @ 5031)
[    0.998365]        installing_text: zh (222 x 38 @ 5922)
[    1.029506] SELinux: Loaded file_contexts
[    1.029631] Command: "/sbin/recovery" "--update_package=@/cache/recovery/block.map" "--locale=zh-CN"
[   88.676745] wrote 129279 blocks; expected 129279
[   88.676811] stashed 0 blocks
[   88.676840] max alloc needed was 4096
[   88.676930] deleting stash 34a21d3b3dc53f7084ea0b7f275c179b3062f9be
[   90.216571] Patching firmware images...
[   90.217492] prepare_partitions: Preparing for primary partition update
[   90.217700] 'apdp' partition not backup - skip safe update
[   90.217744] 'keystore' partition not backup - skip safe update
[   90.217795] 'msadp' partition not backup - skip safe update
[   90.217825] 'mdtp' partition not backup - skip safe update
[   90.217860] 'dsp' partition not backup - skip safe update
[   90.375081] prepare_partitions: Preparing for backup partition update
[   90.543922] prepare_partitions: Finalizing partitions
[   90.601289]
[   90.854443] W:Failed to read /sys/class/thermal/thermal_zone53/temp: Invalid argument
[   90.854541] W:Failed to read /sys/class/thermal/thermal_zone52/temp: Invalid argument
[   90.854606] W:Failed to read /sys/class/thermal/thermal_zone51/temp: Invalid argument
[   90.854752] W:Failed to read /sys/class/thermal/thermal_zone49/temp: No such device
[   90.854818] W:Failed to read /sys/class/thermal/thermal_zone48/temp: No such device
[   90.854883] W:Failed to read /sys/class/thermal/thermal_zone47/temp: No such device
[   90.854946] W:Failed to read /sys/class/thermal/thermal_zone46/temp: Invalid argument
[   90.855009] W:Failed to read /sys/class/thermal/thermal_zone45/temp: Invalid argument
[   90.861607] I:current maximum temperature: 90277
[   90.861798] I:@/cache/recovery/block.map
[   90.861823] I:1
[   90.861846] I:time_total: 89
[   90.861868] I:retry: 0
[   90.861890] I:target_build: 57
[   90.861913] I:bytes_written_system: 1574789120
[   90.861935] I:bytes_stashed_system: 0
[   90.861956] I:bytes_written_vendor: 529526784
[   90.861978] I:bytes_stashed_vendor: 0
[   90.862000] I:uncrypt_time: 20
[   90.862022] I:temperature_start: 90555
[   90.862043] I:temperature_end: 90277
[   90.862065] I:temperature_max: 90555
[   90.862087] I:
[   90.862308] Mounted /cache/xxx-recovery
[   90.882512] mkdir /cache/xxx-recovery error[File exists]
[   90.902829] Recovery install reason=update_package result=success on Fri Jan  2 07:42:48 1970
[   90.902859]  !
[   90.948791] I:Saving locale "zh-CN"

After the upgrade succeeds, the directory structure of /cache/recovery is as follows:

msm8953_64:/cache/recovery # ls -l
total 448
-rw------- 1 root   root      277 2020-05-12 17:48 block.map
-rw-r--r-- 1 root   root      271 1970-01-02 15:42 last_install
-rw------- 1 system system 368240 1970-01-02 15:42 last_kmsg
-rw------- 1 root   root        5 1970-01-02 15:42 last_locale
-rw-r----- 1 root   root    49067 1970-01-02 15:42 last_log
-rw------- 1 system system     38 2020-05-12 17:47 uncrypt_file


epilogue

   well, there's nothing more to say about this problem. I emphasize that if you really encounter this problem, you must check the permission problem step by step through logcat -b events | grep avc, and then add the corresponding permission.



Write at the end

  dear readers, Android P recovery upgrade Map of '@ /cache/recovery/block The map 'failed problem analysis guide has been completed. I won't say much more. At the end, please readers, if this article is helpful to you, pay attention to and praise it. Of course, if there are mistakes and deficiencies, you can also pat bricks.

Posted by gavin101 on Wed, 01 Jun 2022 11:01:53 +0530