OpenPrinting / OpenPrinting/fuzzing

Memory allocation/deallocation mismatch in fuzz_array.c causes immediate crash with AddressSanitizer

Open
#43 0 comments 0 reactions 0 assignees View on GitHub

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_array with 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.