Source-linked AI summary
Prompt Fuzzing for Fuzz Driver Generation
Yunlong Lyu, Yuxuan Xie, Peng Chen, Hao Chen
TL;DR
High-quality fuzz drivers are difficult to write, and existing automatic approaches trade broad API exploration against reaching deep states. PromptFuzz iteratively generates and validates drivers through coverage-guided prompt fuzzing. Across 14 libraries, its drivers achieved higher branch coverage than OSS-Fuzz and Hopper and detected new genuine bugs.
Problem
Consumer-code-derived drivers have limited coverage, while interpretative fuzzing needs many attempts across a large search space; prior LLM prompts also missed diverse and infrequent API usage.
Source: §1 · p. 1, §2.3 · p. 3Method
PromptFuzz iteratively mutates API-aware LLM prompts using code-coverage feedback, validates generated programs, and turns their API arguments into fuzzable variables.
Source: §1 · p. 1, §3.1 · p. 3Results
1.61 and 1.63 times higher branch coverage than OSS-Fuzz and Hopper, respectively; PromptFuzz found 33 genuine new bugs among 49 crashes, with 30 community-confirmed.
Source: §1 · p. 2, §8 · p. 12Takeaways & Limitations
PromptFuzz generates library fuzz drivers without requiring consumer code or domain knowledge.
Source: §8 · p. 12The experiments used GPT-3.5, and PromptFuzz performance may vary significantly with the LLM model used.
Source: §6 · p. 12
Abstract
from arXiv · showhide
Crafting high-quality fuzz drivers not only is time-consuming but also requires a deep understanding of the library. However, the state-of-the-art automatic fuzz driver generation techniques fall short of expectations. While fuzz drivers derived from consumer code can reach deep states, they have limited coverage. Conversely, interpretative fuzzing can explore most API calls but requires numerous attempts within a large search space. We propose PromptFuzz, a coverage-guided fuzzer for prompt fuzzing that iteratively generates fuzz drivers to explore undiscovered library code. To explore API usage in fuzz drivers during prompt fuzzing, we propose several key techniques: instructive program generation, erroneous program validation, coverage-guided prompt mutation, and constrained fuzzer scheduling. We implemented PromptFuzz and evaluated it on 14 real-world libraries. Compared with OSS-Fuzz and Hopper (the state-of-the-art fuzz driver generation tool), fuzz drivers generated by PromptFuzz achieved 1.61 and 1.63 times higher branch coverage than those by OSS-Fuzz and Hopper, respectively. Moreover, the fuzz drivers generated by PromptFuzz detected 33 genuine, new bugs out of a total of 49 crashes, out of which 30 bugs have been confirmed by their respective communities.
1 INTRODUCTION
Automatic fuzz-driver generation must balance broad API coverage with the ability to reach deep library states, while producing valid drivers is difficult. PromptFuzz iteratively mutates prompts using coverage feedback and outperforms OSS-Fuzz and Hopper in reported branch coverage.
1 INTRODUCTION
- Consumer-code-based driver generation can reach deep states but has limited coverage, while interpretative fuzzing can cover most APIs but needs many attempts across a vast search space.Consumer-code traces cannot reveal valid API usage absent from consumer code.Source: §1 · p. 1
- Earlier LLM-based fuzz-driver work used scenario-specific instructions, yielding low API-usage diversity and missing infrequently used code or deep states.PromptFuzz addresses this by iteratively adapting prompts to coverage feedback.Source: §1 · p. 1
- PromptFuzz iteratively mutates prompts with coverage guidance to explore undiscovered library code, validates generated programs, and converts API-call constants into fuzzable variables.The resulting drivers are fused into a driver compatible with existing fuzzers.Source: §1 · pp. 1–2
- 1.61 and 1.63 times higher branch coverage than OSS-Fuzz and Hopper, respectively; PromptFuzz also found 33 genuine new bugs among 49 crashes, with 30 community-confirmed.The evaluation covered 14 real-world libraries.Source: §1 · p. 2
2 BACKGROUND
Library fuzz drivers must translate random bytes into valid, constrained API arguments and exercise library functions, but writing them requires substantial library understanding. LLMs generate code from prompts, yet prior fuzz-driver prompting and validation approaches had important limits.
2.1 Library Fuzzing
- Library fuzz drivers convert random bytes into well-structured API arguments, invoke APIs, and exercise code; producing them well requires satisfying library constraints and understanding the library.The libvpx example highlights constrained arguments and iterative API calls in a decoding workflow.Source: §2.1 · p. 2
2.2 Large Language Model
- LLMs predict subsequent words from prior tokens and generate text autoregressively; user-provided starting tokens are prompts.Representative models named in the section include GPT-3, ChatGPT, and GPT-4.Source: §2.2 · p. 2
2.3 LLM-based Fuzz Driver Generation
- Prior LLM fuzz-driver prompts often targeted one API and produced simple or common usage, while compiler- or rule-based validation missed complex semantic errors such as incorrect library use.Buggy generated drivers can create false positives when used for fuzzing.Source: §2.3 · p. 3
3 DESIGN
PromptFuzz generates library programs from API-aware prompts, validates them, and uses coverage feedback to steer further prompt mutation. It also evolves fuzzing inputs and checks whether generated programs exercise important API calls.
3.1 Overview
- PromptFuzz extracts library signatures and types, generates and validates programs, stores valid seeds, and uses their coverage to mutate prompts toward new paths.It infers API argument constraints, converts constants into fuzzable variables, and consolidates seed programs into a fuzz driver.Source: §3.1 · p. 3
3.2 Instructive Program Generation
- Prompts combine required API functions, relevant library declarations, and optional library-specific specifications to guide programs toward desired code patterns.When libraries have many APIs, PromptFuzz selects a manageable subset; custom types are limited to those used by selected APIs.Source: §3.2 · p. 4
3.3 Erroneous Program Elimination
- PromptFuzz filters generated programs through compiler syntax checks, runtime sanitizers, and corpus fuzzing, then removes programs that fail coverage criteria.The sanitizer-based filtering conservatively removes identifiable violations, including some programs whose misuse triggers library errors.Source: §3.3 · pp. 4–5
3.3.1 Fuzzing Validation.
- PromptFuzz evolves the fuzzing corpus by retaining inputs that increase coverage, helping programs with custom input needs reach code that initial seeds may miss.Fuzzing proceeds while coverage increases and within a time budget; later rounds continue evolving the corpus.Source: §3.3.1 · p. 5
3.3.2 Coverage Validation.
- Coverage validation removes programs whose critical paths omit library API calls, addressing unreachable calls and API misuse that runtime sanitizers may not detect.It focuses on paths with the most API calls rather than all paths, and may mistakenly exclude programs without API misuse while reducing false positives.Source: §3.3.2 · p. 5
3.4 Coverage-Guide Prompt Mutation
PromptFuzz uses coverage feedback to mutate API combinations in prompts and guide iterative program generation. It schedules API functions and mutations using energy and seed-program quality to explore library usage.
3.4 Coverage-Guide Prompt Mutation
- Coverage feedback guides successive prompt mutations of API combinations, while API-level power scheduling helps generate effective prompts.The approach targets library code not yet explored by generated programs.Source: §3.4 · p. 5
3.4.1 Power Schedule.
- PromptFuzz reduces the energy of well-tested API functions to balance library coverage against LLM query costs.Additional prompts can increase coverage but also raise query costs; their benefit diminishes when coverage plateaus.Source: §3.4.1 · pp. 5–6
- Each iteration updates API-function branch coverage, including branches in recursive callees, not just the function body.The system maintains visited branches and call graphs for the library under test.Source: §3.4.1 · p. 6
- Fewer seed programs and prompts exercising an API function yield higher energy and a greater chance of including it in future prompts.The energy schedule uses seed-program count, prompt count, and an exponent regulating API-function frequency.Source: §3.4.1 · p. 6
3.4.2 Mutation strategies.
- Prompt mutations insert, replace, or cross over API functions, with energy-guided scheduling assembling combinations for unexplored usage.Combining APIs solely by exploration level can overlook dependencies between them.Source: §3.4.2 · p. 6
- Seed-program quality rewards both the maximum number of data-dependent API calls and the number of unique branches triggered.These measures capture correlated API calls and branch discovery.Source: §3.4.2 · p. 6
- Each iteration updates seed qualities; warm-up selects high-energy APIs, while later mutations pivot on critical-path calls that interact with others.The resulting API combination forms the prompt for the next program-generation round.Source: §3.4.2 · p. 6
3.5 Constrained Fuzzer Scheduling
PromptFuzz selects unique seeds, infers constraints on API arguments, converts suitable constants into fuzzable variables, and combines seeds into a fuzz driver.
3.5 Constrained Fuzzer Scheduling
- The final driver includes seeds that trigger unique branches, since these seeds encompass nearly all discovered API functions.Their API arguments are instrumented as variables under inferred constraints, and seeds are scheduled randomly.Source: §3.5 · p. 6
3.5.1 Argument Constraint Inference.
- Statistical inference and seed-program static analyses identify argument constraints such as array bounds, file paths, format strings, allocation sizes, and file descriptors.When several constraints are inferred for one argument, PromptFuzz uses the most frequently inferred constraint.Source: §3.5.1 · pp. 6–7
3.5.2 Constrained Argument Conversion.
- PromptFuzz converts constants into fuzz-byte variables, adjusts values to satisfy inferred constraints, and cancels conversions when sanitizers detect errors.It retains original constants for filename, format-string, allocation-size, and file-descriptor constraints; array lengths and indices are bounded by the corresponding array length.Source: §3.5.2 · p. 7
3.5.3 Fuzzer Scheduling.
- The consolidated driver schedules seed programs using bytes from fuzzers and starts with a corpus formed from the converted arguments’ constant values.Source: §3.5.3 · p. 7
4 IMPLEMENTATION
PromptFuzz is implemented in Rust with AST processing, control-flow and data-flow analyses, and a file-operation sanitizer.
4 IMPLEMENTATION
- PromptFuzz is implemented in 17 595 lines of Rust code, with its source available in a repository.Source: §4 · p. 7
4.1 AST Visitor
- An AST visitor extracts node attributes for argument-constraint inference and source transformation, while CFGs and intra-procedural data-flow analysis support critical-path and API-dependency analysis.The implementation deserializes ASTs using the clang_ast crate.Source: §4.1 · p. 7
4.2 File Sanitizer
- File-Sanitizer tracks file-descriptor, stream, and filename data flows to detect error operations such as descriptor leaks that ASan and UBSan do not detect.The errors can degrade performance and affect fuzz-driver effectiveness.Source: §4.2 · p. 7
5 EVALUATION
PromptFuzz was evaluated on 14 open-source libraries for coverage, bug detection, and the effects of its components. Results include higher overall branch coverage than OSS-Fuzz and Hopper, alongside findings on detected bugs, validation, argument constraints, and prompt mutation.
5.1 Overall Results
- The evaluation used five repeated experiments with average results and ran each consolidated fuzz driver under a 24-hour timeout.The fuzzing loop continued until 10 consecutive iterations found no new branches, without time or query-budget restrictions during generation.Source: §5.1 · p. 8
- 40.07% branch coverage was 1.61x OSS-Fuzz and 1.63x Hopper across the tested libraries.PromptFuzz had the highest branch coverage in 8 of 14 libraries; its shortfall was marginal for cJSON and zlib and within 1000 branches for libjpeg-turbo, libpcap, re2, and c-ares.Source: §5.1 · p. 8, Table 1 · p. 8, §5.2 · p. 8
5.3 Effectiveness on Bug Detection
- 30 of 44 unique crashes from the 24-hour fuzzing period were verified as valid bugs, with 27 confirmed by communities and three awaiting responses.The authors classified eight null-pointer crashes as library robustness issues rather than false positives; excluding those and six false positives, they reported 86.36% detection accuracy (38/44).Source: §5.3 · p. 9, §5.3.1 · p. 9
5.3.2 False Negative Analysis.
- PromptFuzz detected 18 of 22 bugs found by state-of-the-art library fuzzing approaches, missing cases because of validation, insufficient triggering inputs, or failure to generate buggy code patterns.In the additional 17-bug benchmark, it detected 15; two were missed because the relevant buggy code patterns were not generated, including one API in lcms.Source: §5.3.2 · pp. 9–10
5.3.3 Long-term Fuzzing.
- A further 15-day fuzzing session reported five unique crashes, three of which were confirmed as valid library bugs.Source: §5.3.3 · p. 10
5.4.1 Erroneous Programs Elimination.
- Validation eliminated 23,833 programs for syntax errors, 10,260 for abnormal runtime behavior, and 3,202 for insufficient coverage; review found 32 of 140 coverage-eliminated programs were mistakenly excluded.The reviewed remaining coverage eliminations included 108 programs with erroneous library usage; validation can exclude genuine programs even as it reduces spurious crashes.Source: §5.4.1 · p. 10
5.4.2 Argument Constraint Inference.
- Argument-constraint inference achieved 91.24% precision (250/274) and 79.61% recall (250/314), while converting arguments enabled detection of 15 of 33 identified bugs.The false positives in inferred constraints were not reported to cause additional spurious crashes; 15 bugs could only be detected through the additional converted arguments.Source: §5.4.2 · p. 11
5.4.3 Coverage Guide Prompt Mutation.
- With equal query budgets, coverage-guided prompt mutation outperformed blind mutation in 11 of 14 libraries, but not in libaom, zlib, or libpng.The authors attribute exceptions to API coupling or large API sets; in libpng, guided mutation could remain in local states, and the authors expected a larger query budget to address this.Source: §5.4.3 · p. 11
6 DISCUSSION & FUTURE DIRECTIONS
The discussion considers how model choice and detection accuracy could affect PromptFuzz, and notes that its evaluation covers open-source libraries. It also identifies closed-source use and broader software targets as future directions.
Evaluation scope
- The evaluation used GPT-3.5, and results may differ on closed-source libraries because the evaluated libraries’ source code was available and used to train the chosen model.The authors suggest fine-tuning LLMs could mitigate this issue.Source: §6 · p. 12
Detection accuracy
- PromptFuzz’s detection accuracy is 86.36%, and the authors discuss null-pointer assertions and LLM-based program repair as possible ways to improve it.Hopper inserts assertions after pointer-returning API calls; the authors propose adapting this and program-repair methods to reduce spurious crashes.Source: §6 · p. 12
Future directions
- The authors suggest extending PromptFuzz to web applications, embedded systems, or system applications by treating internal functions as interfaces.They point to whole-function fuzzing as inspiration for this extension.Source: §6 · p. 12
Evaluation scope
- The paper identifies model choice as a factor that could affect performance, noting that more powerful LLMs may better understand instructions and generate higher-quality programs.The experiments used GPT-3.5.Source: §6 · p. 12
7 RELATED WORK
Prior fuzz-driver generators rely on consumer code, user specifications, domain-specific constraints, or interpreter search, while LLM-based testing approaches target other tasks. PromptFuzz is positioned as automatic fuzz-driver generation that iteratively broadens library-code coverage.
7.1 Fuzz Driver Generation.
- Consumer-code and execution-trace methods, specification-based composition, Rust type constraints, and interpreter fuzzing each have stated limitations in scope or search effectiveness.Consumer-dependent methods do not address libraries without external consumers; other approaches require human integration, target domain-specific libraries, or face a large API-and-argument search space.Source: §7.1 · p. 12
- PromptFuzz generates fuzz drivers without external consumers or domain-specific models, while maintaining effectiveness in bug detection.The related-work discussion contrasts this with earlier approaches’ dependencies and limitations.Source: §7.1 · p. 12
7.2 Deep Learning-based Software Testing.
- Unlike LLM-based testing tools aimed at parsers, uncovered functions, or deep-learning APIs, PromptFuzz builds a loop that iteratively generates fuzz drivers to cover broader library code.The paper characterizes its drivers as testing varied library usage while maintaining high bug-detection accuracy.Source: §7.2 · p. 12
8 CONCLUSION
PromptFuzz uses coverage-guided prompt fuzzing and error oracles to generate fuzz drivers without consumer code or domain knowledge. On the evaluated libraries, its drivers achieved higher branch coverage than OSS-Fuzz and Hopper and detected new genuine bugs.
Results
- PromptFuzz’s fuzz drivers achieved 1.61 times greater branch coverage than OSS-Fuzz and 1.63 times greater than Hopper.The paper also reports 33 new genuine bugs from 49 crashes, with 30 confirmed by the respective communities.Source: §8 · p. 12
Approach
- PromptFuzz is a coverage-guided fuzz loop that iteratively constructs LLM prompts to explore library API usage and uses oracles to detect erroneous generated programs.It generates drivers without relying on consumer code or domain knowledge.Source: §8 · p. 12
Results
- The generated drivers detected 33 new genuine bugs among 49 crashes, and 30 of those bugs were confirmed by their communities.Source: §8 · p. 12
A EXAMPLE OF CONVERTED FUZZ DRIVER.
The appendix points to Figure 6 as an example of constrained argument conversion.
A EXAMPLE OF CONVERTED FUZZ DRIVER.
- Figure 6 presents an example of constrained argument conversion described in Section 3.5.2.Source: A EXAMPLE OF CONVERTED FUZZ DRIVER · p. 14
B EXAMPLES OF LIBRARY SPECIFICATION.
PromptFuzz’s library specifications add library-specific guidance to the prompt template when specialized usage rules are needed. The examples address setup requirements and API usage patterns for libmagic, sqlite3, and libTIFF.
B EXAMPLES OF LIBRARY SPECIFICATION.
- Specifications were manually crafted for 3 of the 14 tested libraries; the other 11 received no additional library specification.The specifications are inserted into the prompt template to facilitate specific code-pattern generation.Source: B EXAMPLES OF LIBRARY SPECIFICATION · p. 14
- For libmagic, the specification names and pre-positions the magic database file so generated code can pass its location to magic_load().libmagic API calls require a pre-loaded magic database.Source: B EXAMPLES OF LIBRARY SPECIFICATION · p. 14, Figure 7 · p. 14
- For sqlite3, the specification emphasizes calling sqlite3_close() after sqlite3_open(), whether or not opening the database succeeds, to mitigate memory leaks.This differs from the common *_open() and *_close() pairing pattern.Source: B EXAMPLES OF LIBRARY SPECIFICATION · pp. 14–15, Figure 8 · p. 15
- For libTIFF, the specification steers generation away from using TIFFFdOpen() with a file descriptor obtained through fmemopen(), a combination that consistently fails.The library also offers TIFFOpen() for a file location and TIFFStreamOpen() for a byte stream.Source: B EXAMPLES OF LIBRARY SPECIFICATION · p. 15, Figure 9 · p. 15