diff --git a/projects/elfutils/build.sh b/projects/elfutils/build.sh index df8f8f674..7ee20cb9f 100755 --- a/projects/elfutils/build.sh +++ b/projects/elfutils/build.sh @@ -82,7 +82,6 @@ fi ASAN_OPTIONS=detect_leaks=0 make -j$(nproc) V=1 - $CC $CFLAGS \ -D_GNU_SOURCE -DHAVE_CONFIG_H \ -I. -I./lib -I./libelf -I./libebl -I./libdw -I./libdwelf -I./libdwfl -I./libasm \ @@ -90,4 +89,15 @@ $CC $CFLAGS \ $CXX $CXXFLAGS $LIB_FUZZING_ENGINE fuzz-dwfl-core.o \ ./libdw/libdw.a ./libelf/libelf.a -l:libz.a \ -o "$OUT/fuzz-dwfl-core" + +$CC $CFLAGS \ + -D_GNU_SOURCE -DHAVE_CONFIG_H \ + -I. -I./lib -I./libelf -I./libebl -I./libdw -I./libdwelf -I./libdwfl -I./libasm \ + -c "$SRC/fuzz-elf-get-sections.c" -o fuzz-elf-get-sections.o +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE fuzz-elf-get-sections.o \ + ./libasm/libasm.a ./libebl/libebl.a ./backends/libebl_backends.a ./libcpu/libcpu.a \ + ./libdw/libdw.a ./libelf/libelf.a ./lib/libeu.a -l:libz.a \ + -o "$OUT/fuzz-elf-get-sections" + +# Corpus cp "$SRC/fuzz-dwfl-core_seed_corpus.zip" "$OUT" diff --git a/projects/elfutils/fuzz-elf-get-sections.c b/projects/elfutils/fuzz-elf-get-sections.c new file mode 100644 index 000000000..1110330ca --- /dev/null +++ b/projects/elfutils/fuzz-elf-get-sections.c @@ -0,0 +1,70 @@ +/* Copyright 2022 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. +*/ + +/* Inspired by the elfgetzdata.c test */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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); + + // Main fuzz entrypoint in objdump.c + (void)elf_version(EV_CURRENT); + int fd = open(filename, O_RDONLY); + Elf *elf = elf_begin(fd, ELF_C_READ, NULL); + if (elf != NULL) { + size_t strndx; + elf_getshdrstrndx(elf, &strndx); + + Elf_Scn *scn = NULL; + // Iterate through sections + while ((scn = elf_nextscn(elf, scn)) != NULL) { + GElf_Shdr mem; + GElf_Shdr *shdr = gelf_getshdr(scn, &mem); + const char *name = elf_strptr(elf, strndx, shdr->sh_name); + + // Two options for reading sections. We keep the code structure + // so it resembles the test code. + // Compress and get data of the section + if ((shdr->sh_flags & SHF_COMPRESSED) != 0) { + if (elf_compress(scn, 0, 0) >= 0) { + elf_getdata(scn, NULL); + } + } else if (name != NULL) { + if (name[0] == '.' && name[1] == 'z') { + if (elf_compress_gnu(scn, 0, 0) >= 0) { + elf_getdata(scn, NULL); + } + } + } + } + elf_end(elf); + } + + close(fd); + unlink(filename); + return 0; +}