From 6053054a092d746e13eecc821043b776124001ee Mon Sep 17 00:00:00 2001 From: DavidKorczynski Date: Thu, 28 Oct 2021 22:06:40 +0100 Subject: [PATCH] binutils: add dlltool fuzzer (#6675) * binutils: add dlltool fuzzer * binutils: build in a loop to try multiple times * binutils: disable GAS building as AFLPP has problems with it * disable building ld to make aflpp work * binutils: simplify build * binutils: reenable gas fuzzer * binutils: conditionally build gas fuzzer --- projects/binutils/build.sh | 56 +++++++++++++++++++------- projects/binutils/fuzz_dlltool.c | 68 ++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 projects/binutils/fuzz_dlltool.c diff --git a/projects/binutils/build.sh b/projects/binutils/build.sh index 8688a2788..c2735fdbf 100755 --- a/projects/binutils/build.sh +++ b/projects/binutils/build.sh @@ -31,7 +31,9 @@ cd ../ ./configure --disable-gdb --disable-gdbserver --disable-gdbsupport \ --disable-libdecnumber --disable-readline --disable-sim \ - --disable-libbacktrace --disable-werror --enable-targets=all + --disable-libbacktrace --disable-gas --disable-ld --disable-werror \ + --enable-targets=all +make clean make MAKEINFO=true && true # Due to a bug in AFLPP that occurs *sometimes* we continue only if we have the @@ -82,6 +84,13 @@ if ([ -f ./libctf/.libs/libctf.a ]); then sed -i 's/copy_mian/copy_main/g' fuzz_$i.h done + # Special handling of dlltool + for i in dlltool; do + cp ../../fuzz_$i.c . + sed 's/main (int ac/old_main32 (int ac, char **av);\nint old_main32 (int ac/' $i.c > fuzz_$i.h + sed -i 's/copy_mian/copy_main/g' fuzz_$i.h + done + # Compile for i in objdump readelf nm objcopy; do $CC $CFLAGS -DHAVE_CONFIG_H -DOBJDUMP_PRIVATE_VECTORS="" -I. -I../bfd -I./../bfd -I./../include \ @@ -90,6 +99,15 @@ if ([ -f ./libctf/.libs/libctf.a ]); then fuzz_$i.o -MD -MP -c -o fuzz_$i.o fuzz_$i.c done + # Special handling of dlltool + for i in dlltool; do + $CC $CFLAGS -DHAVE_CONFIG_H -DOBJDUMP_PRIVATE_VECTORS="" -I. -I../bfd -I./../bfd -I./../include \ + -I./../zlib -DLOCALEDIR="\"/usr/local/share/locale\"" \ + -DDLLTOOL_I386 -DDLLTOOL_DEFAULT_I386 -Dbin_dummy_emulation=bin_vanilla_emulation -W -Wall -MT \ + fuzz_$i.o -MD -MP -c -o fuzz_$i.o fuzz_$i.c + done + + # Compile a special version of objdump that limits the amount # of calls to bfd_fatal. $CC $CFLAGS -DHAVE_CONFIG_H -DOBJDUMP_PRIVATE_VECTORS="" -DOBJDUMP_SAFE -I. -I../bfd -I./../bfd -I./../include \ @@ -127,23 +145,30 @@ if ([ -f ./libctf/.libs/libctf.a ]); then $CXX $CXXFLAGS $LIB_FUZZING_ENGINE -I./../zlib \ -o $OUT/fuzz_nm fuzz_nm.o bucomm.o version.o filemode.o \ -Wl,--start-group ${LIBS} -Wl,--end-group + + # link dlltool fuzzer + OBJS="defparse.o deflex.o bucomm.o version.o filemode.o" + $CXX $CXXFLAGS $LIB_FUZZING_ENGINE -I./../zlib \ + -o $OUT/fuzz_dlltool fuzz_dlltool.o ${OBJS} \ + -Wl,--start-group ${LIBS} -Wl,--end-group fi - # Build GAS fuzzer - cd ../gas - ./configure - make - sed 's/main (int argc/old_main32 (int argc, char **argv);\nint old_main32 (int argc/' as.c > fuzz_as.h - rm as.o || true - ar r libar.a *.o - - $CC $CFLAGS -DHAVE_CONFIG_H -I. -I. -I. -I../bfd -I./config -I./../include -I./.. -I./../bfd \ - -DLOCALEDIR="\"/usr/local/share/locale\"" -I./../zlib -c $SRC/fuzz_as.c -o fuzz_as.o - $CXX $CXXFLAGS $LIB_FUZZING_ENGINE -I./../zlib -o $OUT/fuzz_as ./fuzz_as.o \ - libar.a config/tc-i386.o config/obj-elf.o config/atof-ieee.o \ - ../opcodes/.libs/libopcodes.a ../bfd/.libs/libbfd.a \ - -L/src/binutils-gdb/zlib ../libiberty/libiberty.a -lz + # Build GAS fuzzer. Will keep this here in case GAS fuzzer is used in the future. + if [ "$FUZZING_ENGINE" != 'afl' ]; then + cd ../gas + ./configure + make + sed 's/main (int argc/old_main32 (int argc, char **argv);\nint old_main32 (int argc/' as.c > fuzz_as.h + rm as.o || true + ar r libar.a *.o + $CC $CFLAGS -DHAVE_CONFIG_H -I. -I. -I. -I../bfd -I./config -I./../include -I./.. -I./../bfd \ + -DLOCALEDIR="\"/usr/local/share/locale\"" -I./../zlib -c $SRC/fuzz_as.c -o fuzz_as.o + $CXX $CXXFLAGS $LIB_FUZZING_ENGINE -I./../zlib -o $OUT/fuzz_as ./fuzz_as.o \ + libar.a config/tc-i386.o config/obj-elf.o config/atof-ieee.o \ + ../opcodes/.libs/libopcodes.a ../bfd/.libs/libbfd.a \ + -L/src/binutils-gdb/zlib ../libiberty/libiberty.a -lz + fi # Set up seed corpus for readelf in the form of a single ELF file. # Assuming all went well then we can simply create a fuzzer based on # the object files in the binutils directory. @@ -169,6 +194,7 @@ if ([ -f ./libctf/.libs/libctf.a ]); then cp $OUT/fuzz_objcopy.options $OUT/fuzz_readelf.options cp $OUT/fuzz_objcopy.options $OUT/fuzz_as.options cp $OUT/fuzz_objcopy.options $OUT/fuzz_nm.options + cp $OUT/fuzz_objcopy.options $OUT/fuzz_dlltool.options cp $OUT/fuzz_objcopy.options $OUT/fuzz_objdump.options cp $OUT/fuzz_objcopy.options $OUT/fuzz_disas_ext-bfd_arch_csky.options fi diff --git a/projects/binutils/fuzz_dlltool.c b/projects/binutils/fuzz_dlltool.c new file mode 100644 index 000000000..6ecb07099 --- /dev/null +++ b/projects/binutils/fuzz_dlltool.c @@ -0,0 +1,68 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* + * We convert dlltool.c into a header file to make convenient for fuzzing. + * We do this for several of the binutils applications when creating + * the binutils fuzzers. + */ +#include "fuzz_dlltool.h" + +void +init_dlltool_global_state() { + import_list = NULL; + as_name = NULL; + as_flags = ""; + tmp_prefix = NULL; + exp_name = NULL; + imp_name = NULL; + delayimp_name = NULL; + identify_imp_name = NULL; + identify_strict = NULL; + head_label = NULL; + imp_name_lab = NULL; + dll_name = NULL; + add_indirect = 0; + add_underscore = 0; + add_stdcall_underscore = 0; + leading_underscore = -1; + dontdeltemps = 0; + do_default_excludes = true; + use_nul_prefixed_import_tables = false; + def_file = NULL; +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + char filename[256]; + sprintf(filename, "/tmp/libfuzzer.%d", getpid()); + FILE *fp = fopen(filename, "wb"); + if (!fp) { + return 0; + } + fwrite(data, size, 1, fp); + fclose(fp); + + init_dlltool_global_state(); + + program_name = "fuzz_dlltool"; + mname = "mcore-elf"; + + // At the moment we focus on the def file processing + def_file = filename; + process_def_file(filename); + + unlink(filename); + return 0; +}