Closed aaronfhamilton closed 1 month ago
This seems awful similar to #325. Could you verify what version of avbroot you are running on what OS?
Ah, yes using export TMPDIR=/tmp
seemed to get past that error. Now I'm getting a "No compatible boot image found for OtaCertPatcher"
I'm guessing I should be using avbroot-3.41.-x86_64-unknown-linux-gnu.zip?
I'm guessing I should be using avbroot-3.41.-x86_64-unknown-linux-gnu.zip?
I think that would be better, but I don't think that is the cause of your new issue. What device are you trying to run avbroot for?
Generic AI Box from Carlinkit. This is the build.prop from the extracted system image:
####################################
# from generate-common-build-props
# These properties identify this partition image.
####################################
ro.product.system.brand=qti
ro.product.system.device=sdm660_64
ro.product.system.manufacturer=QUALCOMM
ro.product.system.model=sdm660 for arm64
ro.product.system.name=sdm660_64
ro.system.product.cpu.abilist=arm64-v8a,armeabi-v7a,armeabi
ro.system.product.cpu.abilist32=armeabi-v7a,armeabi
ro.system.product.cpu.abilist64=arm64-v8a
ro.system.build.date=Tue May 7 17:10:10 CST 2024
ro.system.build.date.utc=1715073010
ro.system.build.fingerprint=qti/sdm660_64/sdm660_64:13/S10A_123/jiangds05071710:user/release-keys
ro.system.build.id=S10A_123
ro.system.build.tags=release-keys
ro.system.build.type=user
ro.system.build.version.incremental=eng.jiangd.20240507.171242
ro.system.build.version.release=13
ro.system.build.version.release_or_codename=13
ro.system.build.version.sdk=33
####################################
# from out/target/product/sdm660_64/obj/PACKAGING/system_build_prop_intermediates/buildinfo.prop
####################################
# begin build properties
# autogenerated by buildinfo.sh
ro.build.id=S10A_123
ro.build.keys=release-keys
ro.build.display.id=SC218-T6.00.05
ro.build.version.incremental=eng.jiangd.20240507.171242
ro.build.version.sdk=33
ro.boot.oem.pkg=X13-NA-00-00
ro.build.version.preview_sdk=0
ro.build.version.preview_sdk_fingerprint=REL
ro.build.version.codename=REL
ro.build.version.all_codenames=REL
ro.build.version.known_codenames=Base,Base11,Cupcake,Donut,Eclair,Eclair01,EclairMr1,Froyo,Gingerbread,GingerbreadMr1,Honeycomb,HoneycombMr1,HoneycombMr2,IceCreamSandwich,IceCreamSandwichMr1,JellyBean,JellyBeanMr1,JellyBeanMr2,Kitkat,KitkatWatch,Lollipop,LollipopMr1,M,N,NMr1,O,OMr1,P,Q,R,S,Sv2,Tiramisu
ro.build.version.release=13
ro.build.version.release_or_codename=13
ro.build.version.release_or_preview_display=13
ro.build.version.security_patch=2022-12-05
ro.build.version.base_os=
ro.build.version.min_supported_target_sdk=23
ro.build.date=Tue May 7 17:10:10 CST 2024
ro.build.date.utc=1715073010
ro.build.type=user
ro.build.user=jiangds
ro.build.host=hello-PowerEdge-T440
ro.build.tags=release-keys
ro.build.flavor=sdm660_64-user
# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,
# use ro.product.cpu.abilist instead.
ro.product.cpu.abi=arm64-v8a
ro.wifi.channels=
# Do not try to parse thumbprint
# set ro.build.oem.name chelianyi-led
ro.board.reverse.custom=chelianyi-led
ro.build.oem.name=chelianyi-led
ro.build.box.hardware.id=1
persist.sys.oem.brand=Tbox Ambient
persist.sys.show.loading=true
ro.sys.has.navibar=true
ro.build.version.release=13
ro.product.locale=en-US
persist.hotspot.wifi.not.only=0
# begin fota properties
ro.fota.platform=SC218
ro.fota.type=box
ro.fota.oem=Yunlian-Y
ro.fota.device=CPC200-Tbox-Ambient
ro.fota.version=X13-SC218-58 A13 2024-05-07 17:07
ro.fota.product.id=1697705429
ro.fota.secret.id=5e6ac22c30564532906ecb829d8ecd8a
# end fota properties
# end build properties
####################################
# from device/qcom/sdm660_64/system.prop
####################################
#
# system.prop for sdm660
#
#rild.libpath=/system/lib/libreference-ril.so
rild.libpath=/system/vendor/lib64/libril-qc-qmi-1.so
#rild.libargs=-d /dev/smd0
persist.rild.nitz_plmn=
persist.rild.nitz_long_ons_0=
persist.rild.nitz_long_ons_1=
persist.rild.nitz_long_ons_2=
persist.rild.nitz_long_ons_3=
persist.rild.nitz_short_ons_0=
persist.rild.nitz_short_ons_1=
persist.rild.nitz_short_ons_2=
persist.rild.nitz_short_ons_3=
ril.subscription.types=NV,RUIM
DEVICE_PROVISIONED=1
#
# Set network mode to (T/L/G/W/1X/EVDO, T/G/W/L) for 7+5 mode device on DSDS mode
#
ro.telephony.default_network=31,31
debug.sf.enable_hwc_vds=1
debug.sf.hw=1
debug.sf.latch_unsignaled=1
debug.gralloc.enable_fb_ubwc=1
dalvik.vm.heapsize=36m
dev.pm.dyn_samplingrate=1
ro.config.media_vol_default=15
ro.config.vc_call_vol_default=7
ro.config.alarm_vol_default=15
ro.config.system_vol_default=15
persist.demo.hdmirotationlock=false
#Disable Skip Validate
sdm.debug.disable_skip_validate=1
#Property to enable display default color mode
vendor.display.enable_default_color_mode=1
# Display Properties as per treble compliance
vendor.gralloc.enable_fb_ubwc=1
vendor.display.disable_skip_validate=1
#ro.hdmi.enable=true
#
# system props for the cne module
#
persist.vendor.cne.feature=1
#system props for the MM modules
media.stagefright.enable-player=true
media.stagefright.enable-http=true
media.stagefright.enable-aac=true
media.stagefright.enable-qcp=true
media.stagefright.enable-scan=true
mmp.enable.3g2=true
media.aac_51_output_enabled=true
media.settings.xml=/vendor/etc/media_profiles_vendor.xml
#codecs:(PARSER_)AAC AC3 AMR_NB AMR_WB ASF AVI DTS FLV 3GP 3G2 MKV MP2PS MP2TS MP3 OGG QCP WAV FLAC AIFF APE DSD
vendor.mm.enable.qcom_parser=13631487
persist.mm.enable.prefetch=true
#prefer HW codec over SW for thumbnail
media.stagefright.thumbnail.prefer_hw_codecs=true
#property to enable narrow search range for video encoding
vidc.enc.target_support_bframe=1
vendor.vidc.enc.disable_bframes=1
vendor.vidc.dec.enable.downscalar=1
# enable PQ feature by default
vendor.vidc.enc.disable.pq=false
# Additional buffers shared between Camera and Video
vidc.enc.dcvs.extra-buff-count=2
#
# system props for the data modules
#
ro.vendor.use_data_netmgrd=true
persist.vendor.data.mode=concurrent
#system props for time-services
persist.timed.enable=true
# System property for cabl
ro.qualcomm.cabl=2
ro.vendor.display.cabl=2
#
# System props for telephony
# System prop to turn on CdmaLTEPhone always
telephony.lteOnCdmaDevice=1
#Simulate sdcard on /data/media
#
persist.fuse_sdcard=true
#
#snapdragon value add features
#
#minimum duration for offload playback in secs
audio.offload.min.duration.secs=30
#enable offload audio video playback by default
audio.offload.video=true
#enable music through deep buffer
audio.deep_buffer.media=true
#set AudioFlinger client heap size
ro.af.client_heap_size_kbyte=7168
#system prop for RmNet Data
persist.data.df.dev_name=rmnet_usb0
#
# system property determining camera HAL to be used for a Video call
#
# 1 is camera1
# 2 or anything else is camera2
persist.radio.VT_CAM_INTERFACE=2
#property to enable user to access Google WFD settings
persist.debug.wfd.enable=1
#Enable stm-events
persist.debug.coresight.config=stm-events
##property to choose between virtual/external wfd display
persist.sys.wfd.virtual=0
# system prop for NFC DT
ro.nfc.port=I2C
ro.build.selinux=1
#hwui properties
ro.hwui.texture_cache_size=72
ro.hwui.layer_cache_size=48
ro.hwui.r_buffer_cache_size=8
ro.hwui.path_cache_size=32
ro.hwui.gradient_cache_size=1
ro.hwui.drop_shadow_cache_size=6
ro.hwui.texture_cache_flushrate=0.4
ro.hwui.text_small_cache_width=1024
ro.hwui.text_small_cache_height=1024
ro.hwui.text_large_cache_width=2048
ro.hwui.text_large_cache_height=2048
#Bringup properties
persist.vendor.radio.atfwd.start=true
#property to enable VDS WFD solution
persist.hwc.enable_vds=1
#Settings to enable sensors
#Device Orientation sensor
ro.vendor.sensors.dev_ori=true
#Persistent Motion Detector
ro.vendor.sensors.pmd=true
#Stationary Detector
ro.vendor.sensors.sta_detect=true
#Motion Detector
ro.vendor.sensors.mot_detect=true
#Expose aux camera for below packages
vendor.camera.aux.packagelist=org.codeaurora.snapcam
#Whitelisting the below packages
persist.vendor.camera.privapp.list=org.codeaurora.snapcam
persist.camera.privapp.list=org.codeaurora.snapcam
#disable UBWC for camera
persist.vendor.camera.preview.ubwc=0
#set maximum supported adapter voltage
persist.chg.max_volt_mv=9000
#system prop for Bluetooth
ro.bluetooth.library_name=libbluetooth_qti.so
# Property for backup NTP Server
persist.backup.ntpServer="0.pool.ntp.org"
# enable IZat OptInApp overlay
persist.vendor.overlay.izat.optin=rro
# Add Airplane attribute by Guoyanbo for JIRA MC0310-468
sys.sleep.test.ready=false
ro.boot.ftmode=true
#Set reading BT MAC from NV JIRA:MC0310-382
persist.vendor.bluetooth.modem_nv_support=true
####################################
# from variable ADDITIONAL_SYSTEM_PROPERTIES
####################################
ro.treble.enabled=true
ro.actionable_compatible_property.enabled=true
ro.postinstall.fstab.prefix=/system
ro.secure=1
security.perf_harden=1
ro.adb.secure=0
ro.allow.mock.location=0
ro.debuggable=0
dalvik.vm.lockprof.threshold=500
net.bt.name=Android
ro.vendor.qti.va_aosp.support=1
persist.vendor.ssr.restart_level=ALL_ENABLE
####################################
# from variable PRODUCT_SYSTEM_PROPERTIES
####################################
debug.atrace.tags.enableflags=0
persist.traced.enable=1
dalvik.vm.image-dex2oat-Xms=64m
dalvik.vm.image-dex2oat-Xmx=64m
dalvik.vm.dex2oat-Xms=64m
dalvik.vm.dex2oat-Xmx=512m
dalvik.vm.usejit=true
dalvik.vm.usejitprofiles=true
dalvik.vm.dexopt.secondary=true
dalvik.vm.dexopt.thermal-cutoff=2
dalvik.vm.appimageformat=lz4
ro.dalvik.vm.native.bridge=0
pm.dexopt.first-boot=verify
pm.dexopt.boot-after-ota=verify
pm.dexopt.post-boot=extract
pm.dexopt.install=speed-profile
pm.dexopt.install-fast=skip
pm.dexopt.install-bulk=speed-profile
pm.dexopt.install-bulk-secondary=verify
pm.dexopt.install-bulk-downgraded=verify
pm.dexopt.install-bulk-secondary-downgraded=extract
pm.dexopt.bg-dexopt=speed-profile
pm.dexopt.ab-ota=speed-profile
pm.dexopt.inactive=verify
pm.dexopt.cmdline=verify
pm.dexopt.shared=speed
dalvik.vm.dex2oat-resolve-startup-strings=true
dalvik.vm.dex2oat-max-image-block-size=524288
dalvik.vm.minidebuginfo=true
dalvik.vm.dex2oat-minidebuginfo=true
dalvik.vm.madvise.vdexfile.size=104857600
dalvik.vm.madvise.odexfile.size=104857600
dalvik.vm.madvise.artfile.size=4294967295
####################################
# from variable PRODUCT_SYSTEM_DEFAULT_PROPERTIES
####################################
# end of file
Any chance you know of an alternate place to download the OTA?
It looks like they throttle downloads from https://www.carlinkit.com/download.html to exactly 200Kbps for me.
(If not, no worries! I can take a look tomorrow when the download finishes.)
Thanks, got it! 30 seconds much better than a few hours. Taking a look now.
The issue is that the OTA doesn't contain a recovery
image. Without that, avbroot can't patch the OTA verification certificate stored in it, so sideloading OTAs signed by your own keys wouldn't be possible.
Since the OTA is incomplete, I don't think there's much you can do, unfortunately.
Does it possibly use boot and system_ext (or something else) to make the recovery image?
Here is the recovery partition as read using QFIL after applying the update:
https://drive.google.com/file/d/14_zigxxg2mdyk7HFo2DvDP9XzYN_bglB/view?usp=drive_link
Thanks for uploading the recovery image. Is it a completely unmodified image?
If it's unmodified and recovery mode actually boots while the bootloader is locked, then I think signature verification is broken on your device. You wouldn't gain any additional security by using avbroot vs. just leaving the bootloader unlocked.
Details:
The AVB metadata of recovery
itself lists this version number and checksum:
$ footer=$(grep -boa AVBf recovery.bin | cut -d: -f1)
$ cp recovery.bin recovery.bin.2
$ truncate -s $((footer + 64)) recovery.bin.2
$ avbroot avb info -i recovery.bin.2
...
hash_algorithm: "sha256",
partition_name: "recovery",
salt: "55b0f1b9a3f090af8c1758331be5b691432626518de7a1e3924851149dc9c99e",
root_digest: "466b7938a4f780bcc455985da976cf278e94c8f32df8e68c3e4e4e7355353f59",
...
key: "com.android.build.recovery.fingerprint",
value: "qti/sdm660_64/sdm660_64:13/S10A_123/zhangzy07121100:user/release-keys",
...
(I had to chop of a bunch of excess 0's at the end of the file. If those weren't added by QFIL and the partition is actually like that, then it's yet another way that things are broken on this device.)
However, the AVB metadata of vbmeta
from the OTA lists a different version number and checksum for recovery
:
$ avbroot ota extract -i sdm660_update.zip -d extracted -a
$ avbroot avb info -i extracted/vbmeta.img
...
key: "com.android.build.recovery.fingerprint",
value: "qti/sdm660_64/sdm660_64:13/S10A_123/jiangds05071710:user/release-keys",
...
hash_algorithm: "sha256",
partition_name: "recovery",
salt: "8ad31065a5a845c31c11b1bb47c41d2f134403105816578af3d21ce036289a36",
root_digest: "156518a41536f193ec924f67f3a17fce71afb18a5e088325bfd93280b45d34fa",
...
vbmeta
is what the bootloader actually uses to verify the signatures of all the partitions. This shouldn't be able to boot.
Does it possibly use boot and system_ext (or something else) to make the recovery image?
It doesn't look like it. I searched for various strings from your recovery image, like zhangzy07121100
, and they don't appear in any of the other partitions.
As far as I'm aware, it should be unmodified. Here is a separate recovery image that was provided by the vendor for QFIL recovery: https://drive.google.com/file/d/14epN_MlxeS2t0QTb1UVEmo_NChECPJn8/view?usp=drive_link
Not sure if related at all, but the device does have funky behavior where it states "device not activated" after flashing with QFIL until it gets an internet connection.
Ah, yep, that file no longer has the extra 0's at the end of the file, but is otherwise identical to the previous recovery image you uploaded.
I took a further look and it definitely seems like this OEM doesn't care about security at all.
vbmeta
image is signed by: https://android.googlesource.com/platform/external/avb/+/refs/heads/main/test/data/testkey_rsa4096.pemThese private keys are all publicly available and should never be used. Given that and the fact that the recovery
image doesn't match the checksums in vbmeta
, I highly doubt that the bootloader is properly implemented and verifying anything.
Not sure if related at all, but the device does have funky behavior where it states "device not activated" after flashing with QFIL until it gets an internet connection.
This comes from /system/app/CarDataManager/CarDataManager.apk
. I didn't dig deeply into it, but I have no idea why QFIL would have any impact. Anyway, I think you can bypass it and avoid sending data to their servers by running this as root:
setprop persist.chelianyi.activate.state 1
Yes, most the Chinese CarPlay based "AI Box" devices all use the keys from the Google repos. Nice find on the CarDataManager.apk, especially considering I just posted it yesterday.
Could avbroot be tricked into working I placed the recovery.img into the build/payload
folder and modified manifest.json
to include "recovery" in "partsToUpdate" field?
Could avbroot be tricked into working I placed the recovery.img into the
build/payload
folder and modifiedmanifest.json
to include "recovery" in "partsToUpdate" field?
I'm not familiar with this manifest.json
you're referring to. Can you send me a link to the tool that processes this file?
Oops, was looking at the wrong folder. There is no manifest.json
.
Is it possible the recovery partition isn't used since it's an A/B device (or tries to be), and that recovery partition is unused? I'm seeing in the Google A/B docs (https://source.android.com/docs/core/ota/ab/ab_implement#partitions), the recovery is now contained in boot.img.
The recovery program (/system/bin/recovery
) could exist in boot
, vendor_boot
(most common nowadays), or recovery
. This particular device doesn't put it in boot
though.
Does it use update_engine
instead of /system/bin/recovery
by chance?
update_engine
is the tool that installs the contents of payload.bin
into the actual partitions. Recovery mode runs that (and Android does too if the device has an A/B OTA updater app).
By the way, I'm looking to see if I can easily implement avbroot payload {pack,unpack}
commands so that you can manually add your recovery.img
into payload.bin
before patching it with avbroot ota patch
.
What would be awesome!!
I just merged #331 and released version 3.5.0 with the change. Can you give this a try?
Extract payload.bin
from the OTA:
unzip sdm660_update.zip payload.bin
Unpack the payload binary:
avbroot payload unpack -q -i payload.bin
Copy your recovery.img
to payload_images/recovery.img
. Make sure you use the one without the extra zeros at the end of the file. You can check if it is valid by running:
avbroot avb info -i recovery.img
(The bad one will fail with an error.)
Edit payload.toml
and add an entry for recovery
to the end (the order doesn't matter):
[[manifest.partitions]]
partition_name = "recovery"
Pack a new payload binary. It doesn't matter which key you use since it'll get re-signed later anyway.
mv payload.bin payload.bin.orig
avbroot payload pack -q -o payload.bin -k ota.key
Create a new OTA zip with the modified payload binary.
cp sdm660_update.zip sdm660_update.with_recovery.zip
zip -u -0 sdm660_update.with_recovery.zip payload.bin
Two important things:
-0
).Patch sdm660_update.with_recovery.zip
with avbroot ota patch
.
I was able to run the avbroot commands without errors when using the unmodified contents, but if I do the following, then I get an error:
e2fsck -f system.img
resize2fs system.img 2G
e2fsck -E unshare_blocks system.img
mount -t ext4 -o loop,rw system.img ../system
# Modify system contents
umount ../system
e2fsck -f system.img
resize2fs -M system.img
e2fsck -f system.img
Pack using avbroot ...
avbroot payload pack -q -o payload.bin -k ota.key
cp sdm660_update.zip sdm660_update.new.zip
zip -u -0 sdm660_update.new.zip payload.bin
Zip command runs and indicates:
updating: payload.bin (stored 0%)
Patch command returns error:
avbroot ota patch --input sdm660_update.new.zip --key-avb avb4096.pk8 --key-ota ota.key.pem --cert-ota ota.x509.pem --rootless
0.002s INFO Replacing zip entry: META-INF/com/android/otacert
0.002s INFO Copying zip entry: apex_info.pb
0.002s INFO Copying zip entry: care_map.pb
0.002s INFO Copying zip entry: custom.txt
0.002s INFO Patching zip entry: payload.bin
0.003s INFO Extracting from original payload: system
4.977s INFO Extracting from original payload: boot
5.054s INFO Extracting from original payload: vbmeta
5.104s INFO Extracting from original payload: recovery
5.208s INFO Extracting from original payload: vbmeta_system
5.208s INFO Patching boot images: boot, recovery
6.802s INFO Patching system image: system
6.949s ERROR Failed to patch OTA zip
Caused by:
0: Failed to patch payload: payload.bin
1: Failed to patch system image: system
2: AVB error
3: Invalid VBMeta header magic: [0, 0, 0, 0]
... also I tried the steps as recommended for adding the recovery.img partition (without other changes), but the device does not take the patched file. Here's the log file:
08-18 08:13:23.880 E/UpdateManager( 8131): applyPayload start
08-18 08:13:23.888 I/update_engine( 1246): [INFO:update_attempter_android.cc(320)] Using this install plan:
08-18 08:13:23.894 I/update_engine( 1246): [INFO:install_plan.cc(80)] InstallPlan:
08-18 08:13:23.894 I/update_engine( 1246): type: new_update
08-18 08:13:23.894 I/update_engine( 1246): version:
08-18 08:13:23.894 I/update_engine( 1246): source_slot: B
08-18 08:13:23.894 I/update_engine( 1246): target_slot: A
08-18 08:13:23.894 I/update_engine( 1246): initial url: file:///data/update.zip
08-18 08:13:23.894 I/update_engine( 1246): hash_checks_mandatory: true
08-18 08:13:23.894 I/update_engine( 1246): powerwash_required: false
08-18 08:13:23.894 I/update_engine( 1246): switch_slot_on_reboot: true
08-18 08:13:23.894 I/update_engine( 1246): run_post_install: true
08-18 08:13:23.894 I/update_engine( 1246): is_rollback: false
08-18 08:13:23.894 I/update_engine( 1246): rollback_data_save_requested: false
08-18 08:13:23.894 I/update_engine( 1246): write_verity: true
08-18 08:13:23.894 I/update_engine( 1246): Payload: 0
08-18 08:13:23.894 I/update_engine( 1246): urls: ()
08-18 08:13:23.894 I/update_engine( 1246): size: 2075195198
08-18 08:13:23.894 I/update_engine( 1246): metadata_size: 125336
08-18 08:13:23.894 I/update_engine( 1246): metadata_signature:
08-18 08:13:23.894 I/update_engine( 1246): hash: 12AE5F955E21C1B2471B6A7AD93AA985A9530073D5CF9B525EA4427CC738A075
08-18 08:13:23.894 I/update_engine( 1246): type: unknown
08-18 08:13:23.894 I/update_engine( 1246): fingerprint:
08-18 08:13:23.894 I/update_engine( 1246): app_id:
08-18 08:13:23.894 I/update_engine( 1246): already_applied: false
08-18 08:13:23.897 I/update_engine( 1246): [INFO:postinstall_runner_action.cc(95)] postinstall mount point: /postinstall
08-18 08:13:23.900 D/UpdateManager( 8131): onStatusUpdate invoked, status=2, progress=0.00
08-18 08:13:23.900 D/OTA ( 8131): UITYPE_UPGRADE onProgressUpdate=0.0
08-18 08:13:23.900 I/update_engine( 1246): [INFO:metrics_utils.cc(318)] Number of Reboots during current update attempt = 0
08-18 08:13:23.904 I/update_engine( 1246): [INFO:metrics_utils.cc(326)] Payload Attempt Number = 1
08-18 08:13:23.908 I/update_engine( 1246): [INFO:metrics_utils.cc(343)] Update Monotonic Timestamp Start = 1/1/1970 0:10:18 GMT
08-18 08:13:23.915 I/update_engine( 1246): [INFO:metrics_utils.cc(352)] Update Boot Timestamp Start = 1/1/1970 0:10:18 GMT
08-18 08:13:23.919 I/update_engine( 1246): [INFO:update_attempter_android.cc(821)] Clearing update complete marker.
08-18 08:13:23.925 I/update_engine( 1246): [INFO:update_attempter_android.cc(701)] Scheduling an action processor start.
08-18 08:13:23.928 E/UpdateManager( 8131): applyPayload end
08-18 08:13:23.928 I/update_engine( 1246): [INFO:action_processor.cc(51)] ActionProcessor: starting UpdateBootFlagsAction
08-18 08:13:23.931 I/update_engine( 1246): [INFO:update_boot_flags_action.cc(36)] Already updated boot flags. Skipping.
08-18 08:13:23.933 I/update_engine( 1246): [INFO:action_processor.cc(116)] ActionProcessor: finished UpdateBootFlagsAction with code ErrorCode::kSuccess
08-18 08:13:23.933 D/UpdateManager( 8131): onStatusUpdate invoked, status=11, progress=0.00
08-18 08:13:23.934 D/OTA ( 8131): UITYPE_UPGRADE onProgressUpdate=0.0
08-18 08:13:23.936 I/update_engine( 1246): [INFO:action_processor.cc(143)] ActionProcessor: starting CleanupPreviousUpdateAction
08-18 08:13:23.939 I/update_engine( 1246): [INFO:cleanup_previous_update_action.cc(149)] Starting/resuming CleanupPreviousUpdateAction
08-18 08:13:23.942 I/update_engine( 1246): [INFO:cleanup_previous_update_action.cc(189)] Boot completed, waiting on markBootSuccessful()
08-18 08:13:23.946 I/update_engine( 1246): EnsureMetadataMounted does nothing in Android mode.
08-18 08:13:23.947 W/LocSvc_ApiV02( 1075): reportSv:3448] At least one RF_LOSS is 0 in gps.conf, please configure it
08-18 08:13:23.939 I/recordH264Scree( 804): type=1400 audit(0.0:3275): avc: denied { write } for path="socket:[30797]" dev="sockfs" ino=30797 scontext=u:r:init:s0 tcontext=u:r:init:s0 tclass=tcp_socket permissive=1
08-18 08:13:23.948 E/PowerManagerService( 1349): mScreenOffTimeoutSetting=-1 nextTimeout=-1
08-18 08:13:23.952 E/PowerManagerService( 1349): mScreenOffTimeoutSetting=-1 nextTimeout=-1
08-18 08:13:23.954 E/PowerManagerService( 1349): mScreenOffTimeoutSetting=-1 nextTimeout=-1
08-18 08:13:23.949 I/cat ( 790): type=1400 audit(0.0:3276): avc: denied { write } for path="/data/.X13_Log/X13_Log/kernel_6.ini" dev="sda10" ino=6897691 scontext=u:r:toolbox:s0 tcontext=u:object_r:system_data_file:s0 tclass=file permissive=1
08-18 08:13:23.957 E/PowerManagerService( 1349): mScreenOffTimeoutSetting=-1 nextTimeout=-1
08-18 08:13:23.957 I/update_engine( 1246): Read merge statistics file failed: No such file or directory
08-18 08:13:23.959 E/PowerManagerService( 1349): mScreenOffTimeoutSetting=-1 nextTimeout=-1
08-18 08:13:23.959 E/PowerManagerService( 1349): mScreenOffTimeoutSetting=-1 nextTimeout=-1
08-18 08:13:23.966 I/update_engine( 1246): [INFO:cleanup_previous_update_action.cc(261)] Waiting for any previous merge request to complete. This can take up to several minutes.
08-18 08:13:23.969 I/update_engine( 1246): CheckMergeState for snapshots returned: 0
08-18 08:13:23.972 I/update_engine( 1246): ProcessUpdateState handling state: 0
08-18 08:13:23.974 I/update_engine( 1246): [INFO:cleanup_previous_update_action.cc(297)] Can't find any snapshot to merge.
08-18 08:13:23.978 I/update_engine( 1246): [INFO:cleanup_previous_update_action.cc(130)] Stopping/suspending/completing CleanupPreviousUpdateAction
08-18 08:13:23.982 I/update_engine( 1246): [INFO:cleanup_previous_update_action.cc(479)] Not reporting merge stats because state is None
08-18 08:13:23.984 I/update_engine( 1246): [INFO:cleanup_previous_update_action.cc(130)] Stopping/suspending/completing CleanupPreviousUpdateAction
08-18 08:13:23.987 I/update_engine( 1246): [INFO:action_processor.cc(116)] ActionProcessor: finished CleanupPreviousUpdateAction with code ErrorCode::kSuccess
08-18 08:13:23.990 I/update_engine( 1246): [INFO:action_processor.cc(143)] ActionProcessor: starting InstallPlanAction
08-18 08:13:23.992 I/update_engine( 1246): [INFO:action_processor.cc(116)] ActionProcessor: finished InstallPlanAction with code ErrorCode::kSuccess
08-18 08:13:23.996 I/update_engine( 1246): [INFO:action_processor.cc(143)] ActionProcessor: starting DownloadAction
08-18 08:13:24.002 I/update_engine( 1246): [INFO:install_plan.cc(80)] InstallPlan:
08-18 08:13:24.002 I/update_engine( 1246): type: new_update
08-18 08:13:24.002 I/update_engine( 1246): version:
08-18 08:13:24.002 I/update_engine( 1246): source_slot: B
08-18 08:13:24.002 I/update_engine( 1246): target_slot: A
08-18 08:13:24.002 I/update_engine( 1246): initial url: file:///data/update.zip
08-18 08:13:24.002 I/update_engine( 1246): hash_checks_mandatory: true
08-18 08:13:24.002 I/update_engine( 1246): powerwash_required: false
08-18 08:13:24.002 I/update_engine( 1246): switch_slot_on_reboot: true
08-18 08:13:24.002 I/update_engine( 1246): run_post_install: true
08-18 08:13:24.002 I/update_engine( 1246): is_rollback: false
08-18 08:13:24.002 I/update_engine( 1246): rollback_data_save_requested: false
08-18 08:13:24.002 I/update_engine( 1246): write_verity: true
08-18 08:13:24.002 I/update_engine( 1246): Payload: 0
08-18 08:13:24.002 I/update_engine( 1246): urls: ()
08-18 08:13:24.002 I/update_engine( 1246): size: 2075195198
08-18 08:13:24.002 I/update_engine( 1246): metadata_size: 125336
08-18 08:13:24.002 I/update_engine( 1246): metadata_signature:
08-18 08:13:24.002 I/update_engine( 1246): hash: 12AE5F955E21C1B2471B6A7AD93AA985A9530073D5CF9B525EA4427CC738A075
08-18 08:13:24.002 I/update_engine( 1246): type: unknown
08-18 08:13:24.002 I/update_engine( 1246): fingerprint:
08-18 08:13:24.002 I/update_engine( 1246): app_id:
08-18 08:13:24.002 I/update_engine( 1246): already_applied: false
08-18 08:13:24.005 I/update_engine( 1246): [INFO:download_action.cc(86)] Marking new slot as unbootable
08-18 08:13:24.014 D/BTCallService( 3674): mRunnable mAudioVoice.....
08-18 08:13:24.049 I/update_engine( 1246): [INFO:multi_range_http_fetcher.cc(45)] starting first transfer
08-18 08:13:24.052 I/update_engine( 1246): [INFO:multi_range_http_fetcher.cc(74)] starting transfer of range 2446+2075195198
08-18 08:13:24.039 I/update_engine( 1246): type=1400 audit(0.0:3277): avc: denied { read } for name="update.zip" dev="sda10" ino=14 scontext=u:r:update_engine:s0 tcontext=u:object_r:system_data_root_file:s0 tclass=file permissive=1
08-18 08:13:24.039 I/update_engine( 1246): type=1400 audit(0.0:3278): avc: denied { open } for path="/data/update.zip" dev="sda10" ino=14 scontext=u:r:update_engine:s0 tcontext=u:object_r:system_data_root_file:s0 tclass=file permissive=1
08-18 08:13:24.039 I/update_engine( 1246): type=1400 audit(0.0:3279): avc: denied { getattr } for path="/data/update.zip" dev="sda10" ino=14 scontext=u:r:update_engine:s0 tcontext=u:object_r:system_data_root_file:s0 tclass=file permissive=1
08-18 08:13:24.055 D/UpdateManager( 8131): onStatusUpdate invoked, status=3, progress=0.00
08-18 08:13:24.055 D/OTA ( 8131): UITYPE_UPGRADE onProgressUpdate=9.073844921658747E-6
08-18 08:13:24.058 I/update_engine( 1246): [INFO:delta_performer.cc(113)] Completed 0/? operations, 16384/2075195198 bytes downloaded (0%), overall progress 0%
08-18 08:13:24.062 E/update_engine( 1246): [ERROR:payload_metadata.cc(64)] Bad payload format -- invalid delta magic: 33265343 Expected: 43724155
08-18 08:13:24.064 E/update_engine( 1246): [ERROR:download_action.cc(227)] Error ErrorCode::kDownloadInvalidMetadataMagicString (21) in DeltaPerformer's Write method when processing the received payload -- Terminating processing
08-18 08:13:24.067 I/update_engine( 1246): [INFO:delta_performer.cc(215)] Discarding 24 unused downloaded bytes
08-18 08:13:24.069 I/update_engine( 1246): [INFO:multi_range_http_fetcher.cc(177)] Received transfer terminated.
08-18 08:13:24.072 I/update_engine( 1246): [INFO:multi_range_http_fetcher.cc(129)] TransferEnded w/ code 200
08-18 08:13:24.074 I/update_engine( 1246): [INFO:multi_range_http_fetcher.cc(131)] Terminating.
08-18 08:13:24.077 I/update_engine( 1246): [INFO:action_processor.cc(116)] ActionProcessor: finished DownloadAction with code ErrorCode::kDownloadInvalidMetadataMagicString
08-18 08:13:24.082 I/update_engine( 1246): [INFO:action_processor.cc(121)] ActionProcessor: Aborting processing due to failure.
08-18 08:13:24.085 I/update_engine( 1246): [INFO:update_attempter_android.cc(565)] Processing Done.
08-18 08:13:24.088 D/UpdateManager( 8131): onStatusUpdate invoked, status=0, progress=0.00
08-18 08:13:24.088 D/OTA ( 8131): UITYPE_UPGRADE onProgressUpdate=0.0
08-18 08:13:24.088 D/UpdateManager( 8131): onPayloadApplicationComplete invoked, errorCode=21
08-18 08:13:24.088 D/UpdateManager( 8131): setUpdaterState invoked newState=1
08-18 08:13:24.088 I/OTA ( 8131): UpdaterStateChange state=ERROR/1
08-18 08:13:24.088 D/OTA ( 8131): uiStateError
08-18 08:13:24.088 I/OTA ( 8131): PayloadApplicationCompleted - errorCode=null/21 FAILURE
08-18 08:13:24.090 D/UpdateManager( 8131): resetUpdate invoked
08-18 08:13:24.090 D/UpdateManager( 8131): setUpdaterState invoked newState=0
08-18 08:13:24.090 I/OTA ( 8131): UpdaterStateChange state=IDLE/0
08-18 08:13:24.090 I/update_engine( 1246): [INFO:metrics_reporter_android.cc(159)] Current update attempt downloads 0 bytes data
08-18 08:13:24.095 I/update_engine( 1246): [INFO:update_attempter_android.cc(402)] Attempting to reset state from UPDATE_STATUS_IDLE to UpdateStatus::IDLE
08-18 08:13:24.098 I/update_engine( 1246): [INFO:update_attempter_android.cc(410)] Cleaning up reserved space for compressed APEX (if any)
08-18 08:13:24.101 I/update_engine( 1246): [INFO:update_attempter_android.cc(821)] Clearing update complete marker.
08-18 08:13:24.104 I/update_engine( 1246): [INFO:dynamic_partition_control_android.cc(1306)] ResetUpdate resetting update state and deleting snapshots.
08-18 08:13:24.107 I/update_engine( 1246): [INFO:delta_performer.cc(1281)] Resetting recorded hash for prepared partitions.
I was able to run the avbroot commands without errors when using the unmodified contents
Great!
but if I do the following, then I get an error:
Ah, by using resize2fs, you wiped out the AVB metadata. I'd recommend this instead:
avbroot avb unpack -i system.img
This will create avb.toml
and raw.img
. Modify raw.img
instead of system.img
with your commands.
Then, recreate system.img
with:
avbroot avb pack -o system.img --recompute-size
... also I tried the steps as recommended for adding the recovery.img partition (without other changes), but the device does not take the patched file.
Hmm, that's extremely odd. Any chance you could upload the patched OTA you were flashing?
The error is:
08-18 08:13:24.062 E/update_engine( 1246): [ERROR:payload_metadata.cc(64)] Bad payload format -- invalid delta magic: 33265343 Expected: 43724155
It's saying the first 4 bytes of payload.bin
are 3&SC
instead of CrAU
. I have no idea what could possibly screw that up.
Here’s the patched file with just recovery partition added:
https://drive.google.com/file/d/14quLMwMToMFFRFGul8TY8S7OTJEaUq8P/view?usp=drivesdk
On Sun, Aug 18, 2024 at 11:49 Andrew Gunnerson @.***> wrote:
I was able to run the avbroot commands without errors when using the unmodified contents
Great!
but if I do the following, then I get an error:
Ah, by using resize2fs, you wiped out the AVB metadata. I'd recommend this instead:
avbroot avb unpack -i system.img
This will create avb.toml and raw.img. Modify raw.img instead of system.img with your commands.
Then, recreate system.img with:
avbroot avb pack -o system.img --recompute-size
... also I tried the steps as recommended for adding the recovery.img partition (without other changes), but the device does not take the patched file.
Hmm, that's extremely odd. Any chance you could upload the patched OTA you were flashing?
The error is:
08-18 08:13:24.062 E/update_engine( 1246): [ERROR:payload_metadata.cc(64)] Bad payload format -- invalid delta magic: 33265343 Expected: 43724155
It's saying the first 4 bytes of payload.bin are 3&SC instead of CrAU. I have no idea what could possibly screw that up.
— Reply to this email directly, view it on GitHub https://github.com/chenxiaolong/avbroot/issues/328#issuecomment-2295355029, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABCQGSMG3D6XSSRVYRRAV7DZSDUERAVCNFSM6AAAAABMOZ2BMSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEOJVGM2TKMBSHE . You are receiving this because you authored the thread.Message ID: @.***>
Thanks! Unfortunately, this is probably not fixable because update_engine
on your device has a broken zip file parser.
Details:
This is a hex dump of the portion of the zip file where payload.bin
starts:
CrAU
- This is where the actual payload data starts.3&SC
- This is where update_engine is incorrectly reading from.The incorrect offset is exactly 64 bytes before where it should be reading.
Looking at the zip, payload.bin
is 5th entry:
❯ unzip -l sdm660_update.new.zip.patched
Archive: sdm660_update.new.zip.patched
signed by avbroot
Length Date Time Name
--------- ---------- ----- ----
1675 01-01-1980 00:00 META-INF/com/android/otacert
0 01-01-1980 00:00 apex_info.pb
525 01-01-1980 00:00 care_map.pb
24 01-01-1980 00:00 custom.txt
2075195198 01-01-1980 00:00 payload.bin
156 01-01-1980 00:00 payload_properties.txt
678 01-01-1980 00:00 META-INF/com/android/metadata
1097 01-01-1980 00:00 META-INF/com/android/metadata.pb
--------- -------
2075199353 8 files
Every entry has a 16 byte data descriptor:
❯ zipdetails -vv --no-language-encoding sdm660_update.new.zip.patched
...
00000000 00000003 00000004 50 4B 03 04 LOCAL HEADER #1 04034B50 (67324752)
0000001E 00000039 0000001C 4D 45 54 41 Filename 'META-INF/com/android/otacert'
000006C5 000006C8 00000004 50 4B 07 08 DATA DESCRIPTOR 08074B50 (134695760)
000006C9 000006CC 00000004 54 09 FC C3 CRC C3FC0954 (3288074580)
000006CD 000006D0 00000004 8B 06 00 00 Compressed Size 0000068B (1675)
000006D1 000006D4 00000004 8B 06 00 00 Uncompressed Size 0000068B (1675)
...
000006D5 000006D8 00000004 50 4B 03 04 LOCAL HEADER #2 04034B50 (67324752)
000006F3 000006FE 0000000C 61 70 65 78 Filename 'apex_info.pb'
000006FF 00000702 00000004 50 4B 07 08 DATA DESCRIPTOR 08074B50 (134695760)
00000703 00000706 00000004 00 00 00 00 CRC 00000000 (0)
00000707 0000070A 00000004 00 00 00 00 Compressed Size 00000000 (0)
0000070B 0000070E 00000004 00 00 00 00 Uncompressed Size 00000000 (0)
...
0000070F 00000712 00000004 50 4B 03 04 LOCAL HEADER #3 04034B50 (67324752)
0000072D 00000737 0000000B 63 61 72 65 Filename 'care_map.pb'
00000945 00000948 00000004 50 4B 07 08 DATA DESCRIPTOR 08074B50 (134695760)
00000949 0000094C 00000004 6B 51 CA AD CRC ADCA516B (2915717483)
0000094D 00000950 00000004 0D 02 00 00 Compressed Size 0000020D (525)
00000951 00000954 00000004 0D 02 00 00 Uncompressed Size 0000020D (525)
...
00000955 00000958 00000004 50 4B 03 04 LOCAL HEADER #4 04034B50 (67324752)
00000973 0000097C 0000000A 63 75 73 74 Filename 'custom.txt'
00000995 00000998 00000004 50 4B 07 08 DATA DESCRIPTOR 08074B50 (134695760)
00000999 0000099C 00000004 78 0A 43 1F CRC 1F430A78 (524487288)
0000099D 000009A0 00000004 18 00 00 00 Compressed Size 00000018 (24)
000009A1 000009A4 00000004 18 00 00 00 Uncompressed Size 00000018 (24)
...
000009A5 000009A8 00000004 50 4B 03 04 LOCAL HEADER #5 04034B50 (67324752)
000009C3 000009CD 0000000B 70 61 79 6C Filename 'payload.bin'
...
So (4 files before payload.bin
) times (16 bytes per data descriptor) = 64 bytes. I very strongly suspect that your device's update_engine
has a broken zip parser and fails to handle data descriptors properly.
I tried flashing your zip on one of my test devices with some safety checks removed (nobody reading this should ever attempt this!) and it was able to successfully read the file.
While data descriptors are optional (and the original sdm660_update.zip
doesn't use them), it is a part of the zip file standard. avbroot's OTA signing logic requires using data descriptors and cannot function without them.
I thought the data descriptors were 12 bytes? Is the 4-byte descriptor a new(er) version of the spec? Also, I'm seeing data descriptors are used in the original file I have. They all have bit 3 set in the general purpose flag (0x0800).
Does it have anything to do with the original zip using zip spec 1.0
and the patched one using spec 2.0
?
Oh huh, I missed that in the original file. It does indeed have a data descriptor, but only for META-INF/com/android/otacert
.
The data descriptors can be either 12 or 16 bytes (or more for zip64) because the 4 byte 0x08074b50 marker is optional (section 4.3.9.3). AOSP supports parsing data descriptors with and without the marker (source).
I don't think the zip spec field has anything to do with it. At least in AOSP, that field is completely ignored.
Would it be a heavy lift to modify the signing logic to support zip files without data descriptors? I'd be happy to donate to the project to make it happen.
I don't accept donations for my projects anymore, but thank you for offering!
Please give #337 a try. Test builds can be found at: https://github.com/chenxiaolong/avbroot/actions/runs/10463414808?pr=337. When patching, you'll want to use the new --zip-mode seekable
option to prevent data descriptors from being written.
You are an Android genius!!! Now on to checkout your Custota project.
I'm getting the following error when trying to sign an OTA image on 3.4.1. Any idea how to resolve this?