Issue 177634
Summary Excessive memory usage of libfuzzer when fuzzing with a recursive `Arbitrary` structure
Labels new issue
Assignees
Reporter V0ldek
    We're using `cargo fuzz` and libfuzzer in [rsonpath](https://github.com/rsonquery/rsonpath). In this particular case we are fuzzing the JSONPath parser to ensure any possible JSONPath query can be roundtripped.

```rs
//! Fuzz round-tripping - for every valid query parsing its `.to_string()` should give an equivalent query.
#![no_main]

use libfuzzer_sys::{fuzz_target, Corpus};
use rsonpath_syntax::JsonPathQuery;

fuzz_target!(|data: JsonPathQuery| -> Corpus {
    let str = data.to_string();
    match rsonpath_syntax::parse(&str) {
        Ok(query) => assert_eq!(data, query, "query string: {str}"),
        Err(err) if err.is_nesting_limit_exceeded() => return Corpus::Reject,
        Err(_) => panic!("expected parse to succeed"),
    }
 Corpus::Keep
});
```

A JSONPath query is recursive - it can contain any number of JSONPath queries nested within.

This fuzzer started causing CI failures because it almost immediately exceeds the default limit of 2560MB. This is not caused by the struct instances or any leak, it looks like libfuzzer's internal state balooning throughout program execution. Running it on my machine without a memory limit causes it to reach rss of 14 GB after an hour. Every step of the fuzzing is also very slow. Even with a tiny `-max_len=128` the memory usage hardly decreases, if at all.

<details> 
 <summary>Logs of batch fuzzing OOM </summary>
```ini
2026-01-23T04:49:25.2232517Z 2026-01-23 04:49:25,222 - root - INFO - Starting fuzzing
2026-01-23T05:04:16.6456364Z Fuzzing logs:
2026-01-23T05:04:16.6458257Z /github/workspace/build-out/query_fuzz_round_trip -timeout=25 -rss_limit_mb=2560 -len_control=0 -artifact_prefix=/tmp/tmpuipj_lpk/ -max_total_time=900 -print_final_stats=1 /github/workspace/cifuzz-corpus/query_fuzz_round_trip >fuzz-0.log 2>&1
2026-01-23T05:04:16.6461834Z /github/workspace/build-out/query_fuzz_round_trip -timeout=25 -rss_limit_mb=2560 -len_control=0 -artifact_prefix=/tmp/tmpuipj_lpk/ -max_total_time=900 -print_final_stats=1 /github/workspace/cifuzz-corpus/query_fuzz_round_trip >fuzz-3.log 2>&1
2026-01-23T05:04:16.6465400Z /github/workspace/build-out/query_fuzz_round_trip -timeout=25 -rss_limit_mb=2560 -len_control=0 -artifact_prefix=/tmp/tmpuipj_lpk/ -max_total_time=900 -print_final_stats=1 /github/workspace/cifuzz-corpus/query_fuzz_round_trip >fuzz-2.log 2>&1
2026-01-23T05:04:16.6468576Z /github/workspace/build-out/query_fuzz_round_trip -timeout=25 -rss_limit_mb=2560 -len_control=0 -artifact_prefix=/tmp/tmpuipj_lpk/ -max_total_time=900 -print_final_stats=1 /github/workspace/cifuzz-corpus/query_fuzz_round_trip >fuzz-1.log 2>&1
2026-01-23T05:04:16.6478612Z pulse...
2026-01-23T05:04:16.6480481Z ================== Job 1 exited with exit code 71 ============
2026-01-23T05:04:16.6481093Z INFO: Running with entropic power schedule (0xFF, 100).
2026-01-23T05:04:16.6481923Z INFO: Seed: 3786348150
2026-01-23T05:04:16.6482505Z INFO: Loaded 1 modules   (7432 inline 8-bit counters): 7432 [0x556a5749d220, 0x556a5749ef28), 
2026-01-23T05:04:16.6483017Z INFO: Loaded 1 PC tables (7432 PCs): 7432 [0x556a5749ef28,0x556a574bbfa8), 
2026-01-23T05:04:16.6483512Z INFO: 1285 files found in /github/workspace/cifuzz-corpus/query_fuzz_round_trip
2026-01-23T05:04:16.6484051Z INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
2026-01-23T05:04:16.6484584Z INFO: seed corpus: files: 1285 min: 1b max: 3936b total: 639438b rss: 37Mb
2026-01-23T05:04:16.6485004Z #1286	INITED cov: 1373 ft: 9492 corp: 949/461Kb exec/s: 0 rss: 78Mb
2026-01-23T05:04:16.6485414Z #8192	pulse  cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 4096 rss: 98Mb
2026-01-23T05:04:16.6485941Z #20397	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 4079 rss: 132Mb L: 39/3936 MS: 1 EraseBytes-
2026-01-23T05:04:16.6486519Z Loaded 1024/1287 files from /github/workspace/cifuzz-corpus/query_fuzz_round_trip
2026-01-23T05:04:16.6486999Z #32768	pulse  cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3640 rss: 159Mb
2026-01-23T05:04:16.6487430Z #65536	pulse  cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3449 rss: 215Mb
2026-01-23T05:04:16.6488008Z #126075	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3502 rss: 306Mb L: 57/3936 MS: 2 ChangeBinInt-EraseBytes-
2026-01-23T05:04:16.6488703Z #127192	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3533 rss: 307Mb L: 48/3936 MS: 2 ChangeByte-EraseBytes-
2026-01-23T05:04:16.6489664Z #131072	pulse cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3542 rss: 313Mb
2026-01-23T05:04:16.6490448Z #166683	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3472 rss: 362Mb L: 282/3936 MS: 2 ChangeByte-EraseBytes-
2026-01-23T05:04:16.6491397Z #197189	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3459 rss: 402Mb L: 781/3936 MS: 3 ShuffleBytes-CMP-EraseBytes- DE: "-9"-
2026-01-23T05:04:16.6492338Z #197306	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3461 rss: 402Mb L: 35/3936 MS: 2 EraseBytes-ShuffleBytes-
2026-01-23T05:04:16.6493241Z #302962	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3442 rss: 520Mb L: 38/3936 MS: 3 EraseBytes-CrossOver-ChangeByte-
2026-01-23T05:04:16.6494118Z #520518	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3424 rss: 743Mb L: 33/3936 MS: 2 ShuffleBytes-EraseBytes-
2026-01-23T05:04:16.6494901Z #870358	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3373 rss: 1069Mb L: 2600/3936 MS: 1 EraseBytes-
2026-01-23T05:04:16.6495574Z #1048576	pulse  cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3371 rss: 1219Mb
2026-01-23T05:04:16.6496231Z #1122308	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3370 rss: 1277Mb L: 35/3936 MS: 1 EraseBytes-
2026-01-23T05:04:16.6496977Z #1122634	REDUCE cov: 1373 ft: 9492 corp: 949/461Kb lim: 4096 exec/s: 3361 rss: 1277Mb L: 32/3936 MS: 1 EraseBytes-
2026-01-23T05:04:16.6497611Z #1141769	RELOAD cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3290 rss: 1292Mb
2026-01-23T05:04:16.6498198Z #1239504	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3296 rss: 1375Mb L: 2416/4057 MS: 1 EraseBytes-
2026-01-23T05:04:16.6499383Z #1318717	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3305 rss: 1448Mb L: 25/4057 MS: 2 InsertByte-EraseBytes-
2026-01-23T05:04:16.6500233Z #1548881	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3302 rss: 1673Mb L: 819/4057 MS: 1 EraseBytes-
2026-01-23T05:04:16.6501000Z #1638643	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3303 rss: 1741Mb L: 20/4057 MS: 1 EraseBytes-
2026-01-23T05:04:16.6501809Z 2026-01-23 05:04:16,645 - root - INFO - Fuzzer: query_fuzz_round_trip. Detected bug.
2026-01-23T05:04:16.6502586Z 2026-01-23 05:04:16,645 - root - INFO - Trying to reproduce crash using: /tmp/tmpuipj_lpk/oom-c80ab2c417b50ddf04243af8f0a092ed36049d93.
2026-01-23T05:04:16.6503620Z #1639228	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3304 rss: 1741Mb L: 37/4057 MS: 5 ChangeBit-ChangeByte-CopyPart-InsertByte-EraseBytes-
2026-01-23T05:04:16.6504827Z #1641380	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3302 rss: 1742Mb L: 35/4057 MS: 2 EraseBytes-PersAutoDict- DE: "-9"-
2026-01-23T05:04:16.6505786Z #1813476	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3309 rss: 1865Mb L: 1532/4057 MS: 2 PersAutoDict-EraseBytes- DE: "-9"-
2026-01-23T05:04:16.6506640Z #1960748	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3300 rss: 1976Mb L: 1289/4057 MS: 1 EraseBytes-
2026-01-23T05:04:16.6507609Z #1981664	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3297 rss: 1991Mb L: 19/4057 MS: 5 InsertByte-ChangeByte-PersAutoDict-CrossOver-EraseBytes- DE: "-9"-
2026-01-23T05:04:16.6508477Z #2097152	pulse  cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3292 rss: 2078Mb
2026-01-23T05:04:16.6509274Z #2146688	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3287 rss: 2115Mb L: 589/4057 MS: 2 InsertByte-EraseBytes-
2026-01-23T05:04:16.6510063Z #2275763	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3283 rss: 2208Mb L: 18/4057 MS: 1 EraseBytes-
2026-01-23T05:04:16.6511014Z #2337480	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3278 rss: 2251Mb L: 4026/4026 MS: 5 ChangeBit-ChangeASCIIInt-ChangeASCIIInt-CopyPart-EraseBytes-
2026-01-23T05:04:16.6512004Z #2384248	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3275 rss: 2283Mb L: 278/4026 MS: 2 ChangeBit-EraseBytes-
2026-01-23T05:04:16.6512836Z #2729115	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3260 rss: 2520Mb L: 215/4026 MS: 2 ChangeASCIIInt-EraseBytes-
2026-01-23T05:04:16.6513714Z #2746294	REDUCE cov: 1373 ft: 9493 corp: 950/465Kb lim: 4096 exec/s: 3261 rss: 2531Mb L: 3142/4026 MS: 3 EraseBytes-ShuffleBytes-CopyPart-
2026-01-23T05:04:16.6514436Z ==649== ERROR: libFuzzer: out-of-memory (used: 2563Mb; limit: 2560Mb)
2026-01-23T05:04:16.6514993Z    To change the out-of-memory limit use -rss_limit_mb=<N>
```
</details>

How to decrease the memory requirement of libfuzzer? This is not sustainable resource usage, even if I could afford a workstation instead of GitHub CI runners.

Previously raised in [rust-fuzz](https://github.com/rust-fuzz/libfuzzer/issues/138), redirected here.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to