| 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