Skip to content

fix(packer): validate blob offsets and bounds in BlobCopier - #591

Open
Huge wants to merge 1 commit into
rustic-rs:mainfrom
Huge:fix/blob-copier-bounds-check
Open

Huge wants to merge 1 commit into
rustic-rs:mainfrom
Huge:fix/blob-copier-bounds-check

Conversation

@Huge

@Huge Huge commented Oct 6, 2026

Copy link
Copy Markdown

Problem

In BlobCopier::copy_fast and BlobCopier::copy (crates/core/src/blob/packer.rs), blob slice offsets are computed directly from index locations:

let start = usize::try_from(blob.offset - offset)
    .expect("convert from u32 to usize should not fail!");
let end = usize::try_from(blob.offset + blob.length - offset)
    .expect("convert from u32 to usize should not fail!");
// ...
&data[start..end]

If an index file contains malformed or corrupted metadata where:

  1. blob.offset < offset (causing unsigned subtraction underflow / panic),
  2. blob.offset + blob.length overflows u32, or
  3. start or end exceeds data.len() / read_data.len(),

the process panics with .expect(...) or out-of-bounds slice indexing &data[start..end], crashing any host application performing repo prune, repack, or copy operations.

Fix

  • Factored out helper get_blob_slice that uses checked_sub, checked_add, and safe slice lookup data.get(start..end).
  • Replaced unchecked conversions and slice indices in copy_fast and copy with calls to get_blob_slice.
  • Returns a structured RusticError (ErrorKind::Repository) with diagnostic context (blob_id, pack_id, blob_offset, blob_length, read_offset, read_length) instead of crashing.

Tests

  • Added unit test test_get_blob_slice verifying normal slices, base offsets, underflow (blob.offset < offset), overflow (blob.offset + length > u32::MAX), and out-of-bounds access.
  • Existing unit tests pass (cargo test -p rustic_core --lib -- blob::packer::tests).
  • Integration tests pass (cargo test -p rustic_core --test integration -- prune, cargo test -p rustic_core --test integration -- copy).

Disclaimer: Found the issue by test-driving an LM-powered vulnerability scanner I work on heavily.

In BlobCopier::copy_fast and BlobCopier::copy, blob offsets and lengths
from index locations were subtracted and sliced directly from
data/read_data without checking that blob.offset >= offset or that
blob.offset + blob.length <= offset + data.len(). A corrupted or malformed
index entry could trigger an underflow/overflow panic or an out-of-bounds
slice panic, terminating the process during repack/copy.

Add get_blob_slice with checked arithmetic and bounds verification that
returns a descriptive RusticError (ErrorKind::Repository) instead of
panicking.

Reported-by: BS.ehlas.cz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant