-
Notifications
You must be signed in to change notification settings - Fork 241
Open
Description
Hi, I decided to run a fuzz test and immediately noticed a crash.
==1309300==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50200002e236 at pc 0x607ae66664c5 bp 0x7ffc3e4badb0 sp 0x7ffc3e4bada8
WRITE of size 1 at 0x50200002e236 thread T0
#0 0x607ae66664c4 in parse_string(cJSON*, char const*, char const**) /home/fagus/isp/CJsonObject/cJSON.c:261:21
#1 0x607ae6660d80 in cJSON_Parse /home/fagus/isp/CJsonObject/cJSON.c:438:10
#2 0x607ae663e5bd in neb::CJsonObject::Parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /home/fagus/isp/CJsonObject/CJsonObject.cpp:507:19
#3 0x607ae663d9d4 in LLVMFuzzerTestOneInput /home/fagus/isp/CJsonObject/fuzz/cjson_fuzz.cpp:9:7
#4 0x607ae6548cb4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5ccb4) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#5 0x607ae65483a9 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5c3a9) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#6 0x607ae6549b95 in fuzzer::Fuzzer::MutateAndTestOne() (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5db95) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#7 0x607ae654a6f5 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile>>&) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5e6f5) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#8 0x607ae65379cf in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x4b9cf) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#9 0x607ae6562056 in main (/home/fagus/isp/CJsonObject/cjson_fuzz+0x76056) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#10 0x73ae0aa2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#11 0x73ae0aa2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#12 0x607ae652c9b4 in _start (/home/fagus/isp/CJsonObject/cjson_fuzz+0x409b4) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
0x50200002e236 is located 0 bytes after 6-byte region [0x50200002e230,0x50200002e236)
allocated by thread T0 here:
#0 0x607ae65fcde3 in malloc (/home/fagus/isp/CJsonObject/cjson_fuzz+0x110de3) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#1 0x607ae6665c3e in parse_string(cJSON*, char const*, char const**) /home/fagus/isp/CJsonObject/cJSON.c:252:19
#2 0x607ae6660d80 in cJSON_Parse /home/fagus/isp/CJsonObject/cJSON.c:438:10
#3 0x607ae663e5bd in neb::CJsonObject::Parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /home/fagus/isp/CJsonObject/CJsonObject.cpp:507:19
#4 0x607ae663d9d4 in LLVMFuzzerTestOneInput /home/fagus/isp/CJsonObject/fuzz/cjson_fuzz.cpp:9:7
#5 0x607ae6548cb4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5ccb4) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#6 0x607ae65483a9 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5c3a9) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#7 0x607ae6549b95 in fuzzer::Fuzzer::MutateAndTestOne() (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5db95) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#8 0x607ae654a6f5 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile>>&) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5e6f5) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#9 0x607ae65379cf in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x4b9cf) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#10 0x607ae6562056 in main (/home/fagus/isp/CJsonObject/cjson_fuzz+0x76056) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
#11 0x73ae0aa2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#12 0x73ae0aa2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#13 0x607ae652c9b4 in _start (/home/fagus/isp/CJsonObject/cjson_fuzz+0x409b4) (BuildId: 97cab75bade6e43708a54d786b0a65e04127801e)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/fagus/isp/CJsonObject/cJSON.c:261:21 in parse_string(cJSON*, char const*, char const**)
Shadow bytes around the buggy address:
0x50200002df80: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fd
0x50200002e000: fa fa fd fa fa fa fd fa fa fa 00 00 fa fa fd fa
0x50200002e080: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fd
0x50200002e100: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x50200002e180: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fd
=>0x50200002e200: fa fa 00 00 fa fa[06]fa fa fa fa fa fa fa fa fa
0x50200002e280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50200002e300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50200002e380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50200002e400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50200002e480: 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
==1309300==ABORTING
MS: 2 CopyPart-CMP- DE: "\000\014"-; base unit: 9b41b23eda7b652e05849707df184aa0506d173f
0x22,0x5c,0x22,0x5c,0x22,0x5c,0x22,0x5c,0x75,0x65,0x0,0xc,0x5b,0x75,0x65,0x5b,
\"\\\"\\\"\\\"\\ue\000\014[ue[
artifact_prefix='./'; Test unit written to ./crash-555d7775e697d9f9f0e169a6ce015a7ad1f24730
Base64: IlwiXCJcIlx1ZQAMW3VlWw==
The crash is reproducible even without sanitizer.
Steps to reproduce:
Create a Makefile for fuzzing in the root of the project (this is the easiest way to build, but not necessary)
CXX := clang++
CXXFLAGS := -std=c++11 -g -O1 -fsanitize=address,fuzzer
SRCS := fuzz/cjson_fuzz.cpp CJsonObject.cpp cJSON.c
TARGET := cjson_fuzz
all:
$(CXX) $(CXXFLAGS) -I. -o $(TARGET) $(SRCS)
clean:
rm -f $(TARGET)
Create a directory for the input data corpus to begin testing
mkdir corpus
echo '{}' > corpus/empty
echo '[]' > corpus/array
echo '{"a":1}' > corpus/obj
And let's create a simple fuzzing target using https://llvm.org/docs/LibFuzzer.html
cjson_fuzz.cpp
#include <cstddef>
#include <cstdint>
#include <string>
#include "CJsonObject.hpp"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
std::string s(Data, Data + Size);
neb::CJsonObject j;
j.Parse(s);
return 0;
}
Make:
make
And let's just run fuzzing
./cjson_fuzz ./corpus
We'll very quickly get a heap-buffer-overflow crash:
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 4160759713
INFO: Loaded 1 modules (2594 inline 8-bit counters): 2594 [0x62d030b4a028, 0x62d030b4aa4a),
INFO: Loaded 1 PC tables (2594 PCs): 2594 [0x62d030b4aa50,0x62d030b54c70),
INFO: 322 files found in ./corpus
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: seed corpus: files: 322 min: 1b max: 129b total: 5144b rss: 32Mb
#323 INITED cov: 168 ft: 483 corp: 166/3175b exec/s: 0 rss: 38Mb
#324 REDUCE cov: 168 ft: 483 corp: 166/3166b lim: 129 exec/s: 0 rss: 39Mb L: 81/129 MS: 1 EraseBytes-
#350 REDUCE cov: 168 ft: 483 corp: 166/3151b lim: 129 exec/s: 0 rss: 39Mb L: 44/129 MS: 1 EraseBytes-
#389 REDUCE cov: 168 ft: 483 corp: 166/3134b lim: 129 exec/s: 0 rss: 39Mb L: 55/129 MS: 4 CrossOver-ChangeBit-CrossOver-EraseBytes-
#415 NEW cov: 168 ft: 485 corp: 167/3165b lim: 129 exec/s: 0 rss: 39Mb L: 31/129 MS: 1 EraseBytes-
#606 REDUCE cov: 168 ft: 485 corp: 167/3148b lim: 129 exec/s: 0 rss: 40Mb L: 30/129 MS: 1 CrossOver-
#727 REDUCE cov: 168 ft: 485 corp: 167/3146b lim: 129 exec/s: 0 rss: 40Mb L: 11/129 MS: 1 EraseBytes-
#820 REDUCE cov: 168 ft: 485 corp: 167/3145b lim: 129 exec/s: 0 rss: 40Mb L: 7/129 MS: 3 ShuffleBytes-EraseBytes-ChangeByte-
#961 REDUCE cov: 168 ft: 485 corp: 167/3144b lim: 129 exec/s: 0 rss: 40Mb L: 11/129 MS: 1 CrossOver-
#1112 REDUCE cov: 168 ft: 485 corp: 167/3104b lim: 129 exec/s: 0 rss: 41Mb L: 50/129 MS: 1 EraseBytes-
=================================================================
==1314564==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5080000032f7 at pc 0x62d030aff4b8 bp 0x7ffdac561e70 sp 0x7ffdac561e68
READ of size 1 at 0x5080000032f7 thread T0
#0 0x62d030aff4b7 in parse_string(cJSON*, char const*, char const**) /home/fagus/isp/CJsonObject/cJSON.c:258:12
#1 0x62d030af9d80 in cJSON_Parse /home/fagus/isp/CJsonObject/cJSON.c:438:10
#2 0x62d030ad75bd in neb::CJsonObject::Parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /home/fagus/isp/CJsonObject/CJsonObject.cpp:507:19
#3 0x62d030ad69d4 in LLVMFuzzerTestOneInput /home/fagus/isp/CJsonObject/fuzz/cjson_fuzz.cpp:7:7
#4 0x62d0309e1cb4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5ccb4) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#5 0x62d0309e13a9 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5c3a9) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#6 0x62d0309e2b95 in fuzzer::Fuzzer::MutateAndTestOne() (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5db95) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#7 0x62d0309e36f5 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile>>&) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5e6f5) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#8 0x62d0309d09cf in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x4b9cf) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#9 0x62d0309fb056 in main (/home/fagus/isp/CJsonObject/cjson_fuzz+0x76056) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#10 0x758f1a22a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#11 0x758f1a22a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#12 0x62d0309c59b4 in _start (/home/fagus/isp/CJsonObject/cjson_fuzz+0x409b4) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
0x5080000032f7 is located 2 bytes after 85-byte region [0x5080000032a0,0x5080000032f5)
allocated by thread T0 here:
#0 0x62d030ad43e1 in operator new(unsigned long) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x14f3e1) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#1 0x62d030ad68c8 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::_M_construct<unsigned char const*>(unsigned char const*, unsigned char const*, std::forward_iterator_tag) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/basic_string.tcc:229:14
#2 0x62d030ad68c8 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string<unsigned char const*, void>(unsigned char const*, unsigned char const*, std::allocator<char> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/basic_string.h:765:4
#3 0x62d030ad68c8 in LLVMFuzzerTestOneInput /home/fagus/isp/CJsonObject/fuzz/cjson_fuzz.cpp:5:17
#4 0x62d0309e1cb4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5ccb4) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#5 0x62d0309e13a9 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5c3a9) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#6 0x62d0309e2b95 in fuzzer::Fuzzer::MutateAndTestOne() (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5db95) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#7 0x62d0309e36f5 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile>>&) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x5e6f5) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#8 0x62d0309d09cf in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/fagus/isp/CJsonObject/cjson_fuzz+0x4b9cf) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#9 0x62d0309fb056 in main (/home/fagus/isp/CJsonObject/cjson_fuzz+0x76056) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
#10 0x758f1a22a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#11 0x758f1a22a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#12 0x62d0309c59b4 in _start (/home/fagus/isp/CJsonObject/cjson_fuzz+0x409b4) (BuildId: 8811f46008271d7e5d23c0a7daf79a90f812b0ab)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/fagus/isp/CJsonObject/cJSON.c:258:12 in parse_string(cJSON*, char const*, char const**)
Shadow bytes around the buggy address:
0x508000003000: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fa
0x508000003080: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fa
0x508000003100: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fa
0x508000003180: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fa
0x508000003200: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 04 fa
=>0x508000003280: fa fa fa fa 00 00 00 00 00 00 00 00 00 00[05]fa
0x508000003300: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 03 fa
0x508000003380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x508000003400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x508000003480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x508000003500: 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
==1314564==ABORTING
MS: 1 InsertRepeatedBytes-; base unit: 469d265084ed5682f6171c7cb0bb0fe20bdc2a88
0x22,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x5c,0x75,0x30,
\"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\\u0
artifact_prefix='./'; Test unit written to ./crash-9d3143562b538b4c0311117276bcc334eefc4cf2
Base64: IkVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFXHUw
The crash is reproducible consistently, if you need any help with debugging, I can help.
almilos, sumlin, evgeniiz321, AliceInHunterland, szobov and 1 moreAliceInHunterland
Metadata
Metadata
Assignees
Labels
No labels