This repository now provides libFuzzer harnesses that exercise the runtime ST40 RX ancillary packet path, the ancillary helper utilities, the ST30 RX audio frame path, and the ST20/ST22 RX video frame pipelines. The harnesses are built only when the dedicated Meson option is enabled because they pull in DPDK and need an EAL environment.
- Clang/LLVM with
-fsanitize=fuzzersupport or a standalonelibFuzzerlibrary. - DPDK must already be available, as required by the main library build.
- Linux is recommended; the harnesses rely on EAL flags such as
--no-hugeand--in-memory.
You can turn the fuzzers on either directly through Meson or via the top-level
build.sh helper:
meson setup build -Denable_fuzzing=true./build.sh release enable_fuzzing
# or export MTL_BUILD_ENABLE_FUZZING=true before invoking build.shAdd -Denable_asan=true (or MTL_BUILD_ENABLE_ASAN=true) if you also want
AddressSanitizer instrumentation. Existing build directories can be reconfigured with
meson configure build -Denable_fuzzing=true.
Meson injects the MTL_ENABLE_FUZZING_ST40, MTL_ENABLE_FUZZING_ST30,
MTL_ENABLE_FUZZING_ST20, and MTL_ENABLE_FUZZING_ST22 defines so the RX
implementation exposes the minimal helper hooks required by the fuzzers.
After configuration simply run the standard build:
ninja -C buildThe following fuzz targets will be produced inside build/tests/fuzz/:
st40_rx_rtp_fuzz– feeds arbitrary RTP payloads throughrx_ancillary_session_handle_pkt, using a lightweight DPDK/EAL bootstrap.st40_ancillary_helpers_fuzz– targets the pure helper functions inst_ancillary.c(st40_set_udw,st40_get_udw, parity helpers, checksum, etc.).st30_rx_frame_fuzz– injects fuzzed RFC3550 audio RTP packets into the frame-level ST30 RX path, allocating a tiny in-memory framebuffer to exercise the sequencing and framing logic.st20_rx_frame_fuzz– drives the frame-level ST20 video RX path, including slot management, RTP parsing, bitmap tracking, and framebuffer assembly for RFC4175-formatted video payloads.st22_rx_frame_fuzz– targets the ST22 codestream RX path, validating packetized codestream parsing, JPVS/COLR box handling, and codestream reassembly logic.
Each target is a standalone libFuzzer executable. A minimal invocation looks like:
./build/tests/fuzz/st40_rx_rtp_fuzz -runs=1000 corpus_dirThe harness configures EAL internally (--no-huge --in-memory --no-shconf -c1 -n1),
so no additional environment setup is required beyond access to /dev/hugepages not
being mandatory.
A similar invocation drives the ST30 frame harness:
./build/tests/fuzz/st30_rx_frame_fuzz -max_total_time=60 corpus_audioAnd the new ST20/ST22 video harnesses can be exercised with:
./build/tests/fuzz/st20_rx_frame_fuzz -max_total_time=60 corpus_video
./build/tests/fuzz/st22_rx_frame_fuzz -max_total_time=60 corpus_codestreamFor long fuzzing sessions point the binary at a writable corpus directory. The helper fuzzer works the same way:
./build/tests/fuzz/st40_ancillary_helpers_fuzz -max_total_time=60 corpus_helpersThe validation suite drives every fuzz target with long-running libFuzzer passes and
streams the combined libFuzzer/MTL output into
tests/validation/logs/latest/pytest.log. Execute:
pytest tests/validation/fuzzing/test_fuzzing.py -k fuzzEach test carries @pytest.mark.nightly and runs -runs=500000 iterations by default
(override via MTL_FUZZ_TEST_RUNS). That keeps quick developer test shards short while
allowing the nightly job to exercise a deeper corpus.
All harnesses automatically raise the MTL and DPDK log level to DEBUG and install a
custom printer that forwards every log line to stderr. When invoked through pytest (or
manually), you will see MTL:-prefixed lines for interesting events—payload-type / SSRC
mismatches, redundant packets, enqueue failures, etc.—inside the test logs without any
extra configuration.
- The RX harness drains the session ring immediately after notifying the callback so mbufs are always released, which keeps memory usage stable even under ASan.
- Inputs must be at least the size of an RFC8331 ancillary header (62 bytes) to ensure the handler never reads beyond the provided mbuf.
- All harnesses cap their input size to fit inside a standard DPDK mbuf (2 KiB) to avoid oversized allocations during fuzzing.
- The ST30 harness requires inputs large enough to contain an RFC3550 audio header (12 bytes). Packets larger than 2 KiB are truncated so they still fit within a single mbuf.
- The ST20 harness expects RFC4175-style video payloads (12-byte RTP header plus video-specific extensions). Packets shorter than the combined header size are ignored.
- The ST22 harness operates on RFC9134 codestream packets. Inputs must include at least the base JP2K header; larger payloads exercise the box parsing and codestream completion/marker logic.