diff --git a/fuzz/wget_options_fuzzer.c b/fuzz/wget_options_fuzzer.c index c737abb2..d3dcaff4 100644 --- a/fuzz/wget_options_fuzzer.c +++ b/fuzz/wget_options_fuzzer.c @@ -26,6 +26,7 @@ #include <string.h> // strncmp #include <fcntl.h> // open flags #include <unistd.h> // close +#include <setjmp.h> // longjmp, setjmp #ifdef __cplusplus extern "C" { @@ -35,6 +36,7 @@ void cleanup(void); FILE *fopen_wget(const char *pathname, const char *mode); FILE *fopen_wgetrc(const char *pathname, const char *mode); + void exit_wget(int status); #ifdef __cplusplus } #endif @@ -43,85 +45,6 @@ static const uint8_t *g_data; static size_t g_size; -static int dont_write; - -#if defined HAVE_DLFCN_H && defined HAVE_FMEMOPEN -#include <dlfcn.h> -#include <setjmp.h> -static jmp_buf jmpbuf; - -#ifdef RTLD_NEXT /* Not defined e.g. on CygWin */ -DIR *opendir(const char *name) -{ - DIR *(*libc_opendir)(const char *) = - (DIR *(*)(const char *)) dlsym (RTLD_NEXT, "opendir"); - - if (dont_write) - return NULL; - - return libc_opendir(name); -/* -#ifdef TEST_RUN - printf("opendir %s\n", name); - if (!strcmp(name, SRCDIR"/wget_options_fuzzer.in")) - return libc_opendir(name); - if (!strcmp(name, SRCDIR"/wget_options_fuzzer.new")) - return libc_opendir(name); - if (!strcmp(name, SRCDIR"/wget_options_fuzzer.repro")) - return libc_opendir(name); -#else - if (!strcmp(name, "wget_options_fuzzer.in")) - return libc_opendir(name); - if (!strcmp(name, "wget_options_fuzzer.new")) - return libc_opendir(name); - if (!strcmp(name, "wget_options_fuzzer.repro")) - return libc_opendir(name); -#endif - - return libc_opendir(name); -*/ -} - -/* -FILE *fopen(const char *pathname, const char *mode) -{ - FILE *(*libc_fopen)(const char *, const char *) = - (FILE *(*)(const char *, const char *)) dlsym (RTLD_NEXT, "fopen"); - - if (dont_write) { - size_t len = strlen(pathname); - const char *p; - - if (len >= 7 && !strcmp(pathname + len - 7, ".wgetrc") && !strcmp(mode, "r")) - return fmemopen((void *) g_data, g_size, mode); - - if ((p = strstr(pathname, "crash-")) && strlen(p) == 46) { - printf("open %s, %s\n", pathname, mode); - return libc_fopen(pathname, mode); - } - -// if (*mode == 'w') - return libc_fopen("/dev/null", mode); - -// printf("open %s, %s\n", pathname, mode); - } - - return libc_fopen(pathname, mode); -} -*/ - -void exit(int status) -{ - if (dont_write) - longjmp(jmpbuf, 1); - - void (*libc_exit)(int) = - (void(*)(int)) dlsym (RTLD_NEXT, "exit"); - - libc_exit(status); -} -#endif -#endif FILE *fopen_wget(const char *pathname, const char *mode) { @@ -130,12 +53,28 @@ FILE *fopen_wget(const char *pathname, const char *mode) FILE *fopen_wgetrc(const char *pathname, const char *mode) { +#ifdef HAVE_FMEMOPEN return fmemopen((void *) g_data, g_size, mode); +#else + return NULL; +#endif } +static jmp_buf jmpbuf; +#ifdef FUZZING +void exit_wget(int status) +{ + longjmp(jmpbuf, 1); +} +#else +void exit(int status) +{ + longjmp(jmpbuf, 1); +} +#endif + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { -// static const char *argv[] = { "wget", "-q", "--no-config", "--config", "d41d8cd98f00b204e9800998ecf8427e" }; static const char *argv[] = { "wget", "-q" }; if (size > 2048) // same as max_len = ... in .options file @@ -147,24 +86,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) FILE *bak = stderr; stderr = fopen("/dev/null", "w"); - dont_write = 1; + if (setjmp(jmpbuf)) + goto done; -// try not to open/write to the file system -#if defined HAVE_DLFCN_H && defined HAVE_FMEMOPEN - if (setjmp(jmpbuf)) { - cleanup(); - dont_write = 0; - fclose(stderr); - stderr = bak; - return 0; - } - -// enable_testing(); // function in wget to prevent unwanted action while testing main_wget(sizeof(argv)/sizeof(argv[0]), argv); - cleanup(); -#endif - dont_write = 0; +done: + cleanup(); + fclose(stderr); stderr = bak; diff --git a/src/wget.h b/src/wget.h index 84478373..be241d9f 100644 --- a/src/wget.h +++ b/src/wget.h @@ -397,11 +397,13 @@ typedef enum /* Rename fopen so we can have our own version in fuzz/main.c to not create random files. */ # define fopen(fp, mode) fopen_wget(fp, mode) +# define exit(status) exit_wget(status) /* In run_wgetrc() we call fopen_wgetrc() instead of fopen, so we can catch the call in our fuzzers. */ FILE *fopen_wget(const char *pathname, const char *mode); FILE *fopen_wgetrc(const char *pathname, const char *mode); +void exit_wget(int status); #else /* When not fuzzing, we want to call fopen() instead of fopen_wgetrc() */ # define fopen_wgetrc(fp) fopen(fp)