Create a libfuzzer harness for the png image format. Once built, the fuzzer runs as: ./grub-fuzz-png <corpus-dir>
With some hackery it can also be built with the address sanitizer or afl++. With regard to the license: I first worked on this while I was at IBM. I believe, looking at the fuzz fixes, that this would have been 2021-2022. The code was released to a cross-company grub security working group at this time. I left IBM in April 2022. Work subsequent to that is my own, and is unrelated to my subsequent employer. Signed-off-by: Daniel Axtens <d...@axtens.net> --- .gitignore | 1 + Makefile.util.def | 78 ++++++++++++++++++++++++++++++++++ grub-core/tests/fuzz/imageXX.c | 75 ++++++++++++++++++++++++++++++++ grub-core/tests/fuzz/png.c | 3 ++ 4 files changed, 157 insertions(+) create mode 100644 grub-core/tests/fuzz/imageXX.c create mode 100644 grub-core/tests/fuzz/png.c diff --git a/.gitignore b/.gitignore index 4064d3d1ec89..05cb43189156 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ grub-emu grub-emu-lite grub-emu-lite.exe grub-emu.exe +grub-fuzz-png grub-macho2img grub_emu_init.c grub_emu_init.h diff --git a/Makefile.util.def b/Makefile.util.def index beaef1168f0d..decced46ec19 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -53,6 +53,63 @@ library = { common = grub-core/fs/archelp.c; }; +library = { + name = libfuzzkern.a; + cflags = '$(CFLAGS_GNULIB) -fsanitize=fuzzer-no-link'; + cppflags = '$(CPPFLAGS_GNULIB) -I$(srcdir)/grub-core/lib/json -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION'; + + nostrip = common; + + condition = COND_ENABLE_FUZZERS; + + common = util/misc.c; + common = grub-core/kern/command.c; + common = grub-core/kern/device.c; + common = grub-core/kern/disk.c; + common = grub-core/lib/disk.c; + common = util/getroot.c; + common = grub-core/osdep/unix/getroot.c; + common = grub-core/osdep/getroot.c; + common = grub-core/osdep/devmapper/getroot.c; + common = grub-core/osdep/relpath.c; + extra_dist = grub-core/kern/disk_common.c; + extra_dist = grub-core/osdep/unix/relpath.c; + extra_dist = grub-core/osdep/aros/relpath.c; + extra_dist = grub-core/osdep/windows/relpath.c; + common = grub-core/kern/emu/hostdisk.c; + common = grub-core/osdep/devmapper/hostdisk.c; + common = grub-core/osdep/hostdisk.c; + common = grub-core/osdep/unix/hostdisk.c; + common = grub-core/osdep/exec.c; + common = grub-core/osdep/sleep.c; + common = grub-core/osdep/password.c; + common = grub-core/kern/emu/misc.c; + common = grub-core/kern/emu/mm.c; + common = grub-core/kern/env.c; + common = grub-core/kern/err.c; + common = grub-core/kern/file.c; + common = grub-core/kern/fs.c; + common = grub-core/kern/list.c; + common = grub-core/kern/misc.c; + common = grub-core/kern/partition.c; + common = grub-core/lib/crypto.c; + common = grub-core/lib/json/json.c; + common = grub-core/disk/luks.c; + common = grub-core/disk/luks2.c; + common = grub-core/disk/geli.c; + common = grub-core/disk/cryptodisk.c; + common = grub-core/disk/AFSplitter.c; + common = grub-core/lib/pbkdf2.c; + common = grub-core/commands/extcmd.c; + common = grub-core/lib/arg.c; + common = grub-core/disk/ldm.c; + common = grub-core/disk/diskfilter.c; + common = grub-core/partmap/gpt.c; + common = grub-core/partmap/msdos.c; + common = grub-core/fs/proc.c; + common = grub-core/fs/archelp.c; +}; + library = { name = libgrubmods.a; cflags = '-fno-builtin -Wno-undef'; @@ -1409,3 +1466,24 @@ program = { ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; + +program = { + name = grub-fuzz-png; + + nostrip = common; + + common = grub-core/video/readers/png.c; + common = grub-core/video/bitmap.c; + common = grub-core/io/bufio.c; + + extra_dist = grub-core/tests/fuzz/imageXX.c; + common = grub-core/tests/fuzz/png.c; + + ldadd = 'libfuzzkern.a grub-core/lib/gnulib/libgnu.a $(LIBDEVMAPPER)'; + + cppflags = '-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION'; + cflags='-fsanitize=fuzzer-no-link'; + ldflags='-fsanitize=fuzzer'; + + condition = COND_ENABLE_FUZZERS; +}; diff --git a/grub-core/tests/fuzz/imageXX.c b/grub-core/tests/fuzz/imageXX.c new file mode 100644 index 000000000000..4985cc5d0172 --- /dev/null +++ b/grub-core/tests/fuzz/imageXX.c @@ -0,0 +1,75 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2021-2023 Free Software Foundation, Inc. + * Copyright (C) 2021-2022 IBM Corporation + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <grub/misc.h> +#include <grub/bitmap.h> +#include <grub/procfs.h> +#include <grub/mm.h> + +int LLVMFuzzerTestOneInput (const grub_uint8_t *Data, grub_size_t Size); +extern void MODULE_INIT (void); +extern void grub_procfs_init (void); + +static const grub_uint8_t *data; +static grub_size_t size; +static bool inited; +static struct grub_video_bitmap *bitmap; + +static char * +get_file_contents (grub_size_t *sz) +{ + char *ret; + *sz = size; + ret = grub_malloc (size); + if (ret) + grub_memcpy (ret, data, size); + return ret; +} + +static struct grub_procfs_entry file_entry = +{ + .name = "file." IMG_EXTENSION, + .get_contents = get_file_contents +}; + +static inline void init() +{ + if (inited) + return; + grub_procfs_register ("file." IMG_EXTENSION, &file_entry); + MODULE_INIT(); + grub_procfs_init(); + inited = true; +} + +int LLVMFuzzerTestOneInput(const grub_uint8_t *Data, grub_size_t Size) { + + init(); + data = Data; + size = Size; + grub_err_t err; + + grub_errno = GRUB_ERR_NONE; + err = grub_video_bitmap_load(&bitmap, "(proc)/file." IMG_EXTENSION); + if (err == GRUB_ERR_NONE) { + grub_video_bitmap_destroy(bitmap); + } + + return 0; +} diff --git a/grub-core/tests/fuzz/png.c b/grub-core/tests/fuzz/png.c new file mode 100644 index 000000000000..315bc2326271 --- /dev/null +++ b/grub-core/tests/fuzz/png.c @@ -0,0 +1,3 @@ +#define IMG_EXTENSION "png" +#define MODULE_INIT grub_png_init +#include "imageXX.c" -- 2.25.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel