Skip to content

Commit

Permalink
rafs: add special handling of invalid zero blob index
Browse files Browse the repository at this point in the history
The rafs v6 format reserves blob index 0 for meta blobs, so ensure
invalid zero blob index doesn't cause abnormal behavior.

Signed-off-by: Jiang Liu <gerry@linux.alibaba.com>
  • Loading branch information
jiangliu committed Jun 18, 2023
1 parent 66761f2 commit bc72cbe
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
17 changes: 13 additions & 4 deletions rafs/src/metadata/direct_v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,17 @@ impl OndiskInodeWrapper {
is_tarfs_mode: bool,
is_tail: bool,
) -> Option<BlobIoDesc> {
let blob_index = chunk_addr.blob_index();
let chunk_index = chunk_addr.blob_ci_index();
let blob_index = match chunk_addr.blob_index() {
Err(e) => {
warn!(
"failed to get blob index for chunk address {:?}, {}",
chunk_addr, e
);
return None;
}
Ok(v) => v,
};

match state.blob_table.get(blob_index) {
Err(e) => {
Expand Down Expand Up @@ -1310,7 +1319,7 @@ impl RafsInodeExt for OndiskInodeWrapper {
let has_device = self.mapping.device.lock().unwrap().has_device();

if state.meta.has_inlined_chunk_digest() && has_device {
let blob_index = chunk_addr.blob_index();
let blob_index = chunk_addr.blob_index()?;
let chunk_index = chunk_addr.blob_ci_index();
let device = self.mapping.device.lock().unwrap();
device
Expand All @@ -1322,7 +1331,7 @@ impl RafsInodeExt for OndiskInodeWrapper {
))
})
} else if state.is_tarfs() {
let blob_index = chunk_addr.blob_index();
let blob_index = chunk_addr.blob_index()?;
let chunk_index = chunk_addr.blob_ci_index();
let offset = (chunk_addr.block_addr() as u64) << EROFS_BLOCK_BITS_9;
let size = if idx == self.get_chunk_count() - 1 {
Expand All @@ -1340,7 +1349,7 @@ impl RafsInodeExt for OndiskInodeWrapper {
match chunk_map.as_ref().unwrap().get(chunk_addr) {
None => Err(enoent!(format!(
"failed to get chunk info for chunk {}/{}/{}",
chunk_addr.blob_index(),
chunk_addr.blob_index().unwrap_or_default(),
chunk_addr.blob_ci_index(),
chunk_addr.block_addr()
))),
Expand Down
25 changes: 23 additions & 2 deletions rafs/src/metadata/layout/v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1196,8 +1196,13 @@ impl RafsV6InodeChunkAddr {
/// The index in BlobInfo grows from 0, so when using this method to index the corresponding blob,
/// the index always needs to be minus 1
/// Get the blob index of the chunk.
pub fn blob_index(&self) -> u32 {
(u16::from_le(self.c_blob_addr_hi) & 0x00ff) as u32 - 1
pub fn blob_index(&self) -> Result<u32> {
let idx = (u16::from_le(self.c_blob_addr_hi) & 0x00ff) as u32;
if idx == 0 {
Err(einval!("invalid zero blob index from RafsV6InodeChunkAddr"))
} else {
Ok(idx - 1)
}
}

/// Set the blob index of the chunk.
Expand Down Expand Up @@ -2356,4 +2361,20 @@ mod tests {
assert!(entry2 == target1);
}
}

#[test]
fn test_invalid_blob_idx_from_chunk_addr() {
let mut addr = RafsV6InodeChunkAddr::new();
assert!(addr.blob_index().is_err());
addr.set_blob_index(8);
assert_eq!(addr.blob_index(), 8);

assert_eq!(addr.blob_ci_index(), 0);
addr.set_blob_ci_index(131);
assert_eq!(addr.blob_ci_index(), 131);

assert_eq!(addr.block_addr(), 0);
addr.set_block_addr(179);
assert_eq!(addr.block_addr(), 179);
}
}

0 comments on commit bc72cbe

Please sign in to comment.