OpenPrinting / OpenPrinting/fuzzing
Memory allocation/deallocation mismatch in fuzz_array.c causes immediate crash with AddressSanitizer
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 8
- Forks
- 18
- Avg merge
- 7h 37m
- Merged PRs (30d)
- 1
Description
Description
Summary
The fuzz_array.c fuzzer has a critical memory management bug that causes it to crash immediately when built with AddressSanitizer. The fuzzer uses C's free() function to deallocate memory allocated with C++'s new[] operator,
violating C++ memory management rules.
Impact
- Status: Blocks all fuzzing of CUPS array functionality
- Scope: Affects anyone running
fuzz_arraywith AddressSanitizer (including OSS-Fuzz)
The fuzzer crashes on the very first test case, achieving zero code coverage and preventing discovery of real bugs in CUPS.
Root Cause
Allocation (C++ new[]) in fuzz_helpers.cpp:21,24:
void generate_fuzz_array_data(const uint8_t *data, size_t size, FuzzArray *outData) {
// ...
outData->str1 = new char[fuzz_str1.length() + 1]; // C++ new[]
outData->str2 = new char[fuzz_str2.length() + 1]; // C++ new[]
}
Deallocation (C free()) in fuzz_array.c:161-162:
free(first_string); // ❌ Wrong: should use delete[]
free(second_string); // ❌ Wrong: should use delete[]
AddressSanitizer Error
==1==ERROR: AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs free)
#0 in free
#1 in LLVMFuzzerTestOneInput fuzz_array.c:161:3
0x7be2be1e08d0 is located 0 bytes inside of 2-byte region
allocated by thread T0 here:
#0 in operator new[](unsigned long)
#1 in generate_fuzz_array_data fuzz_helpers.cpp:21:21
#2 in LLVMFuzzerTestOneInput fuzz_array.c:51:3
SUMMARY: AddressSanitizer: alloc-dealloc-mismatch fuzz_array.c:161:3
Reproduction Steps
1. Build fuzzers with AddressSanitizer:
# Using OSS-Fuzz infrastructure
python3 infra/helper.py build_fuzzers --sanitizer address cups
2. Run the fuzzer with any input:
./fuzz_array test_input
3. Expected: Fuzzer crashes immediately with alloc-dealloc-mismatch
Solution
The codebase already provides the correct deallocation function in fuzz_helpers.cpp:29-32:
void free_fuzz_array_data(FuzzArray *data) {
delete[] data->str1; // ✓ Correct
delete[] data->str2; // ✓ Correct
}
Fix: Replace the incorrect free() calls with the proper helper function.
Proposed Patch
--- a/projects/cups/fuzzer/fuzz_array.c
+++ b/projects/cups/fuzzer/fuzz_array.c
@@ -158,8 +158,8 @@
cupsArrayDelete(array);
cupsArrayDelete(dup_array);
- free(first_string);
- free(second_string);
+ // Free fuzz input data using the correct C++ delete[]
+ free_fuzz_array_data(&fuzzInput);
if (status != 0) {
abort();
Testing
After applying the patch:
1. Rebuild the fuzzer with AddressSanitizer
2. Run with test inputs - no crash should occur
3. Fuzzer should successfully test CUPS array operations
Additional Context
- C++ standard requires matching allocation/deallocation pairs:
- new → delete
- new[] → delete[]
- malloc() → free()
- Mixing these causes undefined behavior
- AddressSanitizer correctly detects this violation
The irony is that the correct solution (free_fuzz_array_data()) was already implemented in the codebase, but fuzz_array.c doesn't use it.
Environment
- Compiler: Clang with AddressSanitizer
- Platform: Any (bug is platform-independent C++ standard violation)
- OSS-Fuzz: Affected
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read projects/cups/fuzzer/fuzz_array.c around the cleanup at lines 158-162 and projects/cups/fuzzer/fuzz_helpers.cpp around generate_fuzz_array_data and free_fuzz_array_data. Build the CUPS fuzzer with AddressSanitizer and run fuzz_array with an input; done means the alloc-dealloc-mismatch crash is gone and array fuzzing proceeds.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cpp
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100