Compare commits

..

59 Commits

Author SHA1 Message Date
Andrew Gunnerson 69903c4382 Version 3.24.1
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-02-03 18:19:05 -05:00
Andrew Gunnerson 9987d21cef CHANGELOG.md: Add entry for PR #559
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-02-03 18:16:25 -05:00
Andrew Gunnerson 9802bba5f7 Update dependencies
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-02-03 18:09:44 -05:00
Andrew Gunnerson 1b30328b01 CHANGELOG.md: Add entry for PR #555
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-24 18:55:42 -05:00
Andrew Gunnerson efb25e15dd cli/avb: Fix help text for avbroot avb verify-device -p
Issue: #554

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-24 18:52:32 -05:00
Ivan 2e5754e16c README.ru.md: Update translation
Sync with https://github.com/chenxiaolong/avbroot/commit/2033e481632fb7b81df296f00d1d75ab1759adae

Signed-off-by: Ivan <reddxae@proton.me>
2026-01-10 15:43:36 +03:00
Andrew Gunnerson cd4da8d147 Version 3.24.0
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 23:32:00 -05:00
Andrew Gunnerson 9c48d0ddc5 CHANGELOG.md: Add entry for PR #550
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 23:31:25 -05:00
Andrew Gunnerson ee70fdbcae deny.toml: Ignore compiled honggfuzz executable and object files
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 23:10:50 -05:00
Andrew Gunnerson f8f1afd6b3 CHANGELOG.md: Add entry for PR #549
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 23:07:24 -05:00
Andrew Gunnerson f2b98623cb Update dependencies
Also, switch e2e from toml_edit to toml since we don't need any editing
capabilities.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 21:10:38 -05:00
Andrew Gunnerson 63e21c5aa9 Merge pull request #534 from lefuglyduck/patch-1
Update README.md
2026-01-09 20:27:00 -05:00
Andrew Gunnerson a78a122763 CHANGELOG.md: Add entry for PR #548
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 20:25:41 -05:00
Andrew Gunnerson cd7316b429 Move fuzzing corpus generation to xtask
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 20:15:33 -05:00
Andrew Gunnerson 68d5bd6990 CHANGELOG.md: Add entry for PR #547
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 19:52:31 -05:00
Andrew Gunnerson 2a4c422943 Update toml to support serialization of large u64 values
Upstream bug report: https://github.com/toml-rs/toml/issues/1085
Upstream fix: https://github.com/toml-rs/toml/pull/1086

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 19:49:44 -05:00
Andrew Gunnerson 94b12bf727 CHANGELOG.md: Add entry for PR #539
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 19:36:30 -05:00
Andrew Gunnerson f966714310 cli/ota: Ignore vbmeta partitions filled with zeros
For whatever reason, some OTAs seem to include empty unused vbmeta
partitions. To avoid needing to extract the partitions to check the
contents, we'll just filter out small vbmeta partitions (>=4 KiB and
<=64 KiB) where the partition checksum specified in the payload matches
the SHA-256 digest of an array of zeros of the same size.

Fixes: #537

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 19:35:15 -05:00
Andrew Gunnerson 3eb08f48d1 CHANGELOG.md: Add entry for PR #545
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 01:22:06 -05:00
Andrew Gunnerson dbb5bc4767 format/lp: Fix potential panic caused by empty image extent indices
7017bc66dd relaxed the parser logic to
allow empty images to contain extents. However, the validation check for
extent indices didn't run because it still had a conditional for normal
images. This could cause a panic during parsing due to an out of bounds
read of the extents array.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 01:20:30 -05:00
Andrew Gunnerson 903d6dcd13 CHANGELOG.md: Add entry for PR #544
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 00:55:52 -05:00
Andrew Gunnerson ddcef31b96 fuzz: Fix initial corpus
e22f9f5676 removed all the old binary test
files, leaving broken symlinks in hfuzz_workspace. This commit adds the
source files for generating them from scratch.

This commit also replaces toml_edit with toml since the former cannot
deserialize u64 values.

Fixes: #532

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-09 00:53:18 -05:00
Andrew Gunnerson cbd419f8e9 CHANGELOG.md: Add entry for PR #543
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-08 19:54:20 -05:00
Andrew Gunnerson 9214a832cd patch/boot: Add support for DSU on dedicated recovery devices
On devices with dedicated recovery partitions, first_stage_ramdisk
exists in the ramdisks, but is unused. The first stage switch root
operation is just skipped. To properly add a public key for DSU on these
devices, the top level /avb directory needs to be used.

Fixes: #536

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-08 19:21:55 -05:00
Andrew Gunnerson dc9244f014 CHANGELOG.md: Add entry for PR #541
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-07 20:28:21 -05:00
Andrew Gunnerson 7017bc66dd format/lp: Allow empty images to list extents
Android's DSU mechanism uses this in /metadata/gsi/dsu/dsu/lp_metadata.
The file is an empty image that references the userdata block device and
the extents point to preallocated space for the partition images in
/data/gsi/dsu/dsu.

This commit also relaxes the metadata_max_size limit to 512 KiB since
these DSU LP images set the field to 256 KiB:

https://android.googlesource.com/platform/system/core/+/refs/tags/android-16.0.0_r4/fs_mgr/libfiemap/metadata.cpp#35

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-07 20:26:14 -05:00
Andrew Gunnerson bff45fc53c CHANGELOG.md: Add entry for PR #540
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-07 20:13:44 -05:00
Andrew Gunnerson 0e5ba0f0e2 patch/boot: Always normalize ramdisk archives
Previously, some of the boot image patches did not sort the cpio entries
and (re)assign inode numbers. In practice, this makes no difference, but
it is still not the intended behavior.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2026-01-07 20:10:37 -05:00
lefuglyduck 2033e48163 Update README.md
Added adb command to reboot into recovery. 

Signed-off-by: lefuglyduck <31975903+lefuglyduck@users.noreply.github.com>
2025-12-11 07:02:04 -08:00
Andrew Gunnerson 237f59fd9b Version 3.23.3
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-12-01 21:02:12 -05:00
Andrew Gunnerson b0b00a4c54 CHANGELOG.md: Add entry for PR #530
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-12-01 20:58:15 -05:00
Andrew Gunnerson b9a70efb15 Update dependencies
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-12-01 20:54:47 -05:00
Andrew Gunnerson aeef2936d8 CHANGELOG.md: Add entry for PR #529
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-12-01 20:49:24 -05:00
Andrew Gunnerson 3adab80893 Bump Magisk version upper bound to 30700
There are no breaking changes.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-12-01 20:48:16 -05:00
Andrew Gunnerson 4069429361 Version 3.23.2
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-11-04 20:55:17 -05:00
Andrew Gunnerson 74193c1c9f CHANGELOG.md: Add entry for PR #524
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-11-04 20:54:42 -05:00
Andrew Gunnerson 0f8cef2daa ci.yml: Add aarch64-pc-windows-msvc target
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-11-04 18:10:05 -05:00
Andrew Gunnerson 8731df4504 CHANGELOG.md: Add entry for PR #523
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-11-04 18:08:35 -05:00
Andreas Papon fda11b4262 Add aarch64-unknown-linux-gnu target. 2025-11-04 20:08:05 +01:00
Andrew Gunnerson f0970aa80c Version 3.23.1
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-10-02 19:37:41 -04:00
Andrew Gunnerson 4f0db5a7c4 CHANGELOG.md: Add entry for PR #521
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-10-02 19:28:22 -04:00
Andrew Gunnerson 57374e2e41 Bump Magisk version upper bound to 30500
There are no breaking changes.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-10-02 19:27:19 -04:00
Andrew Gunnerson f4e5c55fe9 Version 3.23.0
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-09-30 20:39:13 -04:00
Andrew Gunnerson 850ce86388 CHANGELOG.md: Add entry for PR #520
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-09-30 20:16:31 -04:00
Andrew Gunnerson c16636a68c Update dependencies
The only breaking changes are a few types from lzma-rust2 being renamed.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-09-30 20:15:20 -04:00
Andrew Gunnerson 26812cd43a CHANGELOG.md: Add entry for PR #519
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-09-30 20:08:55 -04:00
Andrew Gunnerson 135cd320ce Bump Magisk version upper bound to 30400
30300 introduced a new RECOVERYMODE config option, which we
unconditionally disable because we never patch init_boot.cpio within
the vendor_boot image.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-09-30 20:07:34 -04:00
Andrew Gunnerson 919f621833 CHANGELOG.md: Add entry for PR #517
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-09-21 19:03:34 -04:00
Andrew Gunnerson 2c1d86cd96 deny.toml: Remove outdated override for ring license
Issue: #516

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-09-21 18:52:15 -04:00
Andrew Gunnerson 91074ae4c8 Update dependencies and fix clippy 1.90 lints
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-09-21 18:51:25 -04:00
Andrew Gunnerson a5c628b66f Version 3.22.0
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 23:47:22 -04:00
Andrew Gunnerson 156c96d3d4 CHANGELOG.md: Add entry for PR #512
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 23:46:31 -04:00
Andrew Gunnerson 2460d1807d Update dependencies
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 23:24:42 -04:00
Andrew Gunnerson 728d333951 CHANGELOG.md: Add entry for PR #511
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 23:11:10 -04:00
Andrew Gunnerson 39661a994d Cargo.toml: Specify minimum supported toolchain version
Fixes: #506

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 23:08:58 -04:00
Andrew Gunnerson d6b19b69f7 CHANGELOG.md: Add entry for PR #510
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 22:58:44 -04:00
Andrew Gunnerson 96806cba36 cli: Allow skipping unpacking of images
This is useful if the file format metadata is the only thing that the
user needs.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 22:54:44 -04:00
Andrew Gunnerson 5c474a1e98 CHANGELOG.md: Add entry for PR #509
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 22:40:38 -04:00
Andrew Gunnerson 4cf546e5ca cli/payload: Compute CoW size estimates during packing
This was overlooked during the initial implementation. Payload images
using VABC, but without CoW size estimates, are unflashable outside of
recovery.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-08-27 22:06:44 -04:00
94 changed files with 1558 additions and 614 deletions
+7 -3
View File
@@ -28,8 +28,12 @@ jobs:
artifact:
- os: ubuntu-latest
name: x86_64-unknown-linux-gnu
- os: ubuntu-24.04-arm
name: aarch64-unknown-linux-gnu
- os: windows-latest
name: x86_64-pc-windows-msvc
- os: windows-11-arm
name: aarch64-pc-windows-msvc
- os: macos-latest
name: universal-apple-darwin
targets:
@@ -43,7 +47,7 @@ jobs:
android_api: '31'
steps:
- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# For git describe
fetch-depth: 0
@@ -85,7 +89,7 @@ jobs:
done
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
with:
key: ${{ matrix.artifact.name }}
@@ -156,7 +160,7 @@ jobs:
run: cp LICENSE README.md target/output/
- name: Archive executable
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: avbroot-${{ steps.get_version.outputs.version }}-${{ matrix.artifact.name }}
path: |
+2 -2
View File
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Run cargo-deny
uses: EmbarkStudios/cargo-deny-action@30f817c6f72275c6d54dc744fbca09ebc958599f # v2.0.12
uses: EmbarkStudios/cargo-deny-action@3fd3802e88374d3fe9159b834c7714ec57d6c979 # v2.0.15
+2 -2
View File
@@ -24,10 +24,10 @@ jobs:
echo "version=${version}" >> "${GITHUB_OUTPUT}"
- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Create release
uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # v2.3.2
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
tag_name: v${{ steps.get_version.outputs.version }}
name: Version ${{ steps.get_version.outputs.version }}
+69
View File
@@ -7,6 +7,47 @@
to update the actual links at the bottom of the file.
-->
### Version 3.24.1
* Update `avbroot avb verify-device --help` to mention that `ro.boot.vbmeta.public_key_digest` is used when `-p` is not specified ([Issue #554], [PR #555])
* Update dependencies ([PR #559])
### Version 3.24.0
* Always sort ramdisk cpio entries and ensure they have inode numbers assigned ([PR #540])
* Relax LP image parser's validation to allow parsing the `/metadata/gsi/dsu/dsu/lp_metadata` image used by DSU ([PR #541], [PR #545])
* Add support for devices with separate recovery partitions when using `--dsu` ([Issue #536], [PR #543])
* Fix broken symlinks in fuzzing corpus ([Issue #532], [PR #544], [PR #548])
* Ignore unused vbmeta partitions that are filled with zeros ([Issue #537], [PR #539])
* Update dependencies ([PR #547], [PR #549])
* Fix `cargo deny` failing after running fuzzers with `cargo hfuzz` ([PR #550])
### Version 3.23.3
* Add support for Magisk 30600 ([PR #529])
* Update dependencies ([PR #530])
### Version 3.23.2
* Add prebuilt binaries for aarch64 GNU/Linux ([PR #523])
* Add prebuilt binaries for aarch64 Windows ([PR #524])
### Version 3.23.1
* Add support for Magisk 30400 ([PR #521])
### Version 3.23.0
* Update dependencies and fix Rust 1.90 clippy lints ([PR #517], [PR #520])
* Add support for Magisk 30300 ([PR #519])
### Version 3.22.0
* Fix CoW size estimates not being set when running `avbroot payload pack` ([PR #509])
* Add support for only unpacking metadata in `avbroot {avb,boot,cpio,lp,payload} unpack` ([PR #510])
* Specify minimum supported compiler version for building from source ([PR #511])
* Update dependencies ([PR #512])
### Version 3.21.0
* Switch to using rawzip for zip parsing and writing ([PR #489])
@@ -409,6 +450,10 @@ Behind-the-scenes changes:
[Issue #472]: https://github.com/chenxiaolong/avbroot/issues/472
[Issue #482]: https://github.com/chenxiaolong/avbroot/issues/482
[Issue #493]: https://github.com/chenxiaolong/avbroot/issues/493
[Issue #532]: https://github.com/chenxiaolong/avbroot/issues/532
[Issue #536]: https://github.com/chenxiaolong/avbroot/issues/536
[Issue #537]: https://github.com/chenxiaolong/avbroot/issues/537
[Issue #554]: https://github.com/chenxiaolong/avbroot/issues/554
[PR #130]: https://github.com/chenxiaolong/avbroot/pull/130
[PR #132]: https://github.com/chenxiaolong/avbroot/pull/132
[PR #133]: https://github.com/chenxiaolong/avbroot/pull/133
@@ -602,3 +647,27 @@ Behind-the-scenes changes:
[PR #503]: https://github.com/chenxiaolong/avbroot/pull/503
[PR #504]: https://github.com/chenxiaolong/avbroot/pull/504
[PR #505]: https://github.com/chenxiaolong/avbroot/pull/505
[PR #509]: https://github.com/chenxiaolong/avbroot/pull/509
[PR #510]: https://github.com/chenxiaolong/avbroot/pull/510
[PR #511]: https://github.com/chenxiaolong/avbroot/pull/511
[PR #512]: https://github.com/chenxiaolong/avbroot/pull/512
[PR #517]: https://github.com/chenxiaolong/avbroot/pull/517
[PR #519]: https://github.com/chenxiaolong/avbroot/pull/519
[PR #520]: https://github.com/chenxiaolong/avbroot/pull/520
[PR #521]: https://github.com/chenxiaolong/avbroot/pull/521
[PR #523]: https://github.com/chenxiaolong/avbroot/pull/523
[PR #524]: https://github.com/chenxiaolong/avbroot/pull/524
[PR #529]: https://github.com/chenxiaolong/avbroot/pull/529
[PR #530]: https://github.com/chenxiaolong/avbroot/pull/530
[PR #539]: https://github.com/chenxiaolong/avbroot/pull/539
[PR #540]: https://github.com/chenxiaolong/avbroot/pull/540
[PR #541]: https://github.com/chenxiaolong/avbroot/pull/541
[PR #543]: https://github.com/chenxiaolong/avbroot/pull/543
[PR #544]: https://github.com/chenxiaolong/avbroot/pull/544
[PR #545]: https://github.com/chenxiaolong/avbroot/pull/545
[PR #547]: https://github.com/chenxiaolong/avbroot/pull/547
[PR #548]: https://github.com/chenxiaolong/avbroot/pull/548
[PR #549]: https://github.com/chenxiaolong/avbroot/pull/549
[PR #550]: https://github.com/chenxiaolong/avbroot/pull/550
[PR #555]: https://github.com/chenxiaolong/avbroot/pull/555
[PR #559]: https://github.com/chenxiaolong/avbroot/pull/559
Generated
+332 -364
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -4,10 +4,12 @@ members = ["avbroot", "e2e", "fuzz", "xtask"]
resolver = "2"
[workspace.package]
version = "3.21.0"
version = "3.24.1"
license = "GPL-3.0-only"
edition = "2024"
repository = "https://github.com/chenxiaolong/avbroot"
publish = false
rust-version = "1.88.0"
[workspace.lints.clippy]
cast_lossless = "deny"
+1 -1
View File
@@ -237,7 +237,7 @@ Updates to Android, Magisk, and KernelSU are all done the same way: by patching
2. If Magisk or KernelSU is being updated, first install their new `.apk`. If you happen to open the app, make sure it **does not** flash the boot image. Cancel the boot image update prompts if needed.
3. Reboot to recovery mode. If the screen is stuck at a `No command` message, press the volume up button once while holding down the power button.
3. Reboot to recovery mode: `adb reboot recovery`. If the screen is stuck at a `No command` message, press the volume up button once while holding down the power button.
4. Sideload the patched OTA with `adb sideload`.
+1 -1
View File
@@ -235,7 +235,7 @@ avbroot совместим с любым стандартным 4096-битны
2. Если обновляется Magisk или KernelSU, сначала установите их новый `.apk`. Если вы случайно открыли приложение, убедитесь, что оно **не начало** прошивать загрузочный образ. Если в самом приложении появится предложение обновить загрузочный образ, отклоните его.
3. Перезагрузитесь в режим Recovery. Если устройство повисло на сплеше с сообщением "No command", удерживайте кнопку питания, а затем нажмите кнопку увеличения громкости один раз.
3. Перезагрузитесь в режим Recovery: `adb reboot recovery`. Если устройство повисло на сплеше с сообщением "No command", удерживайте кнопку питания, а затем один раз нажмите кнопку увеличения громкости.
4. Обновитесь (Apply update from adb → `adb sideload <ota.zip.patched>`).
+7 -5
View File
@@ -4,7 +4,8 @@ version.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
publish = false
publish.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -26,13 +27,14 @@ dlv-list = "0.6.0"
flate2 = { version = "1.0.29", features = ["zlib-rs"] }
gf256 = { version = "0.3.0", features = ["rs"] }
hex = { version = "0.4.3", features = ["serde"] }
lz4_flex = "0.11.1"
lzma-rust2 = "0.10.0"
lz4_flex = "0.12.0"
lzma-rust2 = "0.15.2"
memchr = "2.6.0"
# We can't upgrade to 0.9.0 until rsa updates its dependency.
num-bigint-dig = "0.8.4"
num-traits = "0.2.16"
passterm = "2.0.3"
phf = { version = "0.12.1", features = ["macros"] }
phf = { version = "0.13.1", features = ["macros"] }
pkcs8 = { version = "0.10.2", features = ["encryption", "pem"] }
prost = "0.14.1"
# We can't upgrade to 0.9.0 until rsa updates its rand_core dependency.
@@ -51,7 +53,7 @@ sha1 = "0.10.5"
sha2 = "0.10.7"
tempfile = "3.8.0"
thiserror = "2.0.3"
toml_edit = { version = "0.23.3", features = ["serde"] }
toml = { version = "0.9.11", features = ["serde"] }
topological-sort = "0.2.2"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
+2 -7
View File
@@ -40,19 +40,14 @@ pub enum Command {
MagiskInfo(boot::MagiskInfoCli),
}
#[derive(Debug, Clone, Copy, ValueEnum)]
#[derive(Clone, Copy, Debug, Default, ValueEnum)]
pub enum LogFormat {
#[default]
Short,
Medium,
Long,
}
impl Default for LogFormat {
fn default() -> Self {
Self::Short
}
}
impl fmt::Display for LogFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.to_possible_value().ok_or(fmt::Error)?.get_name())
+9 -5
View File
@@ -78,7 +78,7 @@ fn write_avb_image(file: &File, info: &mut AvbInfo, recompute_size: bool) -> Res
fn read_info(path: &Path) -> Result<AvbInfo> {
let data = fs::read_to_string(path)
.with_context(|| format!("Failed to read AVB info TOML: {path:?}"))?;
let info = toml_edit::de::from_str(&data)
let info = toml::de::from_str(&data)
.with_context(|| format!("Failed to parse AVB info TOML: {path:?}"))?;
Ok(info)
@@ -86,7 +86,7 @@ fn read_info(path: &Path) -> Result<AvbInfo> {
/// Write AVB information to TOML file.
fn write_info(path: &Path, info: &AvbInfo) -> Result<()> {
let data = toml_edit::ser::to_string_pretty(info)
let data = toml::ser::to_string_pretty(info)
.with_context(|| format!("Failed to serialize AVB info TOML: {path:?}"))?;
fs::write(path, data).with_context(|| format!("Failed to write AVB info TOML: {path:?}"))?;
@@ -735,7 +735,7 @@ fn unpack_subcommand(cli: &UnpackCli, cancel_signal: &AtomicBool) -> Result<()>
write_info(&cli.output_info, &info)?;
if info.footer.is_some() {
if info.footer.is_some() && !cli.no_output_raw {
write_raw_and_verify(
&cli.output_raw,
&mut reader,
@@ -1025,6 +1025,10 @@ struct UnpackCli {
#[arg(long, value_name = "FILE", value_parser, default_value = "raw.img")]
output_raw: PathBuf,
/// Do not output raw image.
#[arg(long, conflicts_with = "output_raw")]
no_output_raw: bool,
/// Ignore invalid digests or FEC data.
#[arg(long)]
ignore_invalid: bool,
@@ -1165,8 +1169,8 @@ struct VerifyCli {
struct VerifyDeviceCli {
/// Path to public key in AVB binary format.
///
/// If this is not specified, the signatures can only be checked for
/// validity, not whether they are trusted.
/// If this is not specified, then the signature is verified against the
/// ro.boot.vbmeta.public_key_digest value provided by the bootloader.
#[arg(short, long, value_name = "FILE", value_parser)]
public_key: Option<PathBuf>,
+55 -13
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Andrew Gunnerson
// SPDX-FileCopyrightText: 2023-2025 Andrew Gunnerson
// SPDX-License-Identifier: GPL-3.0-only
use std::{
@@ -41,14 +41,14 @@ fn write_image(path: &Path, image: &BootImage) -> Result<()> {
fn read_header(path: &Path) -> Result<BootImage> {
let data = fs::read_to_string(path)
.with_context(|| format!("Failed to read header TOML: {path:?}"))?;
let image = toml_edit::de::from_str(&data)
let image = toml::de::from_str(&data)
.with_context(|| format!("Failed to parse header TOML: {path:?}"))?;
Ok(image)
}
fn write_header(path: &Path, image: &BootImage) -> Result<()> {
let data = toml_edit::ser::to_string_pretty(image)
let data = toml::ser::to_string_pretty(image)
.with_context(|| format!("Failed to serialize header TOML: {path:?}"))?;
fs::write(path, data).with_context(|| format!("Failed to write header TOML: {path:?}"))?;
@@ -164,30 +164,44 @@ fn unpack_subcommand(boot_cli: &BootCli, cli: &UnpackCli) -> Result<()> {
}
}
if let Some(data) = kernel {
if let Some(data) = kernel
&& !cli.no_output_kernel
{
write_data_if_not_empty(&cli.output_kernel, data)?;
}
if let Some(data) = second {
if let Some(data) = second
&& !cli.no_output_second
{
write_data_if_not_empty(&cli.output_second, data)?;
}
if let Some(data) = recovery_dtbo {
if let Some(data) = recovery_dtbo
&& !cli.no_output_recovery_dtbo
{
write_data_if_not_empty(&cli.output_recovery_dtbo, data)?;
}
if let Some(data) = dtb {
if let Some(data) = dtb
&& !cli.no_output_dtb
{
write_data_if_not_empty(&cli.output_dtb, data)?;
}
if let Some(header) = vts_signature {
if let Some(header) = vts_signature
&& !cli.no_output_vts_signature
{
write_avb_header(&cli.output_vts_signature, header)?;
}
if let Some(text) = bootconfig {
if let Some(text) = bootconfig
&& !cli.no_output_bootconfig
{
write_text_if_not_empty(&cli.output_bootconfig, text)?;
}
for (i, data) in ramdisks.iter().enumerate() {
let mut path = cli.output_ramdisk_prefix.as_os_str().to_owned();
path.push(i.to_string());
if !cli.no_output_ramdisk {
for (i, data) in ramdisks.iter().enumerate() {
let mut path = cli.output_ramdisk_prefix.as_os_str().to_owned();
path.push(i.to_string());
write_data_if_not_empty(Path::new(&path), data)?;
write_data_if_not_empty(Path::new(&path), data)?;
}
}
Ok(())
@@ -339,6 +353,10 @@ struct UnpackCli {
#[arg(long, value_name = "FILE", value_parser, default_value = "kernel.img")]
output_kernel: PathBuf,
/// Do not output kernel image.
#[arg(long, conflicts_with = "output_kernel")]
no_output_kernel: bool,
/// Path prefix for output ramdisk images.
#[arg(
long,
@@ -348,10 +366,18 @@ struct UnpackCli {
)]
output_ramdisk_prefix: PathBuf,
/// Do not output ramdisk images.
#[arg(long, conflicts_with = "output_ramdisk_prefix")]
no_output_ramdisk: bool,
/// Path to output second stage bootloader image.
#[arg(long, value_name = "FILE", value_parser, default_value = "second.img")]
output_second: PathBuf,
/// Do not output second stage bootloader image.
#[arg(long, conflicts_with = "output_second")]
no_output_second: bool,
/// Path to output recovery dtbo/acpio image.
#[arg(
long,
@@ -361,10 +387,18 @@ struct UnpackCli {
)]
output_recovery_dtbo: PathBuf,
/// Do not output recovery dtbo/acpio image.
#[arg(long, conflicts_with = "output_recovery_dtbo")]
no_output_recovery_dtbo: bool,
/// Path to output device tree blob image.
#[arg(long, value_name = "FILE", value_parser, default_value = "dtb.img")]
output_dtb: PathBuf,
/// Do not output device tree blob image.
#[arg(long, conflicts_with = "output_dtb")]
no_output_dtb: bool,
/// Path to output VTS signature.
#[arg(
long,
@@ -374,6 +408,10 @@ struct UnpackCli {
)]
output_vts_signature: PathBuf,
/// Do not output VTS signature.
#[arg(long, conflicts_with = "output_vts_signature")]
no_output_vts_signature: bool,
/// Path to output bootconfig text.
#[arg(
long,
@@ -382,6 +420,10 @@ struct UnpackCli {
default_value = "bootconfig.txt"
)]
output_bootconfig: PathBuf,
/// Do not output bootconfig text.
#[arg(long, conflicts_with = "output_bootconfig")]
no_output_bootconfig: bool,
}
/// Pack a boot image.
+19 -13
View File
@@ -73,7 +73,7 @@ fn flush_writer(writer: CpioWriter<CompressedWriter<BufWriter<File>>>) -> Result
fn read_info(path: &Path) -> Result<CpioInfo> {
let data = fs::read_to_string(path)
.with_context(|| format!("Failed to read cpio info TOML: {path:?}"))?;
let info = toml_edit::de::from_str(&data)
let info = toml::de::from_str(&data)
.with_context(|| format!("Failed to parse cpio info TOML: {path:?}"))?;
Ok(info)
@@ -81,7 +81,7 @@ fn read_info(path: &Path) -> Result<CpioInfo> {
/// Write cpio information to TOML file.
fn write_info(path: &Path, info: &CpioInfo) -> Result<()> {
let data = toml_edit::ser::to_string_pretty(info)
let data = toml::ser::to_string_pretty(info)
.with_context(|| format!("Failed to serialize cpio info TOML: {path:?}"))?;
fs::write(path, data).with_context(|| format!("Failed to write cpio info TOML: {path:?}"))?;
@@ -170,22 +170,24 @@ fn unpack_subcommand(
display_format(cpio_cli, format);
fs::create_dir_all(&cli.output_tree)
.with_context(|| format!("Failed to create directory: {:?}", cli.output_tree))?;
if !cli.no_output_tree {
fs::create_dir_all(&cli.output_tree)
.with_context(|| format!("Failed to create directory: {:?}", cli.output_tree))?;
while let Some(entry) = reader.next_entry().context("Failed to read cpio entry")? {
display_entry(cpio_cli, &entry);
while let Some(entry) = reader.next_entry().context("Failed to read cpio entry")? {
display_entry(cpio_cli, &entry);
if let Some(mut writer) = create_tree_file(&cli.output_tree, &entry)? {
let file_size = entry.data.size()?;
if let Some(mut writer) = create_tree_file(&cli.output_tree, &entry)? {
let file_size = entry.data.size()?;
stream::copy_n(&mut reader, &mut writer, file_size.into(), cancel_signal)
.context("Failed to copy data")?;
stream::copy_n(&mut reader, &mut writer, file_size.into(), cancel_signal)
.context("Failed to copy data")?;
writer.into_inner().context("Failed to flush data")?;
writer.into_inner().context("Failed to flush data")?;
}
info.entries.push(entry);
}
info.entries.push(entry);
}
write_info(&cli.output_info, &info)?;
@@ -300,6 +302,10 @@ struct UnpackCli {
/// Path to output files directory.
#[arg(long, value_name = "DIR", value_parser, default_value = "cpio_tree")]
output_tree: PathBuf,
/// Do not output files.
#[arg(long, conflicts_with = "output_tree")]
no_output_tree: bool,
}
/// Pack a cpio archive.
+7 -3
View File
@@ -50,14 +50,14 @@ fn open_lp_outputs(paths: &[impl AsRef<Path>]) -> Result<Vec<File>> {
fn read_info(path: &Path) -> Result<Metadata> {
let data = fs::read_to_string(path)
.with_context(|| format!("Failed to read metadata info TOML: {path:?}"))?;
let info = toml_edit::de::from_str(&data)
let info = toml::de::from_str(&data)
.with_context(|| format!("Failed to parse metadata info TOML: {path:?}"))?;
Ok(info)
}
fn write_info(path: &Path, metadata: &Metadata) -> Result<()> {
let data = toml_edit::ser::to_string_pretty(metadata)
let data = toml::ser::to_string_pretty(metadata)
.with_context(|| format!("Failed to serialize metadata info TOML: {path:?}"))?;
fs::write(path, data)
.with_context(|| format!("Failed to write metadata info TOML: {path:?}"))?;
@@ -179,7 +179,7 @@ fn unpack_subcommand(lp_cli: &LpCli, cli: &UnpackCli, cancel_signal: &AtomicBool
write_info(&cli.output_info, &metadata)?;
// For empty images, there's no data to unpack.
if metadata.image_type == ImageType::Empty {
if metadata.image_type == ImageType::Empty || cli.no_output_images {
return Ok(());
}
@@ -535,6 +535,10 @@ struct UnpackCli {
#[arg(long, value_name = "DIR", value_parser, default_value = "lp_images")]
output_images: PathBuf,
/// Do not output images.
#[arg(long, conflicts_with = "output_images")]
no_output_images: bool,
/// The LP metadata slot to use.
///
/// This slot is the only slot where data extents are copied from. Any data
+32 -3
View File
@@ -78,6 +78,23 @@ bitflags! {
}
}
fn is_zero_sha256(mut size: u64, digest: &[u8]) -> bool {
if digest.len() != ring::digest::SHA256_OUTPUT_LEN {
return false;
}
let mut context = ring::digest::Context::new(&ring::digest::SHA256);
while size > 0 {
let n = size.min(util::ZEROS.len() as u64);
context.update(&util::ZEROS[..n as usize]);
size -= n;
}
let zero_digest = context.finish();
zero_digest.as_ref() == digest
}
/// Get the images required for patching. If [`RequiredFlags::SYSTEM`] is
/// specified, then the system image is included. If [`RequiredFlags::ALL_COW`]
/// is specified, then all images with CoW size estimates are included.
@@ -96,6 +113,18 @@ pub fn get_required_images(
} else if required_flags.contains(RequiredFlags::SYSTEM) && name == "system" {
flags |= PartitionFlags::SYSTEM;
} else if name.starts_with("vbmeta") {
let Some(pi) = &partition.new_partition_info else {
continue;
};
// Some devices seem to ship with empty unused vbmeta partitions.
// Use the SHA-256 checksum to skip them so we don't have to extract
// them to check.
let size = pi.size();
if (4096..=65536).contains(&size) && is_zero_sha256(size, pi.hash()) {
continue;
}
flags |= PartitionFlags::VBMETA;
}
@@ -830,7 +859,7 @@ pub fn compress_image(
/// Recompute the CoW estimate for an image and update the OTA manifest
/// partition entry appropriately. The input file is not modified.
fn recow_image(
pub fn recow_image(
name: &str,
file: &File,
header: &mut PayloadHeader,
@@ -2066,10 +2095,10 @@ pub fn verify_subcommand(cli: &VerifyCli, cancel_signal: &AtomicBool) -> Result<
}
}
let boot_images = boot::load_boot_images(&boot_image_names, &Opener(temp_dir.path()))
let (boot_images, layout) = boot::load_boot_images(&boot_image_names, &Opener(temp_dir.path()))
.context("Failed to load all boot images")?;
let targets = OtaCertPatcher::new(ota_cert.clone())
.find_targets(&boot_images, cancel_signal)
.find_targets(layout, &boot_images, cancel_signal)
.context("Failed to find boot image containing otacerts.zip")?;
if targets.is_empty() {
+45 -19
View File
@@ -52,14 +52,14 @@ fn open_writer(
fn read_info(path: &Path) -> Result<PayloadHeader> {
let data = fs::read_to_string(path)
.with_context(|| format!("Failed to read payload info TOML: {path:?}"))?;
let info = toml_edit::de::from_str(&data)
let info = toml::de::from_str(&data)
.with_context(|| format!("Failed to parse payload info TOML: {path:?}"))?;
Ok(info)
}
fn write_info(path: &Path, manifest: &PayloadHeader) -> Result<()> {
let data = toml_edit::ser::to_string_pretty(manifest)
let data = toml::ser::to_string_pretty(manifest)
.with_context(|| format!("Failed to serialize payload info TOML: {path:?}"))?;
fs::write(path, data)
.with_context(|| format!("Failed to write payload info TOML: {path:?}"))?;
@@ -113,24 +113,26 @@ fn unpack_subcommand(
write_info(&cli.output_info, &header)?;
fs::create_dir_all(&cli.output_images)
.with_context(|| format!("Failed to create directory: {:?}", cli.output_images))?;
if !cli.no_output_images {
fs::create_dir_all(&cli.output_images)
.with_context(|| format!("Failed to create directory: {:?}", cli.output_images))?;
ota::extract_payload(
&reader.into_inner(),
&cli.output_images,
0,
payload_size,
&header,
&header
.manifest
.partitions
.iter()
.map(|p| &p.partition_name)
.cloned()
.collect(),
cancel_signal,
)?;
ota::extract_payload(
&reader.into_inner(),
&cli.output_images,
0,
payload_size,
&header,
&header
.manifest
.partitions
.iter()
.map(|p| &p.partition_name)
.cloned()
.collect(),
cancel_signal,
)?;
}
Ok(())
}
@@ -160,6 +162,26 @@ fn pack_subcommand(
})
.collect::<Result<HashMap<_, _>>>()?;
for (name, input_file) in &input_files {
let Some(dpm) = &header.manifest.dynamic_partition_metadata else {
continue;
};
if !dpm.groups.iter().any(|g| g.partition_names.contains(name)) {
continue;
}
header
.manifest
.partitions
.iter_mut()
.find(|p| p.partition_name == *name)
.unwrap()
.estimate_cow_size = Some(0);
ota::recow_image(name, input_file, &mut header, cancel_signal)?;
}
// Compress the images and compute the list of install operations for
// insertion into the payload header. The compressed data is stored in new
// temp files and the original input files are dropped.
@@ -366,6 +388,10 @@ struct UnpackCli {
default_value = "payload_images"
)]
output_images: PathBuf,
/// Do not output images.
#[arg(long, conflicts_with = "output_images")]
no_output_images: bool,
}
/// Pack a payload binary.
+2 -2
View File
@@ -151,11 +151,11 @@ mod tests {
contents.extend("💩".as_bytes());
let data = TestData { contents };
let serialized = toml_edit::ser::to_string(&data).unwrap();
let serialized = toml::ser::to_string(&data).unwrap();
assert_eq!(serialized, "contents = 'foo\\xFFbar💩'\n");
let new_data: TestData = toml_edit::de::from_str(&serialized).unwrap();
let new_data: TestData = toml::de::from_str(&serialized).unwrap();
assert_eq!(data.contents, new_data.contents);
}
}
+8 -8
View File
@@ -9,7 +9,7 @@ use flate2::{
write::{DeflateEncoder, GzEncoder},
};
use lz4_flex::frame::FrameDecoder;
use lzma_rust2::{CheckType, XZOptions, XZReader, XZWriter};
use lzma_rust2::{CheckType, XzOptions, XzReader, XzWriter};
use serde::{Deserialize, Serialize};
use thiserror::Error;
@@ -121,8 +121,8 @@ pub enum CompressedReader<R: Read> {
Deflate(DeflateDecoder<R>),
Gzip(GzDecoder<R>),
Lz4(FrameDecoder<R>),
/// Boxed because the [`XZReader`] is nearly 4 KiB.
Xz(Box<XZReader<R>>),
/// Boxed because the [`XzReader`] is nearly 4 KiB.
Xz(Box<XzReader<R>>),
}
impl<R: Read> CompressedReader<R> {
@@ -132,7 +132,7 @@ impl<R: Read> CompressedReader<R> {
CompressedFormat::Deflate => Self::Deflate(DeflateDecoder::new(reader)),
CompressedFormat::Gzip => Self::Gzip(GzDecoder::new(reader)),
CompressedFormat::Lz4Legacy => Self::Lz4(FrameDecoder::new(reader)),
CompressedFormat::Xz => Self::Xz(Box::new(XZReader::new(reader, false))),
CompressedFormat::Xz => Self::Xz(Box::new(XzReader::new(reader, false))),
}
}
@@ -168,7 +168,7 @@ impl<R: Read + Seek> CompressedReader<R> {
} else if &magic[0..4] == LZ4_LEGACY_MAGIC {
Ok(Self::Lz4(FrameDecoder::new(reader)))
} else if &magic == XZ_MAGIC {
Ok(Self::Xz(Box::new(XZReader::new(reader, false))))
Ok(Self::Xz(Box::new(XzReader::new(reader, false))))
} else if raw_if_unknown {
Ok(Self::None(reader))
} else {
@@ -195,7 +195,7 @@ pub enum CompressedWriter<W: Write> {
Deflate(DeflateEncoder<W>),
Gzip(GzEncoder<W>),
Lz4Legacy(Lz4LegacyEncoder<W>),
Xz(XZWriter<W>),
Xz(XzWriter<W>),
}
impl<W: Write> CompressedWriter<W> {
@@ -215,10 +215,10 @@ impl<W: Write> CompressedWriter<W> {
}
CompressedFormat::Xz => {
// Some kernels are compiled without support for the default CRC64.
let mut options = XZOptions::with_preset(6);
let mut options = XzOptions::with_preset(6);
options.set_check_sum_type(CheckType::Crc32);
let xz_writer = XZWriter::new(writer, options).map_err(Error::XzInit)?;
let xz_writer = XzWriter::new(writer, options).map_err(Error::XzInit)?;
Ok(Self::Xz(xz_writer))
}
}
+57 -2
View File
@@ -775,8 +775,8 @@ pub fn assign_inodes(entries: &mut [CpioEntry], missing_only: bool) -> Result<()
// (dev maj, dev min) -> (inode set, last assigned inode)
let mut inodes: HashMap<(u32, u32), (HashSet<u32>, u32)> = HashMap::new();
if missing_only {
for entry in &mut *entries {
for entry in &mut *entries {
if missing_only {
if entry.inode != 0 {
let key = (entry.dev_maj, entry.dev_min);
let (set, last) = inodes.entry(key).or_default();
@@ -784,6 +784,8 @@ pub fn assign_inodes(entries: &mut [CpioEntry], missing_only: bool) -> Result<()
set.insert(entry.inode);
*last = (*last).max(entry.inode);
}
} else {
entry.inode = 0;
}
}
@@ -835,3 +837,56 @@ pub fn save(
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_assign_inodes_missing() {
let mut entries = [
CpioEntry::new_directory(b"a", 0o755),
CpioEntry::new_directory(b"b", 0o755),
CpioEntry::new_directory(b"c", 0o755),
CpioEntry::new_directory(b"d", 0o755),
CpioEntry::new_directory(b"e", 0o755),
];
entries[0].inode = 999;
entries[2].inode = 500;
entries[3].dev_maj = 1;
entries[3].dev_min = 1;
assign_inodes(&mut entries, true).unwrap();
assert_eq!(entries[0].inode, 999);
assert_eq!(entries[1].inode, 1000);
assert_eq!(entries[2].inode, 500);
assert_eq!(entries[3].inode, 300000);
assert_eq!(entries[4].inode, 1001);
}
#[test]
fn test_assign_inodes_reassign() {
let mut entries = [
CpioEntry::new_directory(b"a", 0o755),
CpioEntry::new_directory(b"b", 0o755),
CpioEntry::new_directory(b"c", 0o755),
CpioEntry::new_directory(b"d", 0o755),
CpioEntry::new_directory(b"e", 0o755),
];
entries[0].dev_maj = 1;
entries[0].dev_min = 1;
entries[0].inode = 1000;
entries[1].inode = 1000;
entries[2].inode = 500;
entries[3].dev_maj = 1;
entries[3].dev_min = 1;
assign_inodes(&mut entries, false).unwrap();
assert_eq!(entries[0].inode, 300000);
assert_eq!(entries[1].inode, 300000);
assert_eq!(entries[2].inode, 300001);
assert_eq!(entries[3].inode, 300001);
}
}
+16 -34
View File
@@ -54,7 +54,7 @@ const PARTITION_RESERVED_BYTES: u32 = 4096;
/// Maximum allowed size of [`RawGeometry::metadata_max_size`] to prevent the
/// memory usage from blowing up.
const METADATA_MAX_SIZE: u32 = 128 * 1024;
const METADATA_MAX_SIZE: u32 = 512 * 1024;
#[derive(Debug, Error)]
pub enum Error {
@@ -118,8 +118,6 @@ pub enum Error {
},
#[error("Partition {name:?}: Extent indices too large")]
PartitionExtentIndicesTooLarge { name: DebugString },
#[error("Partition {name:?}: Extent indices set on empty image")]
PartitionExtentIndicesEmptyImage { name: DebugString },
#[error("Partition {name:?}: Extent index too large")]
PartitionExtentIndexTooLarge { name: DebugString },
#[error("Partition {name:?}: Extent count too large")]
@@ -674,7 +672,6 @@ impl RawPartition {
/// [`RawPartitionGroup::validate`] do not.
fn validate(
&self,
image_type: ImageType,
header: &RawHeader,
extents: &[RawExtent],
groups: &[RawPartitionGroup],
@@ -695,26 +692,15 @@ impl RawPartition {
});
}
match image_type {
ImageType::Normal => {
if self
.first_extent_index
.get()
.checked_add(self.num_extents.get())
.is_none_or(|n| n as usize > extents.len())
{
return Err(Error::PartitionExtentIndicesTooLarge {
name: DebugString::new(self.name),
});
}
}
ImageType::Empty => {
if self.first_extent_index.get() != 0 || self.num_extents.get() != 0 {
return Err(Error::PartitionExtentIndicesEmptyImage {
name: DebugString::new(self.name),
});
}
}
if self
.first_extent_index
.get()
.checked_add(self.num_extents.get())
.is_none_or(|n| n as usize > extents.len())
{
return Err(Error::PartitionExtentIndicesTooLarge {
name: DebugString::new(self.name),
});
}
if self.group_index.get() as usize >= groups.len() {
@@ -971,7 +957,7 @@ struct RawMetadataSlot {
impl RawMetadataSlot {
/// Ensure that all fields are semantically valid and can be used without
/// further checks.
fn validate(&self, image_type: ImageType, geometry: &RawGeometry) -> Result<()> {
fn validate(&self, geometry: &RawGeometry) -> Result<()> {
self.header.validate(geometry)?;
for (len, descriptor, name) in [
@@ -1032,7 +1018,7 @@ impl RawMetadataSlot {
}
for partition in &self.partitions {
partition.validate(image_type, &self.header, &self.extents, &self.groups)?;
partition.validate(&self.header, &self.extents, &self.groups)?;
}
for (i, group) in self.groups.iter().enumerate() {
@@ -1111,11 +1097,7 @@ impl RawMetadata {
/// Read a single [`RawMetadataSlot`], including the header and all tables.
/// This does not read the extra padding between the end of the last table
/// and [`RawGeometry::metadata_max_size`].
fn read_metadata(
mut reader: impl Read,
image_type: ImageType,
geometry: &RawGeometry,
) -> Result<RawMetadataSlot> {
fn read_metadata(mut reader: impl Read, geometry: &RawGeometry) -> Result<RawMetadataSlot> {
let mut header = RawHeader::new_zeroed();
reader
@@ -1155,7 +1137,7 @@ impl RawMetadata {
block_devices: block_devices.to_vec(),
};
slot.validate(image_type, geometry)?;
slot.validate(geometry)?;
Ok(slot)
}
@@ -1194,7 +1176,7 @@ impl RawMetadata {
}
}
slot.validate(self.image_type, &self.geometry)?;
slot.validate(&self.geometry)?;
}
Ok(())
@@ -1229,7 +1211,7 @@ impl<R: Read> FromReader<R> for RawMetadata {
.stream_position()
.map_err(|e| Error::DataRead("orig_offset", e))?;
match Self::read_metadata(&mut reader, image_type, &geometry) {
match Self::read_metadata(&mut reader, &geometry) {
Ok(m) => *slot = Some(m),
Err(e @ Error::DataRead(_, _)) => return Err(e),
Err(e) => last_err = Some(e),
+4 -4
View File
@@ -15,7 +15,7 @@ use base64::Engine;
use base64::engine::general_purpose::STANDARD;
use bzip2::write::BzDecoder;
use flate2::{Compression, write::GzEncoder};
use lzma_rust2::{CheckType, XZOptions, XZReader, XZWriter};
use lzma_rust2::{CheckType, XzOptions, XzReader, XzWriter};
use num_traits::CheckedAdd;
use prost::Message;
use rayon::{
@@ -814,7 +814,7 @@ pub fn apply_operation(
// reader and read till EOF.
let limited_reader = (&mut *reader).take(data_length);
let hashing_reader = HashingReader::new(limited_reader, hasher);
let mut decoder = XZReader::new(hashing_reader, false);
let mut decoder = XzReader::new(hashing_reader, false);
stream::copy(&mut decoder, &mut *writer, cancel_signal)
.map_err(error_fn)?;
@@ -922,9 +922,9 @@ fn compress_chunk(raw_data: &[u8], cancel_signal: &AtomicBool) -> Result<(Vec<u8
// decompression. Also, we intentionally pick the lowest compression level
// since we primarily care about squishing zeros. The non-zero portions of
// boot images are usually already-compressed kernels and ramdisks.
let mut options = XZOptions::with_preset(0);
let mut options = XzOptions::with_preset(0);
options.set_check_sum_type(CheckType::None);
let mut xz_writer = XZWriter::new(hashing_writer, options).map_err(Error::XzInit)?;
let mut xz_writer = XzWriter::new(hashing_writer, options).map_err(Error::XzInit)?;
stream::copy_n(reader, &mut xz_writer, raw_data.len() as u64, cancel_signal)
.map_err(Error::XzCompress)?;
+5 -5
View File
@@ -520,14 +520,14 @@ impl ChunkList {
// Find the chunk to insert before. We save the last used index to
// optimize for sequential insertion and avoid needing to search the
// entire list every time.
let mut insert_before = self.chunks.front_index();
if let Some(last_used) = self.last_used
let mut insert_before = if let Some(last_used) = self.last_used
&& chunk.bounds.start >= self.chunks.get(last_used).unwrap().bounds.start
{
// The new chunk starts after the last used chunk.
insert_before = Some(last_used);
}
Some(last_used)
} else {
self.chunks.front_index()
};
while let Some(index) = insert_before {
if self.chunks.get(index).unwrap().bounds.start >= chunk.bounds.start {
-22
View File
@@ -330,28 +330,6 @@ struct ZipLocalHeader {
extra_field_len: little_endian::U16,
}
#[derive(Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
#[repr(C, packed)]
struct ZipCentralHeader {
pub signature: little_endian::U32,
pub version_made_by: little_endian::U16,
pub version_needed: little_endian::U16,
pub flags: little_endian::U16,
pub compression_method: little_endian::U16,
pub last_mod_time: little_endian::U16,
pub last_mod_date: little_endian::U16,
pub crc32: little_endian::U32,
pub compressed_size: little_endian::U32,
pub uncompressed_size: little_endian::U32,
pub file_name_len: little_endian::U16,
pub extra_field_len: little_endian::U16,
pub file_comment_len: little_endian::U16,
pub disk_number_start: little_endian::U16,
pub internal_file_attrs: little_endian::U16,
pub external_file_attrs: little_endian::U32,
pub local_header_offset: little_endian::U32,
}
/// Convert a streaming zip into a non-streaming one. If any entry uses ZIP64,
/// the local header must contain an [`ExtraFieldId::ANDROID_ZIP_ALIGNMENT`]
/// extra field with sufficient size (16 bytes to be safe). This is used as
+1 -1
View File
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2023 Andrew Gunnerson
// SPDX-License-Identifier: GPL-3.0-only
//! Hack to format an integer as an octal string because toml_edit can't output
//! Hack to format an integer as an octal string because toml can't output
//! octal-formatted integers and many other toml parsers can't parse it either.
use std::{
+119 -44
View File
@@ -16,7 +16,7 @@ use std::{
};
use bstr::ByteSlice;
use lzma_rust2::{CheckType, XZOptions, XZWriter};
use lzma_rust2::{CheckType, XzOptions, XzWriter};
use rawzip::{RECOMMENDED_BUFFER_SIZE, ZipArchive};
use rayon::iter::{IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator};
use regex::bytes::Regex;
@@ -139,10 +139,13 @@ fn load_ramdisk(
}
fn save_ramdisk(
entries: &[CpioEntry],
entries: &mut [CpioEntry],
format: CompressedFormat,
cancel_signal: &AtomicBool,
) -> Result<Vec<u8>> {
cpio::sort(entries);
cpio::assign_inodes(entries, false).map_err(Error::RamdiskSaveCpio)?;
let raw_writer = Cursor::new(vec![]);
let mut writer =
CompressedWriter::new(raw_writer, format).map_err(Error::RamdiskSaveCompression)?;
@@ -156,6 +159,12 @@ fn save_ramdisk(
Ok(raw_writer.into_inner())
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct BootLayoutInfo {
pub has_recovery: bool,
}
#[derive(Clone, Eq, PartialEq)]
pub struct BootImageInfo {
pub header: Header,
pub footer: Footer,
@@ -171,11 +180,17 @@ pub trait BootImagePatch {
/// can be inspected, but during patching, only the boot image is available.
fn find_targets<'a>(
&self,
layout: BootLayoutInfo,
boot_images: &HashMap<&'a str, BootImageInfo>,
cancel_signal: &AtomicBool,
) -> TargetsResult<Vec<&'a str>>;
fn patch(&self, boot_image: &mut BootImage, cancel_signal: &AtomicBool) -> Result<()>;
fn patch(
&self,
layout: BootLayoutInfo,
boot_image: &mut BootImage,
cancel_signal: &AtomicBool,
) -> Result<()>;
}
/// Root a boot image with Magisk.
@@ -196,11 +211,12 @@ impl MagiskRootPatcher {
// replaced by PREINITDEVICE
// - Versions newer than the latest supported version are assumed to support
// the same features as the latest version
const VERS_SUPPORTED: &'static [Range<u32>] = &[25102..25207, 25211..30300];
const VERS_SUPPORTED: &'static [Range<u32>] = &[25102..25207, 25211..30700];
const VER_PREINIT_DEVICE: RangeFrom<u32> = 25211..;
const VER_RANDOM_SEED: Range<u32> = 25211..26103;
const VER_PATCH_VBMETA: Range<u32> = Self::VERS_SUPPORTED[0].start..26202;
const VER_XZ_BACKUP: RangeFrom<u32> = 26403..;
const VER_VENDOR_BOOT: RangeFrom<u32> = 30300..;
const ZIP_INIT_LD: &'static str = "lib/arm64-v8a/libinit-ld.so";
const ZIP_LIBMAGISK: &'static str = "lib/arm64-v8a/libmagisk.so";
@@ -301,11 +317,11 @@ impl MagiskRootPatcher {
}
fn xz_compress(name: &[u8], reader: impl Read, cancel_signal: &AtomicBool) -> Result<Vec<u8>> {
let mut options = XZOptions::with_preset(9);
let mut options = XzOptions::with_preset(9);
options.set_check_sum_type(CheckType::None);
let raw_writer = Cursor::new(Vec::new());
let mut writer = XZWriter::new(raw_writer, options).map_err(Error::XzInit)?;
let mut writer = XzWriter::new(raw_writer, options).map_err(Error::XzInit)?;
let raw_writer = stream::copy(reader, &mut writer, cancel_signal)
.and_then(|_| writer.finish())
@@ -391,15 +407,15 @@ impl MagiskRootPatcher {
let mut new_path = b".backup/".to_vec();
new_path.extend(&old_entry.path);
let mut new_data = None;
if xz_compress && let CpioEntryData::Data(data) = &old_entry.data {
let new_data = if xz_compress && let CpioEntryData::Data(data) = &old_entry.data {
new_path.extend(b".xz");
let reader = Cursor::new(data);
let buf = Self::xz_compress(&new_path, reader, cancel_signal)?;
new_data = Some(CpioEntryData::Data(buf));
}
Some(CpioEntryData::Data(buf))
} else {
None
};
new_entries.push(CpioEntry {
path: new_path,
@@ -436,6 +452,7 @@ impl BootImagePatch for MagiskRootPatcher {
fn find_targets<'a>(
&self,
_layout: BootLayoutInfo,
boot_images: &HashMap<&'a str, BootImageInfo>,
_cancel_signal: &AtomicBool,
) -> TargetsResult<Vec<&'a str>> {
@@ -450,7 +467,12 @@ impl BootImagePatch for MagiskRootPatcher {
Ok(targets)
}
fn patch(&self, boot_image: &mut BootImage, cancel_signal: &AtomicBool) -> Result<()> {
fn patch(
&self,
_layout: BootLayoutInfo,
boot_image: &mut BootImage,
cancel_signal: &AtomicBool,
) -> Result<()> {
// Load the first ramdisk. If it doesn't exist, we have to generate one
// from scratch.
let ramdisk = match boot_image {
@@ -586,6 +608,13 @@ impl BootImagePatch for MagiskRootPatcher {
magisk_config.push_str("RECOVERYMODE=false\n");
// We never install Magisk into the init_boot.cpio within the
// vendor_boot ramdisk. This config option was introduced in commit
// 742913ebcb10cf819a54699497359535047874f7.
if Self::VER_VENDOR_BOOT.contains(&self.version) {
magisk_config.push_str("VENDORBOOT=false\n");
}
if Self::VER_PREINIT_DEVICE.contains(&self.version)
&& let Some(device) = &self.preinit_device
{
@@ -611,9 +640,7 @@ impl BootImagePatch for MagiskRootPatcher {
));
// Repack ramdisk.
cpio::sort(&mut entries);
cpio::assign_inodes(&mut entries, false).map_err(Error::RamdiskSaveCpio)?;
let new_ramdisk = save_ramdisk(&entries, ramdisk_format, cancel_signal)?;
let new_ramdisk = save_ramdisk(&mut entries, ramdisk_format, cancel_signal)?;
match boot_image {
BootImage::V0Through2(b) => b.ramdisk = new_ramdisk,
@@ -724,7 +751,7 @@ impl OtaCertPatcher {
entry.data = CpioEntryData::Data(zip.to_vec());
// Repack ramdisk.
*ramdisk = save_ramdisk(&entries, ramdisk_format, cancel_signal)?;
*ramdisk = save_ramdisk(&mut entries, ramdisk_format, cancel_signal)?;
Ok(true)
}
@@ -737,6 +764,7 @@ impl BootImagePatch for OtaCertPatcher {
fn find_targets<'a>(
&self,
_layout: BootLayoutInfo,
boot_images: &HashMap<&'a str, BootImageInfo>,
cancel_signal: &AtomicBool,
) -> TargetsResult<Vec<&'a str>> {
@@ -769,7 +797,12 @@ impl BootImagePatch for OtaCertPatcher {
Ok(targets)
}
fn patch(&self, boot_image: &mut BootImage, cancel_signal: &AtomicBool) -> Result<()> {
fn patch(
&self,
_layout: BootLayoutInfo,
boot_image: &mut BootImage,
cancel_signal: &AtomicBool,
) -> Result<()> {
let ramdisks = match boot_image {
BootImage::V0Through2(b) => slice::from_mut(&mut b.ramdisk),
BootImage::V3Through4(b) => slice::from_mut(&mut b.ramdisk),
@@ -808,34 +841,49 @@ impl DsuPubKeyPatcher {
const FIRST_STAGE_PATH: &'static [u8] = b"first_stage_ramdisk";
const DSU_KEYS_PATH: &'static [u8] = b"first_stage_ramdisk/avb";
const AVBROOT_KEY_PATH: &'static [u8] = b"first_stage_ramdisk/avb/avbroot.avbpubkey";
const RECOVERY_DSU_KEYS_PATH: &'static [u8] = b"avb";
const RECOVERY_AVBROOT_KEY_PATH: &'static [u8] = b"avb/avbroot.avbpubkey";
pub fn new(key: RsaPublicKey) -> Self {
Self { key }
}
fn patch_ramdisk(&self, ramdisk: &mut Vec<u8>, cancel_signal: &AtomicBool) -> Result<bool> {
fn patch_ramdisk(
&self,
layout: BootLayoutInfo,
ramdisk: &mut Vec<u8>,
cancel_signal: &AtomicBool,
) -> Result<bool> {
let (mut entries, ramdisk_format) = load_ramdisk(ramdisk, cancel_signal)?;
if !entries.iter_mut().any(|e| e.path == Self::FIRST_STAGE_PATH) {
return Ok(false);
}
if !entries.iter().any(|e| e.path == Self::DSU_KEYS_PATH) {
entries.push(CpioEntry::new_directory(Self::DSU_KEYS_PATH, 0o755));
let (dsu_keys_path, avbroot_key_path) = if layout.has_recovery {
(
Self::RECOVERY_DSU_KEYS_PATH,
Self::RECOVERY_AVBROOT_KEY_PATH,
)
} else {
(Self::DSU_KEYS_PATH, Self::AVBROOT_KEY_PATH)
};
debug!("DSU key path: {:?}", avbroot_key_path.as_bstr());
if !entries.iter().any(|e| e.path == dsu_keys_path) {
entries.push(CpioEntry::new_directory(dsu_keys_path, 0o755));
}
let binary_key = avb::encode_public_key(&self.key).map_err(Error::AvbEncodeKey)?;
let data = CpioEntryData::Data(binary_key);
if let Some(e) = entries
.iter_mut()
.find(|e| e.path == Self::AVBROOT_KEY_PATH)
{
if let Some(e) = entries.iter_mut().find(|e| e.path == avbroot_key_path) {
e.data = data;
} else {
entries.push(CpioEntry::new_file(Self::AVBROOT_KEY_PATH, 0o644, data));
entries.push(CpioEntry::new_file(avbroot_key_path, 0o644, data));
}
*ramdisk = save_ramdisk(&entries, ramdisk_format, cancel_signal)?;
*ramdisk = save_ramdisk(&mut entries, ramdisk_format, cancel_signal)?;
Ok(true)
}
@@ -848,6 +896,7 @@ impl BootImagePatch for DsuPubKeyPatcher {
fn find_targets<'a>(
&self,
layout: BootLayoutInfo,
boot_images: &HashMap<&'a str, BootImageInfo>,
cancel_signal: &AtomicBool,
) -> TargetsResult<Vec<&'a str>> {
@@ -861,6 +910,12 @@ impl BootImagePatch for DsuPubKeyPatcher {
BootImage::VendorV3Through4(b) => &b.ramdisks,
};
let dsu_keys_path = if layout.has_recovery {
Self::RECOVERY_DSU_KEYS_PATH
} else {
Self::DSU_KEYS_PATH
};
for ramdisk in ramdisks {
if ramdisk.is_empty() {
continue;
@@ -871,10 +926,12 @@ impl BootImagePatch for DsuPubKeyPatcher {
let mut found = false;
for entry in entries {
if entry.path == Self::DSU_KEYS_PATH {
if entry.path == dsu_keys_path {
dsu_keys_targets.push(name);
found = true;
} else if entry.path == Self::FIRST_STAGE_PATH {
// This exists even on devices with recovery partitions.
// init just doesn't switch root to it.
first_stage_targets.push(name);
found = true;
}
@@ -908,7 +965,12 @@ impl BootImagePatch for DsuPubKeyPatcher {
}
}
fn patch(&self, boot_image: &mut BootImage, cancel_signal: &AtomicBool) -> Result<()> {
fn patch(
&self,
layout: BootLayoutInfo,
boot_image: &mut BootImage,
cancel_signal: &AtomicBool,
) -> Result<()> {
let ramdisks = match boot_image {
BootImage::V0Through2(b) => slice::from_mut(&mut b.ramdisk),
BootImage::V3Through4(b) => slice::from_mut(&mut b.ramdisk),
@@ -920,7 +982,7 @@ impl BootImagePatch for DsuPubKeyPatcher {
continue;
}
if self.patch_ramdisk(ramdisk, cancel_signal)? {
if self.patch_ramdisk(layout, ramdisk, cancel_signal)? {
return Ok(());
}
}
@@ -1005,6 +1067,7 @@ impl BootImagePatch for PrepatchedImagePatcher {
fn find_targets<'a>(
&self,
_layout: BootLayoutInfo,
boot_images: &HashMap<&'a str, BootImageInfo>,
_cancel_signal: &AtomicBool,
) -> TargetsResult<Vec<&'a str>> {
@@ -1029,7 +1092,12 @@ impl BootImagePatch for PrepatchedImagePatcher {
Ok(targets)
}
fn patch(&self, boot_image: &mut BootImage, _cancel_signal: &AtomicBool) -> Result<()> {
fn patch(
&self,
_layout: BootLayoutInfo,
boot_image: &mut BootImage,
_cancel_signal: &AtomicBool,
) -> Result<()> {
let prepatched_image = self.load_prepatched_image()?;
// Level 0: Warnings that don't affect booting
@@ -1278,10 +1346,10 @@ pub trait BootImageOpener {
pub fn load_boot_images<'a>(
names: &[&'a str],
opener: &(dyn BootImageOpener + Sync),
) -> TargetsResult<HashMap<&'a str, BootImageInfo>> {
) -> TargetsResult<(HashMap<&'a str, BootImageInfo>, BootLayoutInfo)> {
let parent_span = Span::current();
names
let images = names
.par_iter()
.map(|&name| {
let _span = debug_span!(parent: &parent_span, "image", name).entered();
@@ -1294,7 +1362,13 @@ pub fn load_boot_images<'a>(
Ok((name, info))
})
.collect()
.collect::<TargetsResult<HashMap<_, _>>>()?;
let layout = BootLayoutInfo {
has_recovery: images.contains_key("recovery"),
};
Ok((images, layout))
}
/// Apply applicable patches to the list of specified boot images. For each
@@ -1317,7 +1391,7 @@ pub fn patch_boot_images<'a>(
}
// Preparse all images. Some patchers need to inspect every candidate.
let mut images = load_boot_images(names, opener)?;
let (mut images, layout) = load_boot_images(names, opener)?;
// Find the targets that each patcher wants to patch.
let all_targets = patchers
@@ -1325,14 +1399,15 @@ pub fn patch_boot_images<'a>(
.map(|p| {
let _span =
debug_span!(parent: &parent_span, "patcher", name = p.patcher_name()).entered();
p.find_targets(&images, cancel_signal).and_then(|targets| {
if targets.is_empty() {
Err(TargetsError::NoTargets(p.patcher_name()))
} else {
debug!("Found patcher targets: {targets:?}");
Ok(targets)
}
})
p.find_targets(layout, &images, cancel_signal)
.and_then(|targets| {
if targets.is_empty() {
Err(TargetsError::NoTargets(p.patcher_name()))
} else {
debug!("Found patcher targets: {targets:?}");
Ok(targets)
}
})
})
.collect::<TargetsResult<Vec<_>>>()?;
@@ -1359,8 +1434,8 @@ pub fn patch_boot_images<'a>(
.try_for_each(|(&name, (info, patchers))| -> TargetsResult<()> {
patchers.iter().try_for_each(|p| {
let _span =
debug_span!(parent: &parent_span, "patcher", name = p.patcher_name()).entered();
p.patch(&mut info.boot_image, cancel_signal)
debug_span!(parent: &parent_span, "patcher", name = p.patcher_name(), image = name).entered();
p.patch(layout, &mut info.boot_image, cancel_signal)
.map_err(|e| TargetsError::Patch(name.to_owned(), e))
})
})?;
+6 -10
View File
@@ -34,20 +34,13 @@ allow = [
"Apache-2.0 WITH LLVM-exception",
"BSD-3-Clause",
"bzip2-1.0.6",
"GPL-3.0",
"GPL-3.0-only",
"ISC",
"MIT",
"Unicode-3.0",
"Zlib",
]
[[licenses.clarify]]
name = "ring"
expression = "MIT AND ISC AND OpenSSL"
license-files = [
{ path = "LICENSE", hash = 0xbd0eed23 },
]
[bans]
multiple-versions = "warn"
multiple-versions-include-dev = true
@@ -61,8 +54,11 @@ executables = "deny"
include-dependencies = true
include-workspace = true
bypass = [
# Copies of unmodified crashwrangler objects for old macOS versions.
{ name = "honggfuzz", allow-globs = ["honggfuzz/third_party/mac/CrashReport_*.o"] },
# honggfuzz/third_party/mac/CrashReport_*.o are copies of unmodified
# crashwrangler objects for old macOS versions. Unfortunately, when running
# cargo hfuzz, the compiled hongfuzz binary and corresponding object files
# are written to the source directory too.
{ name = "honggfuzz", allow-globs = ["honggfuzz/*.o", "honggfuzz/honggfuzz"] },
# Only used in tests.
{ name = "libloading", allow-globs = ["tests/nagisa*.dll"] },
]
+3 -2
View File
@@ -4,7 +4,8 @@ version.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
publish = false
publish.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -19,7 +20,7 @@ ring = "0.17.14"
rsa = { version = "0.9.6", features = ["hazmat"] }
serde = { version = "1.0.188", features = ["derive"] }
tempfile = "3.8.0"
toml_edit = { version = "0.23.3", features = ["serde"] }
toml = { version = "0.9.11", features = ["serde"] }
topological-sort = "0.2.2"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
+8 -8
View File
@@ -53,11 +53,11 @@ data.ramdisks = [["otacerts", "first_stage", "dsu_key_dir"]]
[profile.pixel_v4_gki.hashes_streaming]
original = "ea96196191e3a4133db4aff45d47aa3468514e29e0a724faac8081cbf4adf808"
patched = "357a448d1a7505b2308ce1c2d19b063e606c60e7349784913a48cdc3f6d50aa4"
patched = "179923431ff94148186d8b0a457636c8a60057d047d55a4fc4da3a162e73eeed"
[profile.pixel_v4_gki.hashes_seekable]
original = "f6615ae355eba38689d24aa535981d09175d4832e7c65c04cdd89aa95d21f09d"
patched = "9195ba963d9897af2f0821ff6051c1efe3fe130055b7936bedf2cd189998fd89"
patched = "b006858b78cddef0e3db1d77454cd945111ce15708121e3a483ff711abedec8b"
# Google Pixel 6a
# What's unique: boot (boot v4, no ramdisk) + vendor_boot (vendor v4, 2 ramdisks)
@@ -97,11 +97,11 @@ data.ramdisks = [["init", "otacerts", "first_stage", "dsu_key_dir"], ["dlkm"]]
[profile.pixel_v4_non_gki.hashes_streaming]
original = "cb2a2e406d2b4c68c8a38f819256a10ada0ed5a4732822bec35bdf7bcdc458eb"
patched = "12f15d29fceeb18af14c9a805de3aedb7f270fe8ec316d9d0fe37fb0c667eacd"
patched = "45cbe96e01b8b2e3ba5e4a2c990e7ff08bee285316a4a7a314aab3ffddf27d0d"
[profile.pixel_v4_non_gki.hashes_seekable]
original = "9450c212c34fe55453b52345c7cc22f72397dc80d9ddc792eafc20b461c2afc9"
patched = "5018c579df9608f9dfe3add2afd8b176de61ba267376cf3a3e422ecc9d3dd112"
patched = "111fdfae91977d80cd141f6c3dc69f3af45bb7fcdf3e2e442bc3f0ad5fa77faa"
# Google Pixel 4a 5G
# What's unique: boot (boot v3) + vendor_boot (vendor v3)
@@ -141,11 +141,11 @@ data.ramdisks = [["otacerts", "first_stage", "dsu_key_dir"]]
[profile.pixel_v3.hashes_streaming]
original = "4b864b906a13ec98b1d6c3440a5eca7404ec63d073080e80a3b84afabcbd2fa2"
patched = "a9077fe32dee8eb7a0369c1334d8f3378ae8044814ae04da700f33294b12a4d8"
patched = "da3b9a4d6a58bb5aaadfc63006cb36b7af9c1c5945e81b38587c245bd5ad1f5a"
[profile.pixel_v3.hashes_seekable]
original = "e0e93ee11de56992f3a5f543858c1d11858b4deb76a91a4caf4fb0f3f34be855"
patched = "8730b398367179a0be092a67e4714f09c2267c656fe3e42ec1f8b43bb3a28634"
patched = "71682a4f31a5920784a0e2e38a6ee5fe3c65213436c7bf1ce347b121cd01a367"
# Google Pixel 4a
# What's unique: boot (boot v2)
@@ -174,8 +174,8 @@ data.deps = ["system"]
[profile.pixel_v2.hashes_streaming]
original = "abc0ad7f80020018101437c2494d6564a877df663d208a123267fc100734c175"
patched = "b1876455f5be9d5b6eafc598a017ad10e5e76339137f8b29777097ab19cdc3b0"
patched = "132fb4d90e3c19a7a5ee0da2082767228255228ea5fb66811df1ccd5ff600bb5"
[profile.pixel_v2.hashes_seekable]
original = "57d4ac5ab7d362a593f3c02f3d2044b5400c10db0f732741a2d18e025d4231ec"
patched = "40d7674be14e19747e7ead118e0f4faf50880c638dfb4bfc0d0154b0e9202d3f"
patched = "b365eb32f463ac4ba13f7bed4e6535a68483379640dc6e842c591f194db042c2"
+2 -7
View File
@@ -6,7 +6,6 @@ use std::{collections::BTreeMap, fs, path::Path};
use anyhow::{Context, Result};
use avbroot::format::payload::{CowVersion, VabcAlgo};
use serde::{Deserialize, Serialize};
use toml_edit::DocumentMut;
#[derive(Clone, Copy, Serialize, Deserialize)]
pub struct Sha256Hash(
@@ -130,12 +129,8 @@ pub struct Config {
pub profile: BTreeMap<String, Profile>,
}
pub fn load_config(path: &Path) -> Result<(Config, DocumentMut)> {
pub fn load_config(path: &Path) -> Result<Config> {
let contents =
fs::read_to_string(path).with_context(|| format!("Failed to read config: {path:?}"))?;
let config: Config = toml_edit::de::from_str(&contents)
.with_context(|| format!("Failed to parse config: {path:?}"))?;
let document: DocumentMut = contents.parse().unwrap();
Ok((config, document))
toml::de::from_str(&contents).with_context(|| format!("Failed to parse config: {path:?}"))
}
+2 -2
View File
@@ -1203,7 +1203,7 @@ fn filter_profiles<'a>(config: &'a Config, cli: &'a ProfileGroup) -> Result<BTre
}
fn test_subcommand(cli: &TestCli, cancel_signal: &AtomicBool) -> Result<()> {
let (config, _) = config::load_config(&cli.config.config)?;
let config = config::load_config(&cli.config.config)?;
let profiles = filter_profiles(&config, &cli.profile)?;
if profiles.is_empty() {
@@ -1336,7 +1336,7 @@ fn test_subcommand(cli: &TestCli, cancel_signal: &AtomicBool) -> Result<()> {
}
fn list_subcommand(cli: &ListCli) -> Result<()> {
let (config, _) = config::load_config(&cli.config.config)?;
let config = config::load_config(&cli.config.config)?;
for profile in config.profile.keys() {
println!("{profile}");
+1
View File
@@ -1,4 +1,5 @@
/hfuzz_target/
/hfuzz_workspace/
HONGGFUZZ.REPORT.TXT
*.honggfuzz.cov
*.fuzz
+2 -1
View File
@@ -4,7 +4,8 @@ version.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
publish = false
publish.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+9 -3
View File
@@ -10,7 +10,13 @@ While avbroot's parsers are all memory-safe, it is still possible for panics or
cargo install honggfuzz
```
2. Pick a fuzz target to run. A fuzz target is the name of the source file in [`src/bin/`](./src/bin) without the `.rs` extension.
2. [Optional] Generate sample files to use as the initial fuzzing corpus.
```bash
cargo xtask fuzz-corpus
```
3. Pick a fuzz target to run. A fuzz target is the name of the source file in [`src/bin/`](./src/bin) without the `.rs` extension.
The list of targets can be queried programmatically with:
@@ -18,7 +24,7 @@ While avbroot's parsers are all memory-safe, it is still possible for panics or
cargo read-manifest | jq -r '.targets[].name'
```
3. Run the fuzzer.
4. Run the fuzzer.
```bash
cargo hfuzz run <fuzz target>
@@ -41,7 +47,7 @@ While avbroot's parsers are all memory-safe, it is still possible for panics or
When a crash occurs, the `Crashes` counter will increment and the input data that triggered the crash will be written to `hfuzz_workspace/<fuzz target>/*.fuzz`. New files are only written for unique crashes.
4. If a crash occurs, run the following command to trigger the crash in a debugger.
5. If a crash occurs, run the following command to trigger the crash in a debugger.
```bash
cargo hfuzz run-debug <fuzz target> \
@@ -0,0 +1,38 @@
image_size = 12288
[header]
required_libavb_version_major = 1
required_libavb_version_minor = 0
algorithm_type = "Sha256Rsa4096"
hash = "3035539ec16eb6e6645a9022dd62379bf448cc53178b91fb68507eb6565b5478"
signature = "25f59424238d43e8e247583f276d45caeed1396e5d6298c4f4f5db4bdb74453ece1783143900157b35bdd99fe29123fe98f0876663b1c985a1426bdfbdf0b31b710ebe54cbb759d4eb1aa6ecc6964c5bccd364f1a9359e53d79797ec0bdc8e453a9a6c559e95ab4d8309422ad182bdc210b3d815b277b2fc8c827ff5849997ca9cf4fcb9fae69902ba865478401c2a4976f07499f27e8f8e3e609679dd32b495c27dfe9dae4de6eb7e9a86abe30da6f0e5454f85cf170eb3ea75250d697770d0028c78c0be12280b7599019ac03a05612384f81263821b8d3cbd902e4c2b6442afed2fb7800dfc4be999f77274afa4d97512147b8ccf791e59a91e75deebd4469538d71bc9272e4c7fbbc657f3d269ec269a617314a8ceb4a4920f9654fd549c8def8a3d5a54c38871cb822af8733a575f69a187717debca30884872206f04cb98aade78c765007e2d9b024185f153ec769de1684e98b0ce41fd0dbefd9aca814887ee0917f067708c66f1e5586c578f3a4f4148f71e5ce7dd84f150b99b1547e3ca6c041fafd085bb987f16a6056a4c28875d151872bda5e316b08bb43cfb2db78759b50e4cf016f0b0b0118e03ee25508da5ce9eee77f97fdeab0831a55c43760d1ba0b4cd0c8570840549f356f32c0abf8666daf478a4cad9b84cda52430137ad12ee15425a0bf948e362c6f2da0f4ff3c57683e0b8760a014e1dbd936c11"
public_key = "0000100080af29ebacee1fc0a795d91674aaeb4f55f4d36ba6f899ddb543be5d1cc878d45d776fe6211a330c0843322334b690dbbb9dc13fa47642abc75889dbba79c82a9dba19c64d4c099f36240775834e9d86013f433a1aaab0bed1f2212dc53cf2d967ded53209c1e5eb5b563d00d307c021b9d2d084e80cdd20a695225ce31e7fb407ccebdec5cda2eb44ed079df3edf31751e77ce43ae9681bc7f6cc4e58945366bb655550e07dd215eb516815e9457feef9301b772f92291fd5758782f20734b9ac75e7469f42ffd4055ae43a8301a37e56dfda4ede5e639fec57ab7268d8787190268952a27e6b8e3ffc503759af317da4a076fd36fe6499f15de27d81dca566f500838d13a442b01ecd1ffdb655ea2ef779bab13cd8eab649402cc1a3f81444ed24717a7c3fa65ac2b8d3625450aae15b75d3dc37e962f516799cb555063eeb262bb51f9af465fc992e07f3aa66917ce086abd9a60716f04fe155efe7901e4132a4dcdcdcf7db23e4eade6b3664bee87a7fd4c6b3247beeb0553263845d6547efda705f58cab911d9a98fb7cdd807bfdbf3dbf1f81ac3e837ba75ea5512be7246bfe768aa1edf23c469db87df980bbb939fd1f28948340882350e4c58f0450329f8088da6b908b4c4c78689eb18b3c06b683b12e518bde5cd57e7fb43792df94c38f643675e5c92b1c0a95f45256969a4bc6ea1db6682745d423cc676f97f57cf2d493d850bfba9362a858faa355e2bd0c9b1a46f6581c9c0751399788bd37fc5e597a402a3bc05bb5959677a48ce4aa9fa6ed5add36a7e11117152610b0e8f86692669825206eb5d297d7f77d114bc867736b6d6eb4309329569d78dfb910cb66132c5a3f415bd1ededfb61fd58c958db4c7a2c17578f537d24b5405e545d1618ae58be3525c9659d6baf2634255e7ca26fcfde1cbc4401e8ca062babede5f5b3f2ad5cbecd3d9332098f402666a9ef85643e3f4ab214a67a5ca91f31f810eab89df57d2f9ef35e9a5f46a99228af059cdd1f0685f1b9405beb0e44fe7f590b50feea1554e8bdaf7be7fd22e6f050a7751731cd7f8737b5acb92378da9d59068106da25b30882abad4629dff6ca9c4c0cf5337bf2d2a9e8c6182dcd6d7c681da01df6c11d0b335cf1f982156393c4e572df540cee2c53a2c146dec9644be4e81cce20df4cb136b3a08fad9a186be892d6653330d11cac1e96d308fd0d2896c8a141edfbdcac827cdf97ac581f493721c9aa1305667df312277c8ab6700c3a978e6f9d00b389faaeaa99b5e023b72c5f5ce885fa2ba816ffc735599fad1e3876d91a501efbbf1315f42a503ddd7a26a784a3f290a86f43dd580c03fc4125716d6b534e35daf1156fcaec37ac8bc9e881d5ec1715632ff82b4dc4e3aabf48c5db6f3608ce2b8bb48bceae621b07f231254dd6f1f7b4584e7102969f523252a6839dca065"
public_key_metadata = "000102030405060708090a0b0c0d0e0f"
rollback_index = 1677974400
flags = 0
rollback_index_location = 0
release_string = "MaxLengthMaxLengthMaxLengthMaxLengthMaxLengthMa"
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
[[header.descriptors]]
type = "Property"
key = "foobar"
value = 'Invalid\x20UTF-8:\x20\xFF'
[[header.descriptors]]
type = "Hash"
image_size = 6
hash_algorithm = "sha256"
partition_name = "vbmeta_appended_hash"
salt = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
root_digest = "2454ef9d58f39d544eb2d92294131c0b3b1473a276418d0b1362693fdafa685b"
flags = 0
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567"
[footer]
version_major = 1
version_minor = 0
original_image_size = 6
vbmeta_offset = 4096
vbmeta_size = 2176
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef01234567"
@@ -0,0 +1 @@
foobar
@@ -0,0 +1,46 @@
image_size = 28672
[header]
required_libavb_version_major = 1
required_libavb_version_minor = 0
algorithm_type = "Sha256Rsa4096"
hash = "2bf01b15b31a729ca8053bc1303b0a4a638ee4819cc3106fd36ff996b703e249"
signature = "8c4f1daf4174f4347e623b57e314d4ac7717014c7476aa2f54ab3a71f3143fb366398dd2a165e092085ce34ed1412a7bf9ce8008f2061164edc3e42ef8b7f2a7e38ebc1f05059b0b829fa82cceef91aad67ffb843c79a9c6944f0f08d7523111a8c25dbfeab9aedb0cbd682f906d33a044be072fa22657024d4d056823310f38b65cad5e293b26142798a3a49c880eb4646bfbf612294f90792b652532d5e9bb5ca79699f968ec811a3aeb038d6033ac82a571f098659294db36666da4380c8a74eb7af8dfe32e5136301dad0e49d71e726d15c0cf659850eaa878133302835fcbe624122aee63b72a960d1c1432561afa55f07a9e57c6791c813131a7c0f6a0e1036036bc613e38cff14a1353b496416f06b1a3c224d8cb51218d251c8720624c936541519167e150dc2ac92091110fae8a08bac660b6ea4ef12f0c710bc7deada678a4e8d00b4803980e40c1899e9a5208b55d06bc519004e2bbfb15c9bec614c496de1f7fe103d9173067084f0170b9f6837f179689c3a4aa11b94e54aa3a49c76838ed5d31fece91a95fc089af72833e453c64c58a8270ec868ae7a4154717f3c98a940e51a197c9ebed4188ff1969faf4d9e59618713af785b538c4f41568dd4ba9b6dff68ab18222b4195938c1e500640218d1d4f6ef014c76deab8e18782e5fff6988ef6e630ff38dcc6709de7548cc1f56d817a0dbfe5df95e6a0f53"
public_key = "0000100080af29ebacee1fc0a795d91674aaeb4f55f4d36ba6f899ddb543be5d1cc878d45d776fe6211a330c0843322334b690dbbb9dc13fa47642abc75889dbba79c82a9dba19c64d4c099f36240775834e9d86013f433a1aaab0bed1f2212dc53cf2d967ded53209c1e5eb5b563d00d307c021b9d2d084e80cdd20a695225ce31e7fb407ccebdec5cda2eb44ed079df3edf31751e77ce43ae9681bc7f6cc4e58945366bb655550e07dd215eb516815e9457feef9301b772f92291fd5758782f20734b9ac75e7469f42ffd4055ae43a8301a37e56dfda4ede5e639fec57ab7268d8787190268952a27e6b8e3ffc503759af317da4a076fd36fe6499f15de27d81dca566f500838d13a442b01ecd1ffdb655ea2ef779bab13cd8eab649402cc1a3f81444ed24717a7c3fa65ac2b8d3625450aae15b75d3dc37e962f516799cb555063eeb262bb51f9af465fc992e07f3aa66917ce086abd9a60716f04fe155efe7901e4132a4dcdcdcf7db23e4eade6b3664bee87a7fd4c6b3247beeb0553263845d6547efda705f58cab911d9a98fb7cdd807bfdbf3dbf1f81ac3e837ba75ea5512be7246bfe768aa1edf23c469db87df980bbb939fd1f28948340882350e4c58f0450329f8088da6b908b4c4c78689eb18b3c06b683b12e518bde5cd57e7fb43792df94c38f643675e5c92b1c0a95f45256969a4bc6ea1db6682745d423cc676f97f57cf2d493d850bfba9362a858faa355e2bd0c9b1a46f6581c9c0751399788bd37fc5e597a402a3bc05bb5959677a48ce4aa9fa6ed5add36a7e11117152610b0e8f86692669825206eb5d297d7f77d114bc867736b6d6eb4309329569d78dfb910cb66132c5a3f415bd1ededfb61fd58c958db4c7a2c17578f537d24b5405e545d1618ae58be3525c9659d6baf2634255e7ca26fcfde1cbc4401e8ca062babede5f5b3f2ad5cbecd3d9332098f402666a9ef85643e3f4ab214a67a5ca91f31f810eab89df57d2f9ef35e9a5f46a99228af059cdd1f0685f1b9405beb0e44fe7f590b50feea1554e8bdaf7be7fd22e6f050a7751731cd7f8737b5acb92378da9d59068106da25b30882abad4629dff6ca9c4c0cf5337bf2d2a9e8c6182dcd6d7c681da01df6c11d0b335cf1f982156393c4e572df540cee2c53a2c146dec9644be4e81cce20df4cb136b3a08fad9a186be892d6653330d11cac1e96d308fd0d2896c8a141edfbdcac827cdf97ac581f493721c9aa1305667df312277c8ab6700c3a978e6f9d00b389faaeaa99b5e023b72c5f5ce885fa2ba816ffc735599fad1e3876d91a501efbbf1315f42a503ddd7a26a784a3f290a86f43dd580c03fc4125716d6b534e35daf1156fcaec37ac8bc9e881d5ec1715632ff82b4dc4e3aabf48c5db6f3608ce2b8bb48bceae621b07f231254dd6f1f7b4584e7102969f523252a6839dca065"
public_key_metadata = "000102030405060708090a0b0c0d0e0f"
rollback_index = 1677974400
flags = 0
rollback_index_location = 0
release_string = "MaxLengthMaxLengthMaxLengthMaxLengthMaxLengthMa"
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
[[header.descriptors]]
type = "Property"
key = "foobar"
value = 'Invalid\x20UTF-8:\x20\xFF'
[[header.descriptors]]
type = "HashTree"
dm_verity_version = 1
image_size = 8192
tree_offset = 8192
tree_size = 4096
data_block_size = 4096
hash_block_size = 4096
fec_num_roots = 2
fec_offset = 12288
fec_size = 8192
hash_algorithm = "sha256"
partition_name = "vbmeta_appended_hash_tree"
salt = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
root_digest = "bfb9f01152b3315096319d03697b4013d1674063418deec55920686ad13537a8"
flags = 0
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567"
[footer]
version_major = 1
version_minor = 0
original_image_size = 8192
vbmeta_offset = 20480
vbmeta_size = 2240
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef01234567"
File diff suppressed because one or more lines are too long
+61
View File
@@ -0,0 +1,61 @@
image_size = 4096
[header]
required_libavb_version_major = 1
required_libavb_version_minor = 0
algorithm_type = "Sha256Rsa4096"
hash = "892d9bd80a0b8b5e5daed1cdedfc252e3fe5573ffa812fa485c2eaec17632f3b"
signature = "752e7688a4de06eab55d37b56c4d7158e6e0477916f5217904edb85c946e4bfa4c0fb5d8aed0d1a0cc084c528cc303209075caa1067bdba7c0cc970d024c022ffe61feabc0eaf45755938d2b9b248ae07d369388b92c23c0f0f31a4a5ac1a4e92ebd2b24fff7953448a8f6827363fd3d32055977d708f72c9224b1a6616b59e79cdb20a4c17959081904d394fdfa27573f0b428fd7179ae3607c93e99a07badd6908e3f76893a346267126798503807d4a58904262afca7544349a796b04f658511724207c5a645c2976faec055f44c44ea21d63c7b2af21a8ffb7f4007249e8f81f8e2746e20965ced023b952bc48cb9c5ae11587b771f47383cfc1f5d021b1024128fc02a5a2f458d131a08975470d9373a9b70336d647943ed9e04bdaa0bbf19bfb087e0e6454cd178152eb826244bbfad20315dc20ae9a889ea99ac0045f438726bb882bf54c87fecfb3056aac7f2d649523b8cbcc8dd5a54917740e440ad7ffdaefde7e98b557798054d94653005213f377ce560fdec934435b2049b09e613906c12da713b97d31966238e7708a47501c0c91c6a9cfb4911fef54acacfa3e83f29a542d8a7d2c0f7b3b92815502ca9307e40c009415e575aab7f3b998a48d4a0a6d59adf3c8bd253620a9cbf53ea5fdb84bce5e21aca3d8d749406770725fc22f925e9a53f1c58eddc5e4dbd68d8537e7dda5035c20c54a5045434c6505"
public_key = "0000100080af29ebacee1fc0a795d91674aaeb4f55f4d36ba6f899ddb543be5d1cc878d45d776fe6211a330c0843322334b690dbbb9dc13fa47642abc75889dbba79c82a9dba19c64d4c099f36240775834e9d86013f433a1aaab0bed1f2212dc53cf2d967ded53209c1e5eb5b563d00d307c021b9d2d084e80cdd20a695225ce31e7fb407ccebdec5cda2eb44ed079df3edf31751e77ce43ae9681bc7f6cc4e58945366bb655550e07dd215eb516815e9457feef9301b772f92291fd5758782f20734b9ac75e7469f42ffd4055ae43a8301a37e56dfda4ede5e639fec57ab7268d8787190268952a27e6b8e3ffc503759af317da4a076fd36fe6499f15de27d81dca566f500838d13a442b01ecd1ffdb655ea2ef779bab13cd8eab649402cc1a3f81444ed24717a7c3fa65ac2b8d3625450aae15b75d3dc37e962f516799cb555063eeb262bb51f9af465fc992e07f3aa66917ce086abd9a60716f04fe155efe7901e4132a4dcdcdcf7db23e4eade6b3664bee87a7fd4c6b3247beeb0553263845d6547efda705f58cab911d9a98fb7cdd807bfdbf3dbf1f81ac3e837ba75ea5512be7246bfe768aa1edf23c469db87df980bbb939fd1f28948340882350e4c58f0450329f8088da6b908b4c4c78689eb18b3c06b683b12e518bde5cd57e7fb43792df94c38f643675e5c92b1c0a95f45256969a4bc6ea1db6682745d423cc676f97f57cf2d493d850bfba9362a858faa355e2bd0c9b1a46f6581c9c0751399788bd37fc5e597a402a3bc05bb5959677a48ce4aa9fa6ed5add36a7e11117152610b0e8f86692669825206eb5d297d7f77d114bc867736b6d6eb4309329569d78dfb910cb66132c5a3f415bd1ededfb61fd58c958db4c7a2c17578f537d24b5405e545d1618ae58be3525c9659d6baf2634255e7ca26fcfde1cbc4401e8ca062babede5f5b3f2ad5cbecd3d9332098f402666a9ef85643e3f4ab214a67a5ca91f31f810eab89df57d2f9ef35e9a5f46a99228af059cdd1f0685f1b9405beb0e44fe7f590b50feea1554e8bdaf7be7fd22e6f050a7751731cd7f8737b5acb92378da9d59068106da25b30882abad4629dff6ca9c4c0cf5337bf2d2a9e8c6182dcd6d7c681da01df6c11d0b335cf1f982156393c4e572df540cee2c53a2c146dec9644be4e81cce20df4cb136b3a08fad9a186be892d6653330d11cac1e96d308fd0d2896c8a141edfbdcac827cdf97ac581f493721c9aa1305667df312277c8ab6700c3a978e6f9d00b389faaeaa99b5e023b72c5f5ce885fa2ba816ffc735599fad1e3876d91a501efbbf1315f42a503ddd7a26a784a3f290a86f43dd580c03fc4125716d6b534e35daf1156fcaec37ac8bc9e881d5ec1715632ff82b4dc4e3aabf48c5db6f3608ce2b8bb48bceae621b07f231254dd6f1f7b4584e7102969f523252a6839dca065"
public_key_metadata = "000102030405060708090a0b0c0d0e0f"
rollback_index = 1677974400
flags = 0
rollback_index_location = 0
release_string = "MaxLengthMaxLengthMaxLengthMaxLengthMaxLengthMa"
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
[[header.descriptors]]
type = "Property"
key = "foobar"
value = 'Invalid\x20UTF-8:\x20\xFF'
[[header.descriptors]]
type = "HashTree"
dm_verity_version = 1
image_size = 4096
tree_offset = 0
tree_size = 2048
data_block_size = 4096
hash_block_size = 4096
fec_num_roots = 1
fec_offset = 2048
fec_size = 2048
hash_algorithm = "sha512"
partition_name = "hashtreed_partition"
salt = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
root_digest = "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"
flags = 0
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567"
[[header.descriptors]]
type = "Hash"
image_size = 6
hash_algorithm = "sha256"
partition_name = "hashed_partition"
salt = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
root_digest = "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"
flags = 0
reserved = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567"
[[header.descriptors]]
type = "KernelCmdline"
flags = 1
cmdline = "foobar"
[[header.descriptors]]
type = "ChainPartition"
rollback_index_location = 1
partition_name = "chained_partition"
public_key = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
flags = 4275878552
reserved = "76543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"
+20
View File
@@ -0,0 +1,20 @@
type = "V0Through2"
kernel_addr = 19088743
ramdisk_addr = 2309737967
second_addr = 38177486
tags_addr = 324508639
page_size = 4096
os_version = 1985229328
name = "NameNameNameName"
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineC"
id = [
1122867,
1146447479,
2291772091,
3437096703,
4293844428,
3148519816,
2003195204,
857870592,
]
extra_cmdline = "ExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtr"
+1
View File
@@ -0,0 +1 @@
kernel data
@@ -0,0 +1 @@
ramdisk data
+1
View File
@@ -0,0 +1 @@
second data
+23
View File
@@ -0,0 +1,23 @@
type = "V0Through2"
kernel_addr = 19088743
ramdisk_addr = 2309737967
second_addr = 38177486
tags_addr = 324508639
page_size = 4096
os_version = 1985229328
name = "NameNameNameName"
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineC"
id = [
1122867,
1146447479,
2291772091,
3437096703,
4293844428,
3148519816,
2003195204,
857870592,
]
extra_cmdline = "ExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtr"
[v1_extra]
recovery_dtbo_offset = 81985529216486895
+1
View File
@@ -0,0 +1 @@
kernel data
@@ -0,0 +1 @@
ramdisk data
@@ -0,0 +1 @@
recovery_dtbo data
+1
View File
@@ -0,0 +1 @@
second data
+26
View File
@@ -0,0 +1,26 @@
type = "V0Through2"
kernel_addr = 19088743
ramdisk_addr = 2309737967
second_addr = 38177486
tags_addr = 324508639
page_size = 4096
os_version = 1985229328
name = "NameNameNameName"
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineC"
id = [
1122867,
1146447479,
2291772091,
3437096703,
4293844428,
3148519816,
2003195204,
857870592,
]
extra_cmdline = "ExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtraCmdlineExtr"
[v1_extra]
recovery_dtbo_offset = 81985529216486895
[v2_extra]
dtb_addr = 18364758544493064720
+1
View File
@@ -0,0 +1 @@
dtb data
+1
View File
@@ -0,0 +1 @@
kernel data
@@ -0,0 +1 @@
ramdisk data
@@ -0,0 +1 @@
recovery_dtbo data
+1
View File
@@ -0,0 +1 @@
second data
+9
View File
@@ -0,0 +1,9 @@
type = "V3Through4"
os_version = 19088743
reserved = [
1122867,
1146447479,
2291772091,
3437096703,
]
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmd"
+1
View File
@@ -0,0 +1 @@
kernel data
@@ -0,0 +1 @@
ramdisk data
+11
View File
@@ -0,0 +1,11 @@
type = "V3Through4"
os_version = 19088743
reserved = [
1122867,
1146447479,
2291772091,
3437096703,
]
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmd"
[v4_extra]
+1
View File
@@ -0,0 +1 @@
kernel data
@@ -0,0 +1 @@
ramdisk data
@@ -0,0 +1,11 @@
type = "V3Through4"
os_version = 19088743
reserved = [
1122867,
1146447479,
2291772091,
3437096703,
]
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmd"
[v4_extra]
@@ -0,0 +1 @@
kernel data
@@ -0,0 +1 @@
ramdisk data
@@ -0,0 +1,25 @@
image_size = 2048
[header]
required_libavb_version_major = 1
required_libavb_version_minor = 0
algorithm_type = "Sha256Rsa4096"
hash = "73b770b8199f1e709ce1cc37ee7f699faa99bf7e88c6eff429a6eda1feb6a1f9"
signature = "58c16f72718891a11f8d1ad92b8053c20d701ac3cc997ee7889d45c999ee91b05795d59d6feac44c316fe15f92dd06e9ae3bc570d8f414191bdaab7aae4c37822cb2f6d34fdcccc65a853d2dc72ecec311db000e27fbdc7bc767b80c1a0b4e88e193ce4f878ce15cac2a4b361294eddc193d36e148768b4c6b0de4001cf2e12fe2b8be84d5217a4c3ea12c0e040900a112f6e519363635a3b3108191b5858c90b62a4d459a6d66218978e002ed07478472ff34269ca575a53eb396e3e13972f115827c741b82e5988eb6f59f953e2ee5ad9fc6ab5d86754f282011e4a511c8ce4ed9d8b077a2b5f1a3e8943c222debaab02e02b6e461f98820a8f90a470ea222b625831e280a8d9bdf96bde33bf830bc2e39a62d52103f3b8988025da86f55a5f075ea362e45c0f92279216dfdf47ead516dfd5d9da546fd5a93e325a1706c0241f71a4d4cd5abec836fd2be0812b9716ce126498a67b0d6610adc94bb9cf9b137af57b1f413155428a4bc0318aff369cdcae69008f883b48d3ba6210c8f90cb473c8101c2381ad1ab2d2b17cdf3a8e65d118beb2283b140630e3f4800159d208c34abac3d9493e321948205e1a6df529a36ec47dac50b06a71aa2350f87738022ad8175c514dfb6acca04b9bac4a002ff587639cab9f1d94e68f13739d7d72b30010db4cf0e62ea796d6207e3b9264b9ec980076c6be7dbd9973e6278225be0"
public_key = "0000100080af29ebacee1fc0a795d91674aaeb4f55f4d36ba6f899ddb543be5d1cc878d45d776fe6211a330c0843322334b690dbbb9dc13fa47642abc75889dbba79c82a9dba19c64d4c099f36240775834e9d86013f433a1aaab0bed1f2212dc53cf2d967ded53209c1e5eb5b563d00d307c021b9d2d084e80cdd20a695225ce31e7fb407ccebdec5cda2eb44ed079df3edf31751e77ce43ae9681bc7f6cc4e58945366bb655550e07dd215eb516815e9457feef9301b772f92291fd5758782f20734b9ac75e7469f42ffd4055ae43a8301a37e56dfda4ede5e639fec57ab7268d8787190268952a27e6b8e3ffc503759af317da4a076fd36fe6499f15de27d81dca566f500838d13a442b01ecd1ffdb655ea2ef779bab13cd8eab649402cc1a3f81444ed24717a7c3fa65ac2b8d3625450aae15b75d3dc37e962f516799cb555063eeb262bb51f9af465fc992e07f3aa66917ce086abd9a60716f04fe155efe7901e4132a4dcdcdcf7db23e4eade6b3664bee87a7fd4c6b3247beeb0553263845d6547efda705f58cab911d9a98fb7cdd807bfdbf3dbf1f81ac3e837ba75ea5512be7246bfe768aa1edf23c469db87df980bbb939fd1f28948340882350e4c58f0450329f8088da6b908b4c4c78689eb18b3c06b683b12e518bde5cd57e7fb43792df94c38f643675e5c92b1c0a95f45256969a4bc6ea1db6682745d423cc676f97f57cf2d493d850bfba9362a858faa355e2bd0c9b1a46f6581c9c0751399788bd37fc5e597a402a3bc05bb5959677a48ce4aa9fa6ed5add36a7e11117152610b0e8f86692669825206eb5d297d7f77d114bc867736b6d6eb4309329569d78dfb910cb66132c5a3f415bd1ededfb61fd58c958db4c7a2c17578f537d24b5405e545d1618ae58be3525c9659d6baf2634255e7ca26fcfde1cbc4401e8ca062babede5f5b3f2ad5cbecd3d9332098f402666a9ef85643e3f4ab214a67a5ca91f31f810eab89df57d2f9ef35e9a5f46a99228af059cdd1f0685f1b9405beb0e44fe7f590b50feea1554e8bdaf7be7fd22e6f050a7751731cd7f8737b5acb92378da9d59068106da25b30882abad4629dff6ca9c4c0cf5337bf2d2a9e8c6182dcd6d7c681da01df6c11d0b335cf1f982156393c4e572df540cee2c53a2c146dec9644be4e81cce20df4cb136b3a08fad9a186be892d6653330d11cac1e96d308fd0d2896c8a141edfbdcac827cdf97ac581f493721c9aa1305667df312277c8ab6700c3a978e6f9d00b389faaeaa99b5e023b72c5f5ce885fa2ba816ffc735599fad1e3876d91a501efbbf1315f42a503ddd7a26a784a3f290a86f43dd580c03fc4125716d6b534e35daf1156fcaec37ac8bc9e881d5ec1715632ff82b4dc4e3aabf48c5db6f3608ce2b8bb48bceae621b07f231254dd6f1f7b4584e7102969f523252a6839dca065"
public_key_metadata = ""
rollback_index = 0
flags = 0
rollback_index_location = 0
release_string = "avbtool 1.2.0"
reserved = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
[[header.descriptors]]
type = "Hash"
image_size = 12288
hash_algorithm = "sha256"
partition_name = "boot"
salt = "6430306466303064"
root_digest = "abd5483e11e7940cb9bf387587a4a1659981a1b83962b7c1faf1b0cd6307d449"
flags = 0
reserved = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
@@ -0,0 +1,8 @@
type = "VendorV3Through4"
page_size = 4096
kernel_addr = 19088743
ramdisk_addr = 2309737967
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdl"
tags_addr = 4275878552
name = "NameNameNameName"
dtb_addr = 1985229328
+1
View File
@@ -0,0 +1 @@
dtb data
@@ -0,0 +1 @@
ramdisk data
+96
View File
@@ -0,0 +1,96 @@
type = "VendorV3Through4"
page_size = 2048
kernel_addr = 19088743
ramdisk_addr = 2309737967
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdl"
tags_addr = 4275878552
name = "NameNameNameName"
dtb_addr = 1985229328
[[v4_extra.ramdisk_metas]]
ramdisk_type = 0
ramdisk_name = "NoneNoneNoneNoneNoneNoneNoneNone"
board_id = [
1122867,
1146447479,
2291772091,
3437096703,
4293844428,
3148519816,
2003195204,
857870592,
4491468,
290822621,
577153774,
863484927,
4290475827,
4004144674,
3717813521,
3431482368,
]
[[v4_extra.ramdisk_metas]]
ramdisk_type = 1
ramdisk_name = "PlatformPlatformPlatformPlatform"
board_id = [
1122867,
1146447479,
2291772091,
3437096703,
4293844428,
3148519816,
2003195204,
857870592,
4491468,
290822621,
577153774,
863484927,
4290475827,
4004144674,
3717813521,
3431482368,
]
[[v4_extra.ramdisk_metas]]
ramdisk_type = 2
ramdisk_name = "RecoveryRecoveryRecoveryRecovery"
board_id = [
1122867,
1146447479,
2291772091,
3437096703,
4293844428,
3148519816,
2003195204,
857870592,
4491468,
290822621,
577153774,
863484927,
4290475827,
4004144674,
3717813521,
3431482368,
]
[[v4_extra.ramdisk_metas]]
ramdisk_type = 3
ramdisk_name = "DlkmDlkmDlkmDlkmDlkmDlkmDlkmDlkm"
board_id = [
1122867,
1146447479,
2291772091,
3437096703,
4293844428,
3148519816,
2003195204,
857870592,
4491468,
290822621,
577153774,
863484927,
4290475827,
4004144674,
3717813521,
3431482368,
]
@@ -0,0 +1 @@
bootconfig data
+1
View File
@@ -0,0 +1 @@
dtb data
@@ -0,0 +1 @@
ramdisk 0 data
@@ -0,0 +1 @@
ramdisk 1 data
@@ -0,0 +1 @@
ramdisk 2 data
@@ -0,0 +1 @@
ramdisk 3 data
+35
View File
@@ -0,0 +1,35 @@
format = "None"
[[entries]]
path = "symlink"
data = "target"
file_type = "Symlink"
file_mode = "777"
nlink = 1
[[entries]]
path = "directory"
file_type = "Directory"
file_mode = "755"
nlink = 1
[[entries]]
path = "file"
file_type = "Regular"
file_mode = "644"
nlink = 1
[[entries]]
path = "reserved"
inode = 12345
file_type = "Reserved"
file_mode = "4777"
uid = 12345678
gid = 87654321
nlink = 2
mtime = 1700000000
dev_maj = 2222
dev_min = 3333
rdev_maj = 4444
rdev_min = 5555
crc32 = 4275878409
+1
View File
@@ -0,0 +1 @@
foobar
+1
View File
@@ -0,0 +1 @@
datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
+80
View File
@@ -0,0 +1,80 @@
image_type = "Empty"
metadata_max_size = 65536
metadata_slot_count = 3
logical_block_size = 4096
[[slots]]
major_version = 10
minor_version = 2
flags = "VIRTUAL_AB_DEVICE"
[[slots.groups]]
name = "default"
flags = ""
partitions = []
[[slots.groups]]
name = "google_dynamic_partitions_a"
flags = ""
maximum_size = 8527020032
[[slots.groups.partitions]]
name = "system_a"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "system_dlkm_a"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "system_ext_a"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "product_a"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "vendor_a"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "vendor_dlkm_a"
attributes = "READONLY"
[[slots.groups]]
name = "google_dynamic_partitions_b"
flags = ""
maximum_size = 8527020032
[[slots.groups.partitions]]
name = "system_b"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "system_dlkm_b"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "system_ext_b"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "product_b"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "vendor_b"
attributes = "READONLY"
[[slots.groups.partitions]]
name = "vendor_dlkm_b"
attributes = "READONLY"
[[slots.block_devices]]
first_logical_sector = 2048
alignment = 1048576
alignment_offset = 0
size = 8531214336
partition_name = "super"
flags = ""
+1
View File
@@ -0,0 +1 @@
datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
@@ -1 +0,0 @@
../../../../avbroot/tests/data/vbmeta_appended_hash.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/vbmeta_appended_hash_tree.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/vbmeta_root.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/boot_v0.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/boot_v1.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/boot_v2.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/boot_v3.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/boot_v4.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/boot_v4_vts.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/vendor_v3.img
@@ -1 +0,0 @@
../../../../avbroot/tests/data/vendor_v4.img
Binary file not shown.
File diff suppressed because one or more lines are too long
+3 -2
View File
@@ -4,7 +4,8 @@ version.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
publish = false
publish.workspace = true
rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -12,7 +13,7 @@ publish = false
anyhow = "1.0.75"
clap = { version = "4.4.1", features = ["derive"] }
regex = { version = "1.9.4", default-features = false, features = ["perf", "std"] }
toml_edit = "0.23.3"
toml_edit = "0.24.0"
[lints]
workspace = true
+192
View File
@@ -0,0 +1,192 @@
// SPDX-FileCopyrightText: 2026 Andrew Gunnerson
// SPDX-License-Identifier: GPL-3.0-only
use std::{
env,
fs::{self},
path::{Path, PathBuf},
process::Command,
};
use anyhow::{Context, Result, bail};
use crate::WORKSPACE_DIR;
#[cfg(not(target_os = "windows"))]
const EXE_SUFFIX: &str = "";
#[cfg(target_os = "windows")]
const EXE_SUFFIX: &str = ".exe";
fn run(mut command: Command) -> Result<()> {
let status = command
.status()
.with_context(|| format!("Failed to spawn: {command:?}"))?;
if !status.success() {
bail!("Command failed with status: {status}: {command:?}");
}
Ok(())
}
fn build_avbroot() -> Result<PathBuf> {
let mut command = Command::new(env!("CARGO"));
command.arg("build");
command.current_dir(WORKSPACE_DIR);
run(command)?;
let mut executable = Path::new(WORKSPACE_DIR).to_owned();
if let Some(target_dir) = env::var_os("CARGO_TARGET_DIR") {
executable.push(target_dir);
} else {
executable.push("target");
}
executable.push("debug");
executable.push(format!("avbroot{EXE_SUFFIX}"));
Ok(executable)
}
fn generate_avb_image(avbroot: &Path, input_dir: &Path, output_file: &Path) -> Result<()> {
let mut command = Command::new(avbroot);
command.arg("avb");
command.arg("pack");
command.arg("-q");
command.arg("-o");
command.arg(output_file);
command.current_dir(input_dir);
run(command)
}
fn generate_boot_image(avbroot: &Path, input_dir: &Path, output_file: &Path) -> Result<()> {
let vts_signature_dir = input_dir.join("vts_signature");
if vts_signature_dir.exists() {
let mut command = Command::new(avbroot);
command.arg("avb");
command.arg("pack");
command.arg("-q");
command.arg("-o");
command.arg("../vts_signature.img");
command.current_dir(vts_signature_dir);
run(command)?;
}
let mut command = Command::new(avbroot);
command.arg("boot");
command.arg("pack");
command.arg("-q");
command.arg("-o");
command.arg(output_file);
command.current_dir(input_dir);
run(command)
}
fn generate_cpio_image(avbroot: &Path, input_dir: &Path, output_file: &Path) -> Result<()> {
let mut command = Command::new(avbroot);
command.arg("cpio");
command.arg("pack");
command.arg("-q");
command.arg("-o");
command.arg(output_file);
command.current_dir(input_dir);
run(command)
}
fn generate_fec_image(avbroot: &Path, input_dir: &Path, output_file: &Path) -> Result<()> {
let mut command = Command::new(avbroot);
command.arg("fec");
command.arg("generate");
command.arg("-i");
command.arg("input.img");
command.arg("-f");
command.arg(output_file);
command.current_dir(input_dir);
run(command)
}
fn generate_lp_image(avbroot: &Path, input_dir: &Path, output_file: &Path) -> Result<()> {
let mut command = Command::new(avbroot);
command.arg("lp");
command.arg("pack");
command.arg("-q");
command.arg("-o");
command.arg(output_file);
command.current_dir(input_dir);
run(command)
}
fn generate_sparse_image(avbroot: &Path, input_dir: &Path, output_file: &Path) -> Result<()> {
let mut command = Command::new(avbroot);
command.arg("sparse");
command.arg("pack");
command.arg("-q");
command.arg("-i");
command.arg("input.img");
command.arg("-o");
command.arg(output_file);
command.current_dir(input_dir);
run(command)
}
type Generator = fn(&Path, &Path, &Path) -> Result<()>;
fn generate_corpus(
avbroot: &Path,
input_dir: &Path,
output_dir: &Path,
generator: Generator,
suffix: &str,
) -> Result<()> {
fs::create_dir_all(output_dir)
.with_context(|| format!("Failed to create directory: {output_dir:?}"))?;
let parent = fs::read_dir(input_dir)
.with_context(|| format!("Failed to open directory: {input_dir:?}"))?;
for entry in parent {
let entry = entry.with_context(|| format!("Failed to list directory: {input_dir:?}"))?;
let entry_input_dir = entry.path();
let mut entry_output_file = output_dir.join(entry.file_name());
entry_output_file.as_mut_os_string().push(suffix);
println!("{entry_input_dir:?} -> {entry_output_file:?}");
generator(avbroot, &entry_input_dir, &entry_output_file)?;
}
Ok(())
}
pub fn fuzz_corpus_subcommand() -> Result<()> {
let fuzz_dir = Path::new(WORKSPACE_DIR).join("fuzz");
let corpus = fuzz_dir.join("corpus");
let hfuzz_workspace = fuzz_dir.join("hfuzz_workspace");
let avbroot = build_avbroot()?;
let items: [(Generator, _, _); _] = [
(generate_avb_image, "avb", ".img"),
(generate_boot_image, "bootimage", ".img"),
(generate_cpio_image, "cpio", ".cpio"),
(generate_fec_image, "fec", ".fec"),
(generate_lp_image, "lp", ".img"),
(generate_sparse_image, "sparse", ".img"),
];
for (generator, name, suffix) in items {
let input_dir = corpus.join(name);
let mut output_dir = hfuzz_workspace.join(name);
output_dir.push("input");
generate_corpus(&avbroot, &input_dir, &output_dir, generator, suffix)?;
}
Ok(())
}
+5 -1
View File
@@ -1,7 +1,8 @@
// SPDX-FileCopyrightText: 2023 Andrew Gunnerson
// SPDX-FileCopyrightText: 2023-2026 Andrew Gunnerson
// SPDX-License-Identifier: GPL-3.0-only
mod changelog;
mod fuzz_corpus;
mod version;
use anyhow::Result;
@@ -16,6 +17,7 @@ fn main() -> Result<()> {
match cli.command {
Command::SetVersion(c) => version::set_version_subcommand(&c),
Command::FuzzCorpus => fuzz_corpus::fuzz_corpus_subcommand(),
Command::UpdateChangelog => changelog::update_changelog_subcommand(),
}
}
@@ -23,6 +25,8 @@ fn main() -> Result<()> {
#[derive(Debug, Subcommand)]
pub enum Command {
SetVersion(SetVersionCli),
/// Generate initial fuzzing corpus.
FuzzCorpus,
/// Update links in CHANGELOG.md.
UpdateChangelog,
}