mirror of
https://github.com/mirror/wget.git
synced 2025-03-31 14:40:18 +08:00
Fix oss-fuzz issue with exit()
* src/wget.h: Define exit() as exit_wget() * fuzz/wget_options_fuzzer.c: Implement exit_wget() and cleanup
This commit is contained in:
parent
bb03572c2a
commit
3ae58dae13
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user