Compare commits

..

5 Commits

Author SHA1 Message Date
Andrew Gunnerson f84df86ef5 Version 3.2.1
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-05-24 18:27:38 -04:00
Andrew Gunnerson 0c064981dd CHANGELOG.md: Add entry for PR #293
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-05-24 18:26:43 -04:00
Andrew Gunnerson 5645183ecc Merge pull request #293 from chenxiaolong/bump-fec-limits
avb: Bump hashtree and FEC size limits to accommodate 8 GiB images
2024-05-24 18:25:36 -04:00
Andrew Gunnerson bc7358a8d9 avb: Bump hashtree and FEC size limits to accommodate 8 GiB images
Fixes: #291

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-05-24 18:20:28 -04:00
Andrew Gunnerson d47c14ab12 Switch to Rust 1.73.0's builtin div_ceil function
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-05-24 17:57:45 -04:00
9 changed files with 44 additions and 31 deletions
+6
View File
@@ -7,6 +7,10 @@
to update the actual links at the bottom of the file.
-->
### Version 3.2.1
* Increase hash tree and FEC size limits to accommodate partition images up to 8 GiB ([Issue #291], [PR #293])
### Version 3.2.0
* Fix potential infinite loop when interrupting avbroot at the right moment to a bug in the bzip2-rs library ([Issue #285], [PR #287])
@@ -194,6 +198,7 @@ Behind-the-scenes changes:
[Issue #265]: https://github.com/chenxiaolong/avbroot/issues/265
[Issue #278]: https://github.com/chenxiaolong/avbroot/issues/278
[Issue #285]: https://github.com/chenxiaolong/avbroot/issues/285
[Issue #291]: https://github.com/chenxiaolong/avbroot/issues/291
[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
@@ -278,3 +283,4 @@ Behind-the-scenes changes:
[PR #287]: https://github.com/chenxiaolong/avbroot/pull/287
[PR #288]: https://github.com/chenxiaolong/avbroot/pull/288
[PR #289]: https://github.com/chenxiaolong/avbroot/pull/289
[PR #293]: https://github.com/chenxiaolong/avbroot/pull/293
Generated
+4 -4
View File
@@ -109,7 +109,7 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "avbroot"
version = "3.2.0"
version = "3.2.1"
dependencies = [
"anyhow",
"assert_matches",
@@ -534,7 +534,7 @@ dependencies = [
[[package]]
name = "e2e"
version = "3.2.0"
version = "3.2.1"
dependencies = [
"anyhow",
"avbroot",
@@ -628,7 +628,7 @@ dependencies = [
[[package]]
name = "fuzz"
version = "3.2.0"
version = "3.2.1"
dependencies = [
"avbroot",
"honggfuzz",
@@ -2068,7 +2068,7 @@ dependencies = [
[[package]]
name = "xtask"
version = "3.2.0"
version = "3.2.1"
dependencies = [
"anyhow",
"clap",
+1 -1
View File
@@ -4,7 +4,7 @@ members = ["avbroot", "e2e", "fuzz", "xtask"]
resolver = "2"
[workspace.package]
version = "3.2.0"
version = "3.2.1"
license = "GPL-3.0-only"
edition = "2021"
repository = "https://github.com/chenxiaolong/avbroot"
+23 -6
View File
@@ -50,13 +50,30 @@ pub const FOOTER_MAGIC: [u8; 4] = *b"AVBf";
/// for early fail. No individual field can actually be this size.
pub const HEADER_MAX_SIZE: u64 = 64 * 1024;
/// Maximum hash tree size. The current limit equals the hash tree size for a
/// 4GiB image using SHA512 digests and a block size of 4096.
pub const HASH_TREE_MAX_SIZE: u64 = 68_177_920;
/// Maximum hash tree size. The current limit equals the hash tree size for an
/// 8GiB image using SHA256 digests and a block size of 4096. This is equal to:
///
/// ```rust
/// use avbroot::format::hashtree::HashTree;
/// let size = HashTree::new(4096, &ring::digest::SHA256, b"")
/// .compute_level_offsets(8 * 1024 * 1024 * 1024)
/// .unwrap()
/// .first()
/// .map(|r| r.end)
/// .unwrap_or(0);
/// ```
pub const HASH_TREE_MAX_SIZE: u64 = 67_637_248;
/// Maximum FEC data size. The current limit equals the FEC data size for a 4GiB
/// image using 2 parity bytes per codeword.
pub const FEC_DATA_MAX_SIZE: u64 = 33_959_936;
/// Maximum FEC data size. The current limit equals the FEC data size for an
/// 8GiB image using 2 parity bytes per codeword. This is equal to:
///
/// ```rust
/// use avbroot::format::fec::Fec;
/// let size = Fec::new(8 * 1024 * 1024 * 1024, 4096, 2)
/// .unwrap()
/// .fec_size();
/// ```
pub const FEC_DATA_MAX_SIZE: u64 = 67_911_680;
#[derive(Debug, Error)]
pub enum Error {
+4 -4
View File
@@ -166,8 +166,8 @@ impl Fec {
return Err(Error::UnsupportedParity(parity));
}
let blocks = util::div_ceil(file_size, u64::from(block_size));
let rounds = util::div_ceil(blocks, u64::from(rs_k));
let blocks = file_size.div_ceil(u64::from(block_size));
let rounds = blocks.div_ceil(u64::from(rs_k));
// Check upfront so we don't need to do checked multiplication later.
rounds
@@ -196,7 +196,7 @@ impl Fec {
/// Get the size of the FEC data needed to cover the entire file.
#[inline]
fn fec_size(&self) -> usize {
pub fn fec_size(&self) -> usize {
usize::from(self.parity()) * self.rounds as usize * self.block_size as usize
}
@@ -225,7 +225,7 @@ impl Fec {
let end_block = if range.end % block_size == 0 {
range.end / block_size
} else {
util::div_ceil(range.end, block_size)
range.end.div_ceil(block_size)
};
for block in start_block..end_block {
+3 -3
View File
@@ -72,14 +72,14 @@ impl HashTree {
/// tree data. The items are returned with the bottom level's offsets first
/// in the list. Note that the bottom level is stored at the end of the hash
/// tree data.
fn compute_level_offsets(&self, image_size: u64) -> Result<Vec<Range<usize>>> {
pub fn compute_level_offsets(&self, image_size: u64) -> Result<Vec<Range<usize>>> {
let algorithm = self.salted_context.algorithm();
let digest_size = algorithm.output_len().next_power_of_two();
let mut ranges = vec![];
let mut level_size = image_size;
while level_size > u64::from(self.block_size) {
let blocks = util::div_ceil(level_size, u64::from(self.block_size));
let blocks = level_size.div_ceil(u64::from(self.block_size));
level_size = blocks
.checked_mul(digest_size as u64)
.and_then(|s| padding::round(s, u64::from(self.block_size)))
@@ -124,7 +124,7 @@ impl HashTree {
let end_block = if range.end % block_size == 0 {
range.end / block_size
} else {
util::div_ceil(range.end, block_size)
range.end.div_ceil(block_size)
};
result.push(start_block..end_block);
+2 -2
View File
@@ -918,7 +918,7 @@ pub fn compress_image(
});
}
let chunks_total = util::div_ceil(file_size, CHUNK_SIZE);
let chunks_total = file_size.div_ceil(CHUNK_SIZE);
let mut bytes_compressed = 0;
let mut context_uncompressed = Context::new(&ring::digest::SHA256);
let mut operations = vec![];
@@ -1059,7 +1059,7 @@ pub fn compress_modified_image(
return Err(Error::ExtentsNotInOrder);
}
let groups_total = util::div_ceil(operations.len(), OPERATION_GROUP);
let groups_total = operations.len().div_ceil(OPERATION_GROUP);
let mut bytes_compressed = 0;
let mut context_uncompressed = Context::new(&ring::digest::SHA256);
let mut modified_operations = vec![];
+1 -1
View File
@@ -129,7 +129,7 @@ pub fn patch_system_image(
return Err(Error::NoHashTreeDescriptor);
};
let num_chunks = util::div_ceil(footer.original_image_size, CHUNK_SIZE);
let num_chunks = footer.original_image_size.div_ceil(CHUNK_SIZE);
trace!("Parallel heuristics search for otacerts.zip with {num_chunks} chunks");
let modified_ranges = (0..num_chunks)
-10
View File
@@ -49,16 +49,6 @@ pub fn parent_path(path: &Path) -> &Path {
Path::new(".")
}
/// Since Rust's built-in .div_ceil() is still nightly-only.
pub fn div_ceil<T: PrimInt>(dividend: T, divisor: T) -> T {
dividend / divisor
+ if dividend % divisor != T::zero() {
T::one()
} else {
T::zero()
}
}
/// Sort and merge overlapping intervals.
pub fn merge_overlapping<T>(sections: &[Range<T>]) -> Vec<Range<T>>
where