diff options
Diffstat (limited to 'projects/binutils')
-rw-r--r-- | projects/binutils/Dockerfile | 2 | ||||
-rwxr-xr-x | projects/binutils/build.sh | 42 | ||||
-rw-r--r-- | projects/binutils/fuzz_cxxfilt.c | 39 | ||||
-rw-r--r-- | projects/binutils/fuzz_readelf.c | 61 | ||||
-rw-r--r-- | projects/binutils/fuzz_readelf.options | 2 | ||||
-rwxr-xr-x | projects/binutils/fuzz_readelf_seed_corpus/simple_elf | bin | 0 -> 6056 bytes | |||
-rw-r--r-- | projects/binutils/project.yaml | 1 |
7 files changed, 144 insertions, 3 deletions
diff --git a/projects/binutils/Dockerfile b/projects/binutils/Dockerfile index 9d0b59011..d384be1c6 100644 --- a/projects/binutils/Dockerfile +++ b/projects/binutils/Dockerfile @@ -18,7 +18,9 @@ FROM gcr.io/oss-fuzz-base/base-builder #TODO change MAINTAINER bug-binutils@gnu.org RUN apt-get update && apt-get install -y make +RUN apt-get install -y flex bison RUN git clone --recursive --depth 1 git://sourceware.org/git/binutils-gdb.git binutils-gdb WORKDIR $SRC COPY build.sh $SRC/ COPY fuzz_*.c $SRC/ +COPY fuzz_readelf_seed_corpus $SRC/fuzz_readelf_seed_corpus diff --git a/projects/binutils/build.sh b/projects/binutils/build.sh index 0c6fcc498..c7206f4cb 100755 --- a/projects/binutils/build.sh +++ b/projects/binutils/build.sh @@ -21,15 +21,51 @@ if [ "$SANITIZER" = undefined ]; then export CXXFLAGS="$CXXFLAGS -fno-sanitize=unsigned-integer-overflow" fi cd binutils-gdb + +# Comment out the lines of logging to stderror from elfcomm.c +# This is to make it nicer to read the output of libfuzzer. +cd binutils +sed -i 's/vfprintf (stderr/\/\//' elfcomm.c +sed -i 's/fprintf (stderr/\/\//' elfcomm.c +cd ../ + ./configure --disable-gdb --enable-targets=all make MAKEINFO=true && true + +# Make fuzzer directory mkdir fuzz cp ../fuzz_*.c fuzz/ - cd fuzz -ls fuzz_*.c | cut -d. -f1 | while read i; do + +for i in fuzz_disassemble fuzz_bfd; do $CC $CFLAGS -I ../include -I ../bfd -I ../opcodes -c $i.c -o $i.o $CXX $CXXFLAGS $i.o -o $OUT/$i $LIB_FUZZING_ENGINE ../opcodes/libopcodes.a ../bfd/libbfd.a ../libiberty/libiberty.a ../zlib/libz.a done - # TODO build corpuses + +# Now compile the src/binutils fuzzers +cd ../binutils + +# First copy the fuzzers, modify applications and copile object files +for i in readelf cxxfilt; do + cp ../../fuzz_$i.c . + + # Modify main functions so we dont have them anymore + sed 's/main (int argc/old_main (int argc, char **argv);\nint old_main (int argc/' $i.c >> $i.h + + # Compile object file + $CC $CFLAGS -DHAVE_CONFIG_H -I. -I../bfd -I./../bfd -I./../include -I./../zlib -DLOCALEDIR="\"/usr/local/share/locale\"" -Dbin_dummy_emulation=bin_vanilla_emulation -W -Wall -MT fuzz_$i.o -MD -MP -c -o fuzz_$i.o fuzz_$i.c +done + +# Link the files +## Readelf +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE -W -Wall -I./../zlib -o fuzz_readelf fuzz_readelf.o version.o unwind-ia64.o dwarf.o elfcomm.o ../libctf/.libs/libctf-nobfd.a -L/src/binutils-gdb/zlib -lz ../libiberty/libiberty.a +mv fuzz_readelf $OUT/fuzz_readelf + +### Set up seed corpus for readelf in the form of a single ELF file. +zip fuzz_readelf_seed_corpus.zip /src/fuzz_readelf_seed_corpus/simple_elf +mv fuzz_readelf_seed_corpus.zip $OUT/ + +## cxxfilt +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE -W -Wall -I./../zlib -o fuzz_cxxfilt fuzz_cxxfilt.o bucomm.o version.o filemode.o ../bfd/.libs/libbfd.a -L/src/binutils-gdb/zlib -lz ../libiberty/libiberty.a +mv fuzz_cxxfilt $OUT/fuzz_cxxfilt diff --git a/projects/binutils/fuzz_cxxfilt.c b/projects/binutils/fuzz_cxxfilt.c new file mode 100644 index 000000000..04aa23b35 --- /dev/null +++ b/projects/binutils/fuzz_cxxfilt.c @@ -0,0 +1,39 @@ +/* Copyright 2020 Google Inc. + +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. +*/ + + +#include "cxxfilt.h" + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (size < 3) + return 0; + char *new_str = malloc(size+1); + if (new_str == NULL) + return 0; + memcpy(new_str, data, size); + new_str[size] = '\0'; + int flags2 = (int)data[0]; + + cplus_demangle_set_style(DMGL_GNU_V3); + char *new_res = cplus_demangle(new_str, flags2); + if (new_res) + free(new_res); + + free(new_str); + return 0; +} diff --git a/projects/binutils/fuzz_readelf.c b/projects/binutils/fuzz_readelf.c new file mode 100644 index 000000000..3cf02e7b1 --- /dev/null +++ b/projects/binutils/fuzz_readelf.c @@ -0,0 +1,61 @@ +/* Copyright 2020 Google Inc. + +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. +*/ + +#include "readelf.h" + +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); + do_syms = TRUE; + do_reloc = TRUE; + do_unwind = TRUE; + do_dynamic = TRUE; + do_header = TRUE; + do_sections = TRUE; + do_section_groups = TRUE; + do_segments = TRUE; + do_version = TRUE; + do_histogram = TRUE; + do_arch = TRUE; + do_notes = TRUE; + + // Main fuzz entrypoint + process_file(filename); + + unlink(filename); + + free (dump_ctf_symtab_name); + free (dump_ctf_strtab_name); + free (dump_ctf_parent_name); + + // Unless we set this global variable to NULL, then we will run + // into a use-after-free error after a certain set of iterations. + // I have applied this patch because the authors of binutils + // prefer to think of their applications as "one-use-only" as written + // here: https://github.com/google/oss-fuzz/pull/2617 + symtab_shndx_list = NULL; + + return 0; +} diff --git a/projects/binutils/fuzz_readelf.options b/projects/binutils/fuzz_readelf.options new file mode 100644 index 000000000..00f65361c --- /dev/null +++ b/projects/binutils/fuzz_readelf.options @@ -0,0 +1,2 @@ +[libfuzzer] +detect_leaks = 0 diff --git a/projects/binutils/fuzz_readelf_seed_corpus/simple_elf b/projects/binutils/fuzz_readelf_seed_corpus/simple_elf Binary files differnew file mode 100755 index 000000000..deea86933 --- /dev/null +++ b/projects/binutils/fuzz_readelf_seed_corpus/simple_elf diff --git a/projects/binutils/project.yaml b/projects/binutils/project.yaml index e12d1318e..d85928611 100644 --- a/projects/binutils/project.yaml +++ b/projects/binutils/project.yaml @@ -5,3 +5,4 @@ auto_ccs : - "p.antoine@catenacyber.fr" - "nickc@redhat.com" - "amodra@gmail.com" + - "david@adalogics.com" |