8000 add a fuzzer for mnt_table_parse_stream · evverx/util-linux@08e74af · GitHub
[go: up one dir, main page]

Skip to content

Commit 08e74af

Browse files
committed
add a fuzzer for mnt_table_parse_stream
The fuzzer is supposed to cover `mnt_table_parse_stream`, which is used by systemd to parse /proc/self/mountinfo. The systemd project has run into memory leaks there at least twice: systemd/systemd#12252 (comment) systemd/systemd#8504 so it seems to be a good idea to continuously fuzz that particular function. The patch can be tested locally by installing clang and running ./tools/oss-fuzz.sh. Currently the fuzzer is failing with ``` ================================================================= ==96638==ERROR: LeakSanitizer: detected memory leaks Direct leak of 216 byte(s) in 1 object(s) allocated from: #0 0x50cd77 in calloc (/home/vagrant/util-linux/out/test_mount_fuzz+0x50cd77) #1 0x58716a in mnt_new_fs /home/vagrant/util-linux/libmount/src/fs.c:36:25 #2 0x54f224 in __table_parse_stream /home/vagrant/util-linux/libmount/src/tab_parse.c:728:9 #3 0x54eed8 in mnt_table_parse_stream /home/vagrant/util-linux/libmount/src/tab_parse.c:804:8 #4 0x5448b2 in LLVMFuzzerTestOneInput /home/vagrant/util-linux/libmount/src/fuzz.c:19:16 util-linux#5 0x44cc88 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/vagrant/util-linux/out/test_mount_fuzz+0x44cc88) util-linux#6 0x44d8b0 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/home/vagrant/util-linux/out/test_mount_fuzz+0x44d8b0) util-linux#7 0x44e270 in fuzzer::Fuzzer::MutateAndTestOne() (/home/vagrant/util-linux/out/test_mount_fuzz+0x44e270) util-linux#8 0x450617 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/home/vagrant/util-linux/out/test_mount_fuzz+0x450617) util-linux#9 0x43adbb in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/vagrant/util-linux/out/test_mount_fuzz+0x43adbb) util-linux#10 0x42ad46 in main (/home/vagrant/util-linux/out/test_mount_fuzz+0x42ad46) util-linux#11 0x7fa084f621a2 in __libc_start_main (/lib64/libc.so.6+0x271a2) SUMMARY: AddressSanitizer: 216 byte(s) leaked in 1 allocation(s). INFO: to ignore leaks on libFuzzer side use -detect_leaks=0. ``` Once the bug is fixed and the OSS-Fuzz counterpart is merged it should be possible to turn on CIFuzz to make sure the fuzz target can be built and run for some time without crashing: https://google.github.io/oss-fuzz/getting-started/continuous-integration/< 8000 /a>
1 parent d454da1 commit 08e74af

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

configure.ac

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ AS_IF([test "x$enable_asan" = xyes], [
167167
])
168168
AC_SUBST([ASAN_LDFLAGS])
169169

170+
AC_ARG_ENABLE([fuzzing-engine],
171+
AS_HELP_STRING([--enable-fuzzing-engine], [compile with fuzzing engine]),
172+
[], [enable_fuzzing_engine=no]
173+
)
174+
AC_PROG_CXX
175+
AM_CONDITIONAL([FUZZING_ENGINE], [test x$enable_fuzzing_engine = xyes])
176+
170177
dnl libtool-2
171178
LT_INIT
172179

libmount/src/Makemodule.am

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ check_PROGRAMS += \
7878
test_mount_tab_update \
7979
test_mount_utils \
8080
test_mount_version \
81-
test_mount_debug
81+
test_mount_debug \
82+
test_mount_fuzz
8283
if LINUX
8384
check_PROGRAMS += test_mount_context
8485
check_PROGRAMS += test_mount_monitor
@@ -147,6 +148,17 @@ test_mount_debug_CFLAGS = $(libmount_tests_cflags)
147148
test_mount_debug_LDFLAGS = $(libmount_tests_ldflags)
148149
test_mount_debug_LDADD = $(libmount_tests_ldadd)
149150

151+
if FUZZING_ENGINE
152+
test_mount_fuzz_SOURCES = libmount/src/fuzz.c
153+
154+
# https://google.github.io/oss-fuzz/getting-started/new-project-guide/#Requirements
155+
nodist_EXTRA_test_mount_fuzz_SOURCES = dummy.cxx
156+
157+
test_mount_fuzz_CFLAGS = $(libmount_tests_cflags)
158+
test_mount_fuzz_LDFLAGS = $(libmount_tests_ldflags)
159+
test_mount_fuzz_LDADD = $(libmount_tests_ldadd) $(LIB_FUZZING_ENGINE)
160+
endif
161+
150162
endif # BUILD_LIBMOUNT_TESTS
151163

152164

libmount/src/fuzz.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include "mountP.h"
2+
3+
#include <stddef.h>
4+
#include <stdint.h>
5+
6+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
7+
struct libmnt_table *tb = NULL;
8+
FILE *f = NULL;
9+
10+
if (size == 0)
11+
return 0;
12+
13+
tb = mnt_new_table();
14+
assert(tb);
15+
16+
f = fmemopen((char*) data, size, "re");
17+
assert(f);
18+
19+
(void) mnt_table_parse_stream(tb, f, "mountinfo");
20+
21+
mnt_unref_table(tb);
22+
fclose(f);
23+
24+
return 0;
25+
}

tools/oss-fuzz.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex
4+
5+
export LC_CTYPE=C.UTF-8
6+
7+
export CC=${CC:-clang}
8+
export CXX=${CXX:-clang++}
9+
export LIB_FUZZING_ENGINE=${LIB_FUZZING_ENGINE:--fsanitize=fuzzer}
10+
11+
SANITIZER=${SANITIZER:-address -fsanitize-address-use-after-scope}
12+
flags="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=$SANITIZER -fsanitize=fuzzer-no-link"
13+
14+
export CFLAGS=${CFLAGS:-$flags}
15+
export CXXFLAGS=${CXXFLAGS:-$flags}
16+
17+
export OUT=${OUT:-$(pwd)/out}
18+
mkdir -p $OUT
19+
20+
./autogen.sh
21+
./configure --disable-all-programs --enable-fuzzing-engine --enable-libmount --enable-libblkid
22+
make -j$(nproc) V=1 check-programs
23+
24+
find . -maxdepth 1 -type f -executable -name "test_*_fuzz" -exec mv {} $OUT \;
25+
find . -type f -name "fuzz-*.dict" -exec cp {} $OUT \;

0 commit comments

Comments
 (0)
0