The pack and unpack commands can never support delta payloads, but
there's no reason not to allow the repack and info commands to read
them.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
std::process::exit() calls the exit syscall, which doesn't run
destructors. It doesn't matter for avbroot, but better to use ExitCode
anyway.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This supports all features of Android sparse images, including holes,
and CRC32 (both full image checksum and CRC32 chunks).
Partial sparse images, like those included in GrapheneOS' new optimized
factory images, can also be packed and unpacked with these new commands,
unlike AOSP's simg2img and img2simg tools.
This new functionality is not relevant for avbroot's main use case, but
is useful for unpacking certain factory images for comparison with OTAs
during troubleshooting.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Empty images don't contain any extent metadata so the partition sizes
are just discarded.
Don't write parsers when you're tired, folks!
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This supports both empty and normal LP images, including those that span
multiple files/devices.
Currently, repacked files are semantically equivalent, but not exactly
identical. avbroot's data structure for the metadata does not preserve
the arbitrary partition ordering of the LP image. Instead, to make the
API a bit nicer, it only preserves the relative partition ordering
within partition groups.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit adds a new `--zip-mode` parameter to `avbroot ota patch` to
control whether the patched OTA zip is written with data descriptors or
not. By default, the `streaming` mode is used, which matches the current
behavior where the zip is hashed for signing as it is being written. The
new `seekable` mode fully writes the zip before rereading it to hash the
contents.
The new mode is useful for devices with broken zip parsers that fail to
properly handle data descriptors.
All of the end-to-end tests have been duplicated to test both modes.
Adding the seekable mode necessitated a couple other changes:
* BufWriter is no longer used. Type erasure is very painful in Rust, so
we need to keep the writer types the same for both the streaming and
seekable modes. BufWriter is unusable in the seekable mode because we
need to be able to read back what was written, which isn't supported.
* HolePunchingWriter has been removed. It was a simple way to produce
sparse files by seeking whenever a write buffer consists fully of
zeros. When combined with BufWriter, there was previously never a
situation where this was undesirable. However, with the new seekable
mode and the zip library's pattern of writing one field at a time, the
final 2 zero bytes (representing an empty archive comment) is never
written and the file size is not increased either.
Removing this is not a big deal since we no longer use stripped OTAs
for the end-to-end tests. Those were really the only OTAs that
benefitted from sparse files. A real OTA has very few zero bytes due
to compression.
Issue: #328
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Older devices, like the Pixel 4a 5G (bramble) use gzip instead of lz4.
This commit also reworks the CoW size estimate calculation to add the
same constant headroom that AOSP's delta_generator adds. Previously,
avbroot was already adding an additional 1% to account for differences
in compression ratios across compression library implementations. This
papered over the issue for large partitions, but small partitions could
still have a CoW size estimate that's too small. Adding the constant
headroom prevents ENOSPC when flashing those partitions.
Fixes: #332
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Some devices have "full" OTAs where the payload is missing the recovery
partition. These subcommands make it possible to manually add back the
missing image. Given the strict requirements for how the OTA zip is laid
out and signed, users can't just replace payload.bin in a zip and call
it a day, but it's sufficient for feeding a modified input to
`avbroot ota patch`.
Issue: #328
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Version 1.6.0 of the bytes library was yanked. There's no vulnerability
that impacts avbroot, but it was tripping the cargo-deny checks.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Older versions of fastboot have bugs that cause the reboot to fastbootd
mode to be skipped, causing failures when flashing dynamic partitions.
Fixes: #314
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
By default, the helper program is invoked in a way that is compatible
with avbtool's --signing_helper. However, the arguments have been
extended slightly to allow passing in the passphrase file or environment
variable for non-interactive use.
Fixes: #310
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This is never reachable due to additional checks in every code path that
invokes sign() and verify(), but still better to be correct.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
lz4_flex appears to compress system images better than the original lz4
implementation used in libsnapshot_cow, so the estimates are too low.
Fixes: #306
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Otherwise, if the partition size increases or the data becomes more
incompressible, update_engine might fail to flash the partition due to
the CoW block device running out of space.
Since all known VABC-enabled OTAs in the wild currently use CoW v2 with
lz4 compression, this is the only configuration we support. CoW v3 also
exists in AOSP's libsnapshot_cow, but is much more complicated to
implement and is not yet used, even in the Android 15 beta OTAs.
Fixes: #306
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>