Skip to content

fix(vmm): cap volume_device_name at MAX_VOLUMES (closes #175)#176

Merged
WaylandYang merged 2 commits into
mainfrom
fix/175-volume-device-name-cap
May 27, 2026
Merged

fix(vmm): cap volume_device_name at MAX_VOLUMES (closes #175)#176
WaylandYang merged 2 commits into
mainfrom
fix/175-volume-device-name-cap

Conversation

@WaylandYang
Copy link
Copy Markdown
Contributor

Closes #175. Thanks to @andraiming for the precise repro and source-cite.

Root cause

volume_device_name's doc said "up to 23 → vdy" but the function itself had no actual cap. Indices 25..153 produced garbage device names like vd{, vd|, vd}, vd~ because (b'b' + index as u8) as char walks past z into ASCII punctuation. The host happily inserted those names into the forkd.mounts= kernel cmdline, and the guest's /forkd-init.sh then silently failed to mount the volume (no /dev/vd{ device exists).

The fix

  • New constant: pub const MAX_VOLUMES: usize = 25; — matches the real virtio-blk /dev/vdb..vdz range (/dev/vda is the rootfs).
  • volume_device_name now returns Result<String> and bails for index >= MAX_VOLUMES with a message naming the cap.
  • BootConfig::with_volume propagates the error and now returns Result<Self>.
  • The sole non-test caller in crates/forkd-cli/src/main.rs is updated with .with_context(...) so users see a contextual CLI error instead of a panic.

Tests

Existing volume_device_name_progression extended to also assert the last valid index (MAX_VOLUMES - 1 → "vdz"). Two new regression tests added:

  • volume_device_name_rejects_past_cap — exercises MAX_VOLUMES, MAX_VOLUMES + 1, 100, 153 (the historical worst case where addition wraps into the next byte per @andraiming's analysis).
  • boot_config_with_volume_errors_past_cap — fills with_volume to capacity, asserts the 26th attachment fails rather than silently producing vd{.

Local results on the dev box (cargo test -p forkd-vmm --lib volume):

running 5 tests
test tests::boot_config_with_multiple_volumes_extends_hint ... ok
test tests::volume_device_name_rejects_past_cap ... ok
test tests::boot_config_with_volume_appends_cmdline_hint ... ok
test tests::volume_device_name_progression ... ok
test tests::boot_config_with_volume_errors_past_cap ... ok

test result: ok. 5 passed; 0 failed

cargo check -p forkd-cli also passes cleanly with the new ? propagation in with_volume.

API compatibility

This is a small API break: BootConfig::with_volume was previously infallible and is now Result<Self>. Only one in-tree caller exists (crates/forkd-cli/src/main.rs) and it's updated in this PR. Out-of-tree callers building against the forkd-vmm crate will need a single ? (or .expect(...)) added.

The doc on volume_device_name said "up to 23 → vdy", but the function
itself had no actual cap. Indices 25..153 produced garbage device names
("vd{", "vd|", "vd}", "vd~", …) because (b'b' + index as u8) silently
walks past 'z' into the ASCII punctuation range. The host-side cmdline
append happily included these names in `forkd.mounts=`; the guest then
silently failed to mount the volume since /dev/vd{ doesn't exist.

This change:

- Adds `pub const MAX_VOLUMES: usize = 25;` matching the real virtio-blk
  /dev/vdb..vdz range (/dev/vda is the rootfs).
- Returns `Result<String>` from `volume_device_name` and bails for
  `index >= MAX_VOLUMES` with a message naming the cap.
- Propagates the error through `BootConfig::with_volume`, which now
  returns `Result<Self>`. The sole non-test caller in forkd-cli wraps
  it with `with_context` so the CLI surface gets a contextual error
  rather than a panic.
- Adds two regression tests:
  - `volume_device_name_rejects_past_cap` — indices MAX_VOLUMES,
    MAX_VOLUMES+1, 100, 153.
  - `boot_config_with_volume_errors_past_cap` — fills to MAX_VOLUMES,
    asserts the 26th attachment fails instead of producing "vd{".
- Updates the existing `volume_device_name_progression` test to also
  assert the last valid index (MAX_VOLUMES - 1) → "vdz".

Note: this is a small API break — `with_volume` was previously
infallible and is now `Result`. Only one in-tree caller exists
(crates/forkd-cli/src/main.rs); it's updated in this PR.

Reported by @andraiming in #175. Closes #175.
@WaylandYang WaylandYang merged commit f7f20f1 into main May 27, 2026
2 checks passed
@WaylandYang WaylandYang deleted the fix/175-volume-device-name-cap branch May 27, 2026 19:17
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.

[Bug] volume_device_name produces garbage device names past index 23

1 participant