mirror of
https://github.com/chenxiaolong/avbroot.git
synced 2026-07-03 14:05:11 +02:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd4da8d147 | |||
| 9c48d0ddc5 | |||
| ee70fdbcae | |||
| f8f1afd6b3 | |||
| f2b98623cb | |||
| 63e21c5aa9 | |||
| a78a122763 | |||
| cd7316b429 | |||
| 68d5bd6990 | |||
| 2a4c422943 | |||
| 94b12bf727 | |||
| f966714310 | |||
| 3eb08f48d1 | |||
| dbb5bc4767 | |||
| 903d6dcd13 | |||
| ddcef31b96 | |||
| cbd419f8e9 | |||
| 9214a832cd | |||
| dc9244f014 | |||
| 7017bc66dd | |||
| bff45fc53c | |||
| 0e5ba0f0e2 | |||
| 2033e48163 | |||
| 237f59fd9b | |||
| b0b00a4c54 | |||
| b9a70efb15 | |||
| aeef2936d8 | |||
| 3adab80893 | |||
| 4069429361 | |||
| 74193c1c9f | |||
| 0f8cef2daa | |||
| 8731df4504 | |||
| fda11b4262 | |||
| f0970aa80c | |||
| 4f0db5a7c4 | |||
| 57374e2e41 | |||
| f4e5c55fe9 | |||
| 850ce86388 | |||
| c16636a68c | |||
| 26812cd43a | |||
| 135cd320ce | |||
| 919f621833 | |||
| 2c1d86cd96 | |||
| 91074ae4c8 | |||
| a5c628b66f | |||
| 156c96d3d4 | |||
| 2460d1807d | |||
| 728d333951 | |||
| 39661a994d | |||
| d6b19b69f7 | |||
| 96806cba36 | |||
| 5c474a1e98 | |||
| 4cf546e5ca |
@@ -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: |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -7,6 +7,42 @@
|
||||
to update the actual links at the bottom of the file.
|
||||
-->
|
||||
|
||||
### 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 +445,9 @@ 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
|
||||
[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 +641,25 @@ 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
|
||||
|
||||
Generated
+296
-335
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -4,10 +4,12 @@ members = ["avbroot", "e2e", "fuzz", "xtask"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "3.21.0"
|
||||
version = "3.24.0"
|
||||
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"
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
+7
-5
@@ -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"
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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,
|
||||
|
||||
+55
-13
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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),
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,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
@@ -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))
|
||||
})
|
||||
})?;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,4 +1,5 @@
|
||||
/hfuzz_target/
|
||||
/hfuzz_workspace/
|
||||
HONGGFUZZ.REPORT.TXT
|
||||
*.honggfuzz.cov
|
||||
*.fuzz
|
||||
|
||||
+2
-1
@@ -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
@@ -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
@@ -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"
|
||||
@@ -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"
|
||||
@@ -0,0 +1 @@
|
||||
kernel data
|
||||
@@ -0,0 +1 @@
|
||||
ramdisk data
|
||||
@@ -0,0 +1 @@
|
||||
second data
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
kernel data
|
||||
@@ -0,0 +1 @@
|
||||
ramdisk data
|
||||
@@ -0,0 +1 @@
|
||||
recovery_dtbo data
|
||||
@@ -0,0 +1 @@
|
||||
second data
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
dtb data
|
||||
@@ -0,0 +1 @@
|
||||
kernel data
|
||||
@@ -0,0 +1 @@
|
||||
ramdisk data
|
||||
@@ -0,0 +1 @@
|
||||
recovery_dtbo data
|
||||
@@ -0,0 +1 @@
|
||||
second data
|
||||
@@ -0,0 +1,9 @@
|
||||
type = "V3Through4"
|
||||
os_version = 19088743
|
||||
reserved = [
|
||||
1122867,
|
||||
1146447479,
|
||||
2291772091,
|
||||
3437096703,
|
||||
]
|
||||
cmdline = "CmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmdlineCmd"
|
||||
@@ -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,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
|
||||
@@ -0,0 +1 @@
|
||||
dtb data
|
||||
@@ -0,0 +1 @@
|
||||
ramdisk data
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
foobar
|
||||
@@ -0,0 +1 @@
|
||||
datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
|
||||
@@ -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 = ""
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user