diff options
Diffstat (limited to 'fuzz/wget_ftpls_fuzzer.c')
-rw-r--r-- | fuzz/wget_ftpls_fuzzer.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/fuzz/wget_ftpls_fuzzer.c b/fuzz/wget_ftpls_fuzzer.c index 138a549..2b67485 100644 --- a/fuzz/wget_ftpls_fuzzer.c +++ b/fuzz/wget_ftpls_fuzzer.c @@ -1,5 +1,5 @@ /* - * Copyright(c) 2017-2018 Free Software Foundation, Inc. + * Copyright (c) 2017-2019 Free Software Foundation, Inc. * * This file is part of GNU Wget. * @@ -59,30 +59,48 @@ FILE *fopen_wgetrc(const char *pathname, const char *mode) return NULL; } +static int do_jump; +static jmp_buf jmpbuf; #ifdef FUZZING void exit_wget(int status) { + longjmp(jmpbuf, 1); } -#else +#elif defined HAVE_DLFCN_H +#include <dlfcn.h> // dlsym +#ifndef RTLD_NEXT +#define RTLD_NEXT RTLD_GLOBAL +#endif void exit(int status) { + if (do_jump) { + longjmp(jmpbuf, 1); + } else { + void (*libc_exit)(int) = (void(*)(int)) dlsym (RTLD_NEXT, "exit"); + libc_exit(status); + } } #endif int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - FILE *fp, *bak; +#ifdef HAVE_FMEMOPEN + FILE *fp; struct fileinfo *fi; if (size > 4096) // same as max_len = ... in .options file return 0; - bak = stderr; - stderr = fopen("/dev/null", "w"); - fp = fmemopen((void *) data, size, "r"); if (!fp) return 0; + CLOSE_STDERR + + do_jump = 1; + + if (setjmp(jmpbuf)) + goto done; + fi = ftp_parse_ls_fp(fp, ST_UNIX); freefileinfo(fi); rewind(fp); @@ -96,12 +114,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) rewind(fp); fi = ftp_parse_ls_fp(fp, ST_MACOS); - freefileinfo(fi); +done: + freefileinfo(fi); fclose(fp); - fclose(stderr); - stderr = bak; + do_jump = 0; + RESTORE_STDERR +#endif return 0; } |