usbip-rs/CLAUDE.md

2.6 KiB

CLAUDE.md

Project overview

Rust USB/IP server library and CLI tool. Two workspace crates: lib/ (library) and cli/ (binary). Linux only.

Security model

Host is trusted, client (in VM) is untrusted. All USB handling in userspace to minimize kernel attack surface. The host kernel's vhci_hcd driver is downstream of responses — don't assume it handles malformed data gracefully.

Building

nix build              # Nix
nix develop -c cargo build  # Cargo via nix devShell

Testing

nix develop -c cargo test -p usbip-rs

Fuzzing

Fuzz targets are in lib/fuzz/ and exercise host-side codepaths against untrusted client input.

nix run .#fuzz-usbip                              # List targets
nix run .#fuzz-usbip -- fuzz_urb_hid              # Single process
nix run .#fuzz-usbip -- fuzz_urb_hid --fork=8     # Parallel (overnight)
nix run .#fuzz-clean-usbip -- fuzz_urb_hid        # Prune fixed artifacts

Crash artifacts: lib/fuzz/artifacts/<target>/. Response validation is in lib/src/fuzz_helpers.rs.

Fixing fuzzer crashes

  1. Priority: Protect the host process and host kernel from untrusted client gaining code execution or privilege escalation. DoS is not a concern — the client would only be DoSing its own service.
  2. Check reachability: Determine whether the crashing state can be reached by a normal, well-behaved client (check the Linux kernel USB/IP source at ../linux/drivers/usb/usbip/ and ../linux/tools/usb/usbip/). If not reachable by a well-behaved client, return an error rather than continuing to process garbage.
  3. No unsafe in parsing or sanitization paths.
  4. Validate at the boundary: Check constraints immediately after deserialization, not deep in business logic.
  5. Update fuzz assertions: Tighten the invariant assertions in lib/src/fuzz_helpers.rs whenever you add or change a constraint — the fuzzer can only find violations it can check.
  6. We are using our own nusb fork, and API compatibility is not a concern. If an issue is better fixed in nusb, stop and explain the situation.

Key architecture

  • handle_urb_loop() — main URB dispatch loop, generic over async transport
  • handler() — full connection handler (negotiation + URB loop), takes UsbIpServer
  • UsbInterfaceHandler trait — implement for new device types
  • Protocol parsing in usbip_protocol.rs, device model in device.rs
  • MockSocket in util::mock — used by both tests and fuzz targets

Conventions

  • No backwards compatibility concerns for the library API
  • pub use re-exports from lib.rs — e.g. mock module is available as usbip_rs::mock::MockSocket
  • Edition 2024