librdkafka icon indicating copy to clipboard operation
librdkafka copied to clipboard

[BUG] A heap-buffer-overflow in `emit` at `src/regexp.c:727:22`

Open JJLeo opened this issue 5 months ago • 1 comments

Description

  • Version: Latest commit 826f585
  • Environment: Ubuntu 20.04.6 LTS, Clang 18.1.8
  • Fuzzing harness: https://github.com/confluentinc/librdkafka/blob/master/tests/fuzzers/fuzz_regex.c

Please let me know if you encounter any issues reproducing it — I can upload a Docker image to help.

Steps to reproduce

git clone https://github.com/confluentinc/librdkafka.git --depth 1
cd librdkafka
export CC="clang"
export CXX="clang++"
export CFLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer"
export CXXFLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer -stdlib=libc++"
export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
mkdir build
cd build
cmake -DRDKAFKA_BUILD_STATIC=ON -DRDKAFKA_BUILD_EXAMPLES=OFF -DHAVE_REGEX=OFF ../
make

$CC -g -fPIC $CFLAGS -I../src -Igenerated/dummy \
    -c ../tests/fuzzers/fuzz_regex.c -o fuzz_regex.o
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE -rdynamic fuzz_regex.o -o fuzz_regex \
    ./src-cpp/librdkafka++.a ./src/librdkafka.a -lm -lssl -lcrypto \
    -lcrypto -lz -ldl -lpthread -lrt
./fuzz_regex $POC

Sanitizer output

==3919==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x524000003d20 at pc 0x63accb5bbb49 bp 0x7ffe16ea2190 sp 0x7ffe16ea2188
WRITE of size 1 at 0x524000003d20 thread T0
    #0 0x63accb5bbb48 in emit /src/librdkafka/src/regexp.c:727:22
    #1 0x63accb5bce6b in compile /src/librdkafka/src/regexp.c:840:27
    #2 0x63accb5bc044 in compile /src/librdkafka/src/regexp.c:761:25
    #3 0x63accb5bbd49 in compile /src/librdkafka/src/regexp.c:744:17
    #4 0x63accb5bbd49 in compile /src/librdkafka/src/regexp.c:744:17
    #5 0x63accb5bb2bb in re_regcomp /src/librdkafka/src/regexp.c:1062:9
    #6 0x63accb5ba8b9 in LLVMFuzzerTestOneInput /src/librdkafka/build/../tests/fuzzers/fuzz_regex.c:51:21
    #7 0x63accb46f2f0 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
    #8 0x63accb45a565 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6
    #9 0x63accb45ffff in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9
    #10 0x63accb48b2a2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #11 0x711250306082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0323ab4806bee6f846d9ad4bccfc29afdca49a58)
    #12 0x63accb45274d in _start (/src/librdkafka/build/fuzz_regex+0x4174d)

0x524000003d20 is located 0 bytes after 7200-byte region [0x524000002100,0x524000003d20)
allocated by thread T0 here:
    #0 0x63accb57b0bf in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:68:3
    #1 0x63accb5bb474 in rd_malloc /src/librdkafka/src/rd.h:140:19
    #2 0x63accb5bafcf in re_regcomp /src/librdkafka/src/regexp.c:1053:13
    #3 0x63accb5ba8b9 in LLVMFuzzerTestOneInput /src/librdkafka/build/../tests/fuzzers/fuzz_regex.c:51:21
    #4 0x63accb46f2f0 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
    #5 0x63accb45a565 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6
    #6 0x63accb45ffff in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9
    #7 0x63accb48b2a2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #8 0x711250306082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0323ab4806bee6f846d9ad4bccfc29afdca49a58)

SUMMARY: AddressSanitizer: heap-buffer-overflow /src/librdkafka/src/regexp.c:727:22 in emit
Shadow bytes around the buggy address:
  0x524000003a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x524000003b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x524000003b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x524000003c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x524000003c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x524000003d00: 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa
  0x524000003d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x524000003e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x524000003e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x524000003f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x524000003f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==3919==ABORTING

POC

librdkafka_crash_1.txt

Credit

Reported by Yifan Zhang, PLL

JJLeo avatar May 26 '25 09:05 JJLeo