Skip to content

Commit 12f9d2a

Browse files
committed
feat: add roundtrip and malformed virtq fuzzing
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
1 parent bd4c939 commit 12f9d2a

11 files changed

Lines changed: 825 additions & 316 deletions

File tree

.github/workflows/Fuzzing.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
strategy:
2323
fail-fast: false
2424
matrix:
25-
target: ['fuzz_host_print', 'fuzz_guest_call', 'fuzz_host_call', 'fuzz_guest_estimate_trace_event', 'fuzz_guest_trace', 'fuzz_virtq_packed_ring']
25+
target: ['fuzz_host_print', 'fuzz_guest_call', 'fuzz_host_call', 'fuzz_guest_estimate_trace_event', 'fuzz_guest_trace', 'fuzz_virtq_malformed', 'fuzz_virtq_roundtrip']
2626
uses: ./.github/workflows/dep_fuzzing.yml
2727
with:
2828
target: ${{ matrix.target }}

.github/workflows/ValidatePullRequest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ jobs:
213213
if: ${{ !cancelled() && !failure() }}
214214
strategy:
215215
matrix:
216-
target: ['fuzz_host_print', 'fuzz_guest_call', 'fuzz_host_call', 'fuzz_guest_estimate_trace_event', 'fuzz_guest_trace', 'fuzz_virtq_packed_ring']
216+
target: ['fuzz_host_print', 'fuzz_guest_call', 'fuzz_host_call', 'fuzz_guest_estimate_trace_event', 'fuzz_guest_trace', 'fuzz_virtq_malformed', 'fuzz_virtq_roundtrip']
217217
arch:
218218
- X64
219219
# arm64 fuzzing runs on the daily schedule (DailyArm64.yml) instead of on

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5454
* Embedded byte payload tables and their value-union variants.
5555

5656
### Fixed
57+
* Allow reclaimed virtqueue completions to span multiple ring reuse cycles.
5758
* Virtqueue consumers return errors when payload copies or runtime bookkeeping
5859
cannot be allocated.
5960
* Use a 16 KiB-aligned default scratch size for Apple Silicon compatibility.

Justfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ like-ci config=default-target hypervisor="kvm":
218218
just fuzz-like-ci fuzz_host_call {{config}} {{hypervisor}}
219219
just fuzz-like-ci fuzz_guest_estimate_trace_event {{config}} {{hypervisor}}
220220
just fuzz-like-ci fuzz_guest_trace {{config}} {{hypervisor}}
221-
just fuzz-like-ci fuzz_virtq_packed_ring {{config}} {{hypervisor}}
221+
just fuzz-like-ci fuzz_virtq_malformed {{config}} {{hypervisor}}
222+
just fuzz-like-ci fuzz_virtq_roundtrip {{config}} {{hypervisor}}
222223

223224
@# spelling
224225
typos

fuzz/Cargo.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,15 @@ doc = false
4949
bench = false
5050

5151
[[bin]]
52-
name = "fuzz_virtq_packed_ring"
53-
path = "fuzz_targets/virtq_packed_ring.rs"
52+
name = "fuzz_virtq_malformed"
53+
path = "fuzz_targets/virtq_malformed.rs"
54+
test = false
55+
doc = false
56+
bench = false
57+
58+
[[bin]]
59+
name = "fuzz_virtq_roundtrip"
60+
path = "fuzz_targets/virtq_roundtrip.rs"
5461
test = false
5562
doc = false
5663
bench = false

fuzz/README.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,45 @@ which evaluates to the following command `cargo +nightly fuzz run fuzz_host_prin
1010

1111
As per Microsoft's Offensive Research & Security Engineering (MORSE) team, all host exposed functions that receive or interact with guest data must be continuously fuzzed for, at least, 500 million fuzz test cases without any crashes. Because `cargo-fuzz` doesn't support setting a maximum number of iterations; instead, we use the `--max_total_time` flag to set a maximum time to run the fuzzer. We have a GitHub action (acting like a CRON job) that runs the fuzzers for 24 hours every week.
1212

13-
Currently, we fuzz the parameters and return type to a hardcoded `PrintOutput` guest function, the `HostPrint` host function, the packed virtqueue ring parser, and canonical ring image validation. We plan to add more fuzzers in the future.
13+
Targets cover guest and host calls, printing, tracing, packed-ring parsing,
14+
canonical ring images, malformed consumer I/O, and producer/consumer round trips.
15+
16+
## Malformed virtqueues
17+
18+
`fuzz_virtq_malformed` exercises ring parsing, canonical images, and
19+
`VirtqConsumer` without a producer. Ring metadata and payloads have separate
20+
memory bounds. The consumer attempts at most eight polls per input, with two
21+
read/write rounds of at most 256 bytes per received chain, followed by completion.
22+
Consumer errors are accepted, including failed reads and reply writes.
23+
Panics and sanitizer findings fail the run.
24+
25+
Inputs have a 16-byte header and 12-byte descriptor records. Descriptor addresses
26+
use signed, wrapping offsets from the payload base. Header byte 13 selects the
27+
I/O length minus one. Trailing three-byte records select a little-endian `u16`
28+
offset and a replacement byte. Offsets wrap within the ring followed by the
29+
payload. When available, one mutation runs before each poll, read, reply write,
30+
and completion.
31+
Mutations run on the same thread between calls.
32+
33+
```sh
34+
just fuzz-timed fuzz_virtq_malformed 60
35+
cargo test -p hyperlight-fuzz --bin fuzz_virtq_malformed
36+
```
37+
38+
## Virtqueue round trip
39+
40+
`fuzz_virtq_roundtrip` checks one request/reply round trip without a VM. Inputs
41+
vary the payloads, I/O chunk size, and spare reply capacity. A fixed queue of
42+
16 descriptors and 64-byte pool slots exercises fragmented messages. The target
43+
checks payload bytes, completion types, backpressure, and resource release.
44+
45+
Inputs have a four-byte header and at most 1024 payload bytes. The header selects
46+
the request/reply split, I/O chunk size, and spare reply capacity.
47+
The malformed target shares the memory backend and covers malformed descriptors.
48+
49+
```sh
50+
just fuzz-timed fuzz_virtq_roundtrip 60
51+
```
1452

1553
## On Failure
1654

0 commit comments

Comments
 (0)