-
Notifications
You must be signed in to change notification settings - Fork 11
Open
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: AffectedMetadata
Metadata
Assignees
Labels
No labels