This way, we can fail hard for parsing errors, but not for verification
errors in `avbroot ota verify`.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
* Try to avoid fail-fast behavior to show as many errors as possible.
Parsing errors always fail immediately, but verification errors don't.
* Move the recovery otacerts.zip check to the end to let more important
checks run first.
* Improve error message when otacerts.zip does not contain the signing
certificate for the OTA to make it clear the issue is not that the zip
contains no certificates at all.
* Always run the recovery otacerts.zip check, but just log the error as
a warning when running with --skip-recovery-ota-cert.
* Fix unformatted error context string when parsing a boot image's
otacerts.zip file fails.
Discussion: #426
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
There are two documented behaviors in liblp that are violated with the
on-disk super partition layout after a virtual A/B CoW merge:
1. The partition name includes a `-` due to the `-cow` suffix. This is
not meant to be a valid character.
2. The extent list is likely to have many gaps and not be sorted. The
format documentation says that gaps are not allowed.
This commit updates avbroot's LP parser to be less strict so that it can
load real on-device super partitions. The extent allocator for the
`pack` subcommand remains unchanged though, so avbroot will always
produce LP images with sorted, gapless extents.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This is the same optimization as is currently done for boot images.
There's no reason to keep the temp file around for the entire patching
process if it's unmodified and we're not going to be copying its data
into the payload.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
The filtering out of partitions was done at the wrong scope, causing
avbroot to warn that extracted-but-unmodified partitions were not
protected by AVB. We never encountered this before because the system
image was always patched and unmodified boot images got filtered out at
an earlier phase during patching.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
The author of ring recently announced that the library is no longer
being maintained and fixes for security issues may be significantly
delayed. Big thanks to Brian Smith for creating and maintaining the
library for so long!
This commit replaces ring with aws-lc, a cryptography library maintained
by Amazon AWS. It seems to be well-regarded and is used by high-profile
projects like rustls. It is also API-compatible with ring, so it is
effectively a drop-in replacement.
Unfortunately, we still cannot switch back to the RustCrypto SHA1 and
SHA2 implementations because they are still significantly slower than
ring and aws-lc on systems that do not support the SHA-NI extensions.
https://rustsec.org/advisories/RUSTSEC-2025-0007
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
* There is now a stable release of bzip2-rs with the fix for both the C
and Rust versions of bzip2 being compiled.
* The zlib-rs deflate implementation is faster than the default
miniz_oxide. Changing this requires updating the checksums in the e2e
tests due to slight differences in compression levels between the two
implementations.
* Temporarily silence RUSTSEC-2025-0007 to avoid blocking CI. The ring
library is no longer maintained.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This is analogous to the existing --skip-recovery-ota-cert option,
except for the system image.
Discussion: #417
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
AOSP says that for non-empty images, the first 4 KiB block is supposed
to be filled with zeros to prevent it from being interpreted as an old
BIOS boot sector. The previous implementation relied on that to
distinguish between empty and non-empty images. However, Samsung decided
to use this region for their own SignerVer02 structure, so the heuristic
doesn't work.
AOSP's liblp tries to parse the input file as an empty image before
falling back to parsing as a normal image. We'll do the same.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
For consistency with decode-avb. The old syntax will remain supported
indefinitely for backwards compatibility.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This also adds a new --none option so that these two components can be
extracted without extracting any partition images.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Previously, we only supported extracting all images or the subset of
images that could potentially be patched by avbroot. This was
unnecessarily slow if the user only needed to extract a specific image.
This commit also deprecates and hides the `--boot-only` option, though
the functionality will remain indefinitely.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
The only remaining fix from our fork has been merged. This can be
switched to a stable release after the next release.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Implicit error propagation was originally used because it was convenient
and made it easy to just bubble up errors via the ? operator without
thinking. However, there have been too many situations where this
resulted in error messages that were completely useless in
troubleshooting the problem. "I/O error", even with a specific reason
attached, is useless where there are potentially hundreds of operations
where I/O can fail.
I no longer think implicit error propagation is a good idea, so this
commit removes every single use of #[from] in every custom error type.
There are now many more error variants, allowing more context to be
attached to the underlying errors.
Previously, it was easy to encounter error messages like:
Caused by:
0: Failed to patch payload: payload.bin
1: Failed to patch boot images: boot, init_boot, vendor_boot
2: Boot image error
3: I/O error
4: failed to fill whole buffer
This is a terrible error message because it doesn't mention which of the
3 boot images failed to parse, nor does it mention during which I/O
operation it encountered EOF. With this commit, this sort of information
is now included. For example, if the boot image happened to be truncated
in the middle of the ramdisk, the error message would now be:
Caused by:
0: Failed to patch payload: payload.bin
1: Failed to patch boot images: boot, init_boot, vendor_boot
2: Failed to load boot image: init_boot
3: Failed to read boot image data: Boot::V3::ramdisk
4: failed to fill whole buffer
Changes:
* Remove all uses of #[from] from thiserror-derived error types.
* Errors during parsing and serialization of RSA private keys, RSA
public keys, and X509 certificates now include the file path.
* Removed unnecessary uses of BufReader and BufWriter when reading and
writing RSA private keys, RSA public keys, and X509 certificates,
since they need to be fully read into memory anyway.
* Use ReadFixedSizeExt instead of read_exact() where possible.
* Use &'static str instead of String in error fields where all possible
values are known at compile-time to avoid unnecessary heap allocation.
* Use ok_or() instead of ok_or_else() to construct errors when the error
variant uses known data and does not require heap allocation.
* Using DebugString instead of String in error variants that store a
preformatted debug string.
While working on this commit, an unrelated bug was found and fixed:
* Fix vendor v4 boot images that were truncated within the padding
following the bootconfig section being treated as valid.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This makes the type potentially more useful outside of just our current
use case of just error messages. Ranges where the starting value is
exclusive are no longer supported, but weren't used anyway.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
The bzip2-rs library now has a new maintainer (same folks that maintain
the sudo-rs project). Version 0.5.0 was recently released, which
includes some much needed bug fixes, but is missing one final one, so we
still need to keep our fork for now.
This commit also switches the backend implementation from the official C
implementation to a Rust implementation maintained by the bzip2-rs
folks. This leaves xz as the only C dependency remaining in avbroot.
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Previously, when patching with a Magisk version newer than the latest
supported version and using --ignore-magisk-warnings, the upper bound of
VER_PREINIT_DEVICE and VER_XZ_BACKUP would prevent those features from
being used. It makes more sense to assume that a newer version supports
all the same features as the latest supported version instead.
Issue: #393
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>