Skip to content

bug: slice index panic in create_overlay when backing_file path exceeds fixed buffer #175

Description

@JingMox

Describe the bug
In crates/bux-qcow2/src/overlay.rs, create_overlay allocates a fixed 256 KiB buffer (4 clusters of 64 KiB each) to construct the minimal QCOW2 v3 overlay header and tables. However, when writing the backing file path into the header via write_backing_file_name, it copies the bytes directly using slice indexing (buf[off..off + backing_bytes.len()]) without validating the length of backing_file.

If backing_file exceeds the available buffer capacity (e.g. an expanded deep path or malicious input > 260 KiB), the slice indexing triggers an out-of-bounds Panic (range end index out of range for slice of length 262144). This unhandled panic crashes the host daemon/worker process and leaves orphaned temporary files (*.qcow2.tmp) on the disk.

Furthermore, if backing_file is between ~65 KiB and 256 KiB, the slice index does not panic, but silently overflows Cluster 0 and clobbers Cluster 1 (the L1 routing table), causing catastrophic silent disk corruption when the VM boots.

To Reproduce
Steps to reproduce the behavior:

  1. Call bux_qcow2::create_overlay (or invoke via DiskManager::create_overlay) passing a backing_file path longer than 260 KiB (e.g. run test repro_bug_2a_create_overlay_long_path_panics).
  2. Observe thread panic at crates/bux-qcow2/src/overlay.rs:164:
    thread 'repro_bug_2a_create_overlay_long_path_panics' panicked at crates/bux-qcow2/src/overlay.rs:164:8:
    range end index 300128 out of range for slice of length 262144
    
  3. Inspect vms_dir: notice that a half-created *.qcow2.tmp file is leaked on the host filesystem without being renamed or cleaned up.

Expected behavior
create_overlay should defensively validate backing_file.len() up-front:

  1. Ensure the backing path does not exceed the remaining capacity of Cluster 0 (CLUSTER_SIZE - header_ext_len), preventing both slice index panics and silent corruption of the L1 table in Cluster 1.
  2. Return a typed error (e.g. Error::BackingPathTooLong) rather than panicking.
  3. Callers should ensure temporary files are properly cleaned up on failure.

Screenshots
N/A (CLI / headless library)

Desktop (please complete the following information):

  • OS: macOS 26.6.2 (Darwin arm64)
  • Rust Version: rustc 1.97.1
  • Shell: zsh

Smartphone (please complete the following information):

  • Device: N/A
  • OS: N/A
  • Browser: N/A
  • Version: N/A

Additional context

  • Offending code location: crates/bux-qcow2/src/overlay.rs:164 in write_backing_file_name.
  • The warning was previously suppressed via #[allow(clippy::indexing_slicing, reason = "buffer sizing invariant maintained by create_overlay (4 clusters)")], which bypassed Clippy's bounds checking lint under an unvalidated assumption.
  • Upstream caller in crates/bux/src/disk/mod.rs:207-214 creates a temporary file before calling create_overlay, which is orphaned on panic.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions