Closed
Description
Hi,
this is an issue found by fuzzing the current master branch.
Affected Projects
matio v1.5.28 (https://github.com/tbeu/matio)
Problem Type
CWE-122: Heap-based Buffer Overflow
Description
Summary
A heap-buffer-overflow vulnerability was discovered in the Mat_VarPrint function. This issue occurs when processing certain files, leading to an out-of-bounds read and potential application crash.
Details
The vulnerability arises in the Mat_VarPrint function defined in src/mat.c at line 2462. The function fails to properly check the buffer boundaries, resulting in a read operation beyond the allocated memory.
PoC
Steps to reproduce:
(According to OSS-Fuzz)
- Build it using the following commands :
git clone --depth 1 https://github.com/madler/zlib
git clone --depth 1 https://github.com/tbeu/matio.git matio
git clone --depth 1 --branch hdf5_1_14 https://github.com/HDFGroup/hdf5.git hdf5
cd matio/
#some env
export CC='clang'
export CFLAGS='-fsanitize=address,fuzzer-no-link -O1 -g'
export CXXFLAGS='-fsanitize=address,fuzzer -O1 -g'
export CXX='clang++'
export WORK=/fuzz/work
export SRC=/fuzz/project
export OUT=/fuzz/fuzzers
pushd "$SRC/zlib"
./configure --static --prefix="$WORK"
make -j$(nproc) CFLAGS="$CFLAGS -fPIC"
make install
popd
wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz
tar xvfvz autoconf-2.71.tar.gz
pushd autoconf-2.71
./configure
make
make install
popd
#build hdf5
pushd "$SRC"
cd hdf5
./autogen.sh
./configure --disable-shared --disable-deprecated-symbols --disable-hl --disable-parallel --disable-trace --disable-internal-debug --disable-asserts --disable-tests --disable-tools --with-pic --with-zlib="$WORK" --prefix="$WORK"
make -j$(nproc)
make install
popd
# build matio
./autogen.sh
./configure --prefix="$WORK" --disable-shared --with-hdf5="$WORK" --with-zlib="$WORK"
make -j$(nproc)
make install
MATIO_INCLUDE="$WORK/include"
MATIO_LIBS_NO_FUZZ="$WORK/lib/libmatio.a $WORK/lib/libhdf5.a $WORK/lib/libz.a"
MATIO_LIBS="$LIB_FUZZING_ENGINE $MATIO_LIBS_NO_FUZZ"
- Compile the fuzzer:
cd ./ossfuzz
for fuzzers in $(find . -name '*_fuzzer.cpp'); do
base=$(basename -s .cpp $fuzzers)
$CXX $CXXFLAGS -std=c++11 -I$MATIO_INCLUDE $fuzzers -o $OUT/$base $MATIO_LIBS
done
- Run the fuzzer to trigger the segmentation fault:
./matio_fuzzer src_mat.c_2462_69
The invalid read access will cause AddressSanitizer to report a segmentation fault during the execution of the post-processing logic.
Report
=================================================================
==24879==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60b00002bb24 at pc 0x5e76dec3cb3d bp 0x7ffc380a9790 sp 0x7ffc380a9788
READ of size 4 at 0x60b00002bb24 thread T0
#0 0x5e76dec3cb3c in Mat_VarPrint /fuzz/project/matio/src/mat.c:2462:69
#1 0x5e76dec3a9ae in Mat_VarPrint /fuzz/project/matio/src/mat.c:2252:25
#2 0x5e76dec3a9ae in Mat_VarPrint /fuzz/project/matio/src/mat.c:2252:25
#3 0x5e76dec2e199 in MatioRead(char const*) /fuzz/project/matio/ossfuzz/./matio_wrap.h:48:9
#4 0x5e76dec2e45d in LLVMFuzzerTestOneInput /fuzz/project/matio/ossfuzz/./matio_fuzzer.cpp:30:12
#5 0x5e76deb545f3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/fuzz/cs/matio_fuzzer+0x4665f3) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#6 0x5e76deb3e36f in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/fuzz/cs/matio_fuzzer+0x45036f) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#7 0x5e76deb440c6 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/fuzz/cs/matio_fuzzer+0x4560c6) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#8 0x5e76deb6dee2 in main (/fuzz/cs/matio_fuzzer+0x47fee2) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#9 0x78476f80fd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#10 0x78476f80fe3f in __libc_start_main csu/../csu/libc-start.c:392:3
#11 0x5e76deb38c34 in _start (/fuzz/cs/matio_fuzzer+0x44ac34) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
0x60b00002bb24 is located 0 bytes to the right of 100-byte region [0x60b00002bac0,0x60b00002bb24)
allocated by thread T0 here:
#0 0x5e76debf0e58 in __interceptor_calloc (/fuzz/cs/matio_fuzzer+0x502e58) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#1 0x5e76dec5a297 in ReadSparse /fuzz/project/matio/src/mat5.c:528:26
#2 0x5e76dec54a60 in Mat_VarRead5 /fuzz/project/matio/src/mat5.c:3391:26
#3 0x5e76dece2285 in ReadNextStructField /fuzz/project/matio/src/mat5.c:1692:45
#4 0x5e76dece1f42 in ReadNextStructField /fuzz/project/matio/src/mat5.c:1686:46
#5 0x5e76decde0d4 in Mat_VarReadNextInfo5 /fuzz/project/matio/src/mat5.c:5413:27
#6 0x5e76dec33b8f in Mat_VarReadNextInfoPredicate /fuzz/project/matio/src/mat.c:2651:22
#7 0x5e76dec33b8f in Mat_VarReadNextInfo /fuzz/project/matio/src/mat.c:2625:12
#8 0x5e76dec2e1de in MatioRead(char const*) /fuzz/project/matio/ossfuzz/./matio_wrap.h:42:23
#9 0x5e76dec2e45d in LLVMFuzzerTestOneInput /fuzz/project/matio/ossfuzz/./matio_fuzzer.cpp:30:12
#10 0x5e76deb545f3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/fuzz/cs/matio_fuzzer+0x4665f3) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#11 0x5e76deb3e36f in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/fuzz/cs/matio_fuzzer+0x45036f) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#12 0x5e76deb440c6 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/fuzz/cs/matio_fuzzer+0x4560c6) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#13 0x5e76deb6dee2 in main (/fuzz/cs/matio_fuzzer+0x47fee2) (BuildId: 69d0eac2c142cb2dc762c58d0e01e47ee83df8a8)
#14 0x78476f80fd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
SUMMARY: AddressSanitizer: heap-buffer-overflow /fuzz/project/matio/src/mat.c:2462:69 in Mat_VarPrint
Shadow bytes around the buggy address:
0x0c167fffd710: fa fa fa fa fa fa fd fd fd fd fd fd fd fd fd fd
0x0c167fffd720: fd fd fd fd fa fa fa fa fa fa fa fa fd fd fd fd
0x0c167fffd730: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa
0x0c167fffd740: fa fa fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c167fffd750: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
=>0x0c167fffd760: 00 00 00 00[04]fa fa fa fa fa fa fa fa fa fd fd
0x0c167fffd770: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
0x0c167fffd780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fffd790: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fffd7a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fffd7b0: 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
==24879==ABORTING
Metadata
Metadata
Assignees
Labels
No labels