Read Merkle tree once per file
EagerChunkReader is added to read the wrapper Merkle tree reader. Also
add a function to calculate the tree size, in order to know how much
bytes to read.
Separately, add a check in fd_server to prevent crash when the read size
is 0.
Bug: 182827266
Test: atest AuthFsHostTest authfs_device_test_src_lib
Change-Id: Ibff8c9ac091f1449aec8f4a52cd148e6f41d7b33
diff --git a/authfs/src/fsverity/verifier.rs b/authfs/src/fsverity/verifier.rs
index 1add37a..17a0a2a 100644
--- a/authfs/src/fsverity/verifier.rs
+++ b/authfs/src/fsverity/verifier.rs
@@ -49,6 +49,12 @@
let chunk_hash = hash_with_padding(chunk, CHUNK_SIZE as usize)?;
+ // When the file is smaller or equal to CHUNK_SIZE, the root of Merkle tree is defined as the
+ // hash of the file content, plus padding.
+ if file_size <= CHUNK_SIZE {
+ return Ok(chunk_hash);
+ }
+
fsverity_walk(chunk_index, file_size, merkle_tree)?.try_fold(
chunk_hash,
|actual_hash, result| {
@@ -141,9 +147,14 @@
merkle_tree: M,
) -> Result<VerifiedFileReader<F, M>, FsverityError> {
let mut buf = [0u8; CHUNK_SIZE as usize];
- let size = merkle_tree.read_chunk(0, &mut buf)?;
- if buf.len() != size {
- return Err(FsverityError::InsufficientData(size));
+ if file_size <= CHUNK_SIZE {
+ let _size = chunked_file.read_chunk(0, &mut buf)?;
+ // The rest of buffer is 0-padded.
+ } else {
+ let size = merkle_tree.read_chunk(0, &mut buf)?;
+ if buf.len() != size {
+ return Err(FsverityError::InsufficientData(size));
+ }
}
let root_hash = Sha256Hasher::new()?.update(&buf[..])?.finalize()?;
let formatted_digest = build_fsverity_formatted_digest(&root_hash, file_size)?;