PR #110 fixed this incorrectly. I misinterpreted "set to zero in the
local header" from §4.4.4 in the spec as referring to the two 32-bit
size fields in the local header. However, the spec considers the zip64
extra record as part of the local header. The correct behavior for
writing zip64 entries to unseekable files is 0xffffffff in the 32-bit
local header size fields (to enable zip64), 0 in the zip64 extra record
(due to streaming writes), and the actual sizes in the data descriptor.
Fixes: #109
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds support for replacing any partition image within
the payload with a custom image. This is useful, for example, to add a
custom kernel to an OTA, which may involve partitions that wouldn't
normally be touched (eg. `vendor_dlkm`).
Any image specified via `--replace` will have its corresponding
descriptor in the vbmeta image updated. This is handled recursively. For
example, replacing `vendor_dlkm` would update both `vbmeta_vendor` and
`vbmeta`. This requires all vbmeta images to be extracted during the
patching process so that a complete dependency graph can be computed.
The performance hit in doing so is negligible, but does require the
checksums of the stripped images to be updated for the tests.
Fixes: #102
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
There are 3 levels of warnings:
* Level 0: Warnings that don't affect booting
* Mismatched `id` or `os_version` fields
* Level 1: Warnings that may affect booting
* Mismatched `cmdline` or `extra_cmdline` fields
* Unexpected addition of `kernel`, `second`, `recovery_dtbo`, `dtb`,
or `bootconfig`
* Level 2: Warnings that are very likely to affect booting
* All other mismatched, added, or removed fields
By default, any warning of level 1 or higher is treated as a fatal
error. Each time `--ignore-prepatched-compat` is passed in, the
permitted warning level is increased.
Fixes: #108
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit fixes two issues:
* Python 3.11.4 has a regression where it sets the local file header's
compressed and uncompressed size fields to 0xffffffff when data
descriptors are used. These should be set to 0 (along with the CRC)
according to §4.4.4 of the spec. We work around this by monkey
patching zipfile's local file header serialization function to correct
the fields.
* avbroot tries to preserve as much metadata from the original zip as
possible, including the `extra` records. This caused zip64 records
(0x0001) to be duplicated. The first instance was from the original
zip (containing invalid size fields) and the second instance was newly
created by zipfile. We fix this by stripping out all 0x0001 records,
similar to what we already do for 0xd935.
Fixes: #109
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
The module helps reduce the chance of OEM unlocking being disabled,
whether by the user or by some OS's initial setup wizard. It works by
running some Java code at boot, which connects to the `OemLockService`
binder service and calls `setOemUnlockAllowedByUser(true)`, the same as
what the Settings app does.
Fixes: #8
Issue: #84
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
These versions are missing Magisk commit
1f8c063dc64806c4f7320ed66c785ff7bc116383, which fixes booting into
recovery on devices that use Android 13 GKIs. Trying to use these
versions with avbroot would prevent the user from installing future OTAs
without manually flashing a boot image patched with a newer Magisk
version while booted into Android first.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
In addition to the preinit device, Magisk now requires a random seed to
be added to the Magisk config in the boot image. Magisk's boot_patch.sh
generates a new seed every time an image is patched, but avbroot will
use the hardcoded seed 0xfedcba9876543210 to guarantee byte-for-byte
reproducibility of the output file. This can be overridden with
--magisk-random-seed <uint64>.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Unlike the prior RULESDEVICE, PREINITDEVICE uses a block device name
since the rdev major/minor is not guaranteed to remain the same across
reboots. This commit completely drops support for RULESDEVICE (25207
through 25210) since it never made it to a stable Magisk release.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Newer Magisk versions no longer try to autodetect a writable ext4
partition for storing SELinux rules during boot. Instead, the block
device is detected during boot image patching and is stored in the
ramdisk's `.backup/.magisk` as `makedev(rdev_maj, rdev_min)`.
This unfortunately complicates the patching process for avbroot. Even if
we replicate Magisk's algorithm for finding a suitable partition,
there's no way to find the block device's rdev for it with the
information contained in the OTA package. This is the first change that
adds a hard dependency on information only attainable from a running
device.
For these newer Magisk versions, the user will have to patch the boot
image once in the Magisk app (must be on the target device) and then run
`avbroot magisk-info` to show the computed device ID. Then, avbroot can
use this during patching via `--magisk-rules-device`. If the user's
device is unable to run the Magisk app prior to patching (eg.
unbootable), they'll have to go through the patching process twice, once
with `--ignore-magisk-warnings` and a second time with the proper device
ID specified.
When using `--ignore-magisk-warnings`, root still works, but there will
be subtle issues, like certain modules failing to load.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This way, the module path is automatically updated when avbroot is
imported. This also fixes the lint warning about `external` being
imported, but not used.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>