1 /*
2 * Copyright (c) 2017-2021 Free Software Foundation, Inc.
3 *
4 * This file is part of GNU Wget.
5 *
6 * GNU Wget is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GNU Wget is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Wget. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <config.h>
21
22 #include <sys/types.h>
23 #include <stdint.h> // uint8_t
24 #include <stdio.h> // fmemopen
25 #include <string.h> // strncmp
26 #include <stdlib.h> // free
27 #include <setjmp.h> // longjmp, setjmp
28 #include <fcntl.h> // open flags
29 #include <unistd.h> // close
30
31 #include "wget.h"
32 #undef fopen_wgetrc
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 #include "netrc.h"
38
39 // declarations for wget internal functions
40 int main_wget(int argc, const char **argv);
41 void cleanup(void);
42 FILE *fopen_wget(const char *pathname, const char *mode);
43 FILE *fopen_wgetrc(const char *pathname, const char *mode);
44 void exit_wget(int status);
45 #ifdef __cplusplus
46 }
47 #endif
48
49 #include "fuzzer.h"
50
fopen_wget(const char * pathname,const char * mode)51 FILE *fopen_wget(const char *pathname, const char *mode)
52 {
53 return fopen("/dev/null", mode);
54 }
55
fopen_wgetrc(const char * pathname,const char * mode)56 FILE *fopen_wgetrc(const char *pathname, const char *mode)
57 {
58 return NULL;
59 }
60
61 static int do_jump;
62 static jmp_buf jmpbuf;
63 #ifdef FUZZING
exit_wget(int status)64 void exit_wget(int status)
65 {
66 longjmp(jmpbuf, 1);
67 }
68 #elif defined HAVE_DLFCN_H
69 #include <dlfcn.h> // dlsym
70 #ifndef RTLD_NEXT
71 #define RTLD_NEXT RTLD_GLOBAL
72 #endif
exit(int status)73 void exit(int status)
74 {
75 if (do_jump) {
76 longjmp(jmpbuf, 1);
77 } else {
78 void (*libc_exit)(int) = (void(*)(int)) dlsym (RTLD_NEXT, "exit");
79 libc_exit(status);
80 }
81 }
82 #endif
83
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)84 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
85 {
86 #ifdef HAVE_FMEMOPEN
87 FILE *fp;
88 struct fileinfo *fi;
89 const char *user = NULL, *pw = NULL;
90
91 if (size > 4096) // same as max_len = ... in .options file
92 return 0;
93
94 fp = fmemopen((void *) data, size, "r");
95 if (!fp) return 0;
96
97 CLOSE_STDERR
98
99 do_jump = 1;
100
101 if (setjmp(jmpbuf))
102 goto done;
103
104 opt.netrc = 1;
105
106 user = NULL; // get first entry
107 search_netrc("x", &user, &pw, 1, fp);
108 netrc_cleanup();
109
110 user = "u"; // get entry for user 'u'
111 search_netrc("x", &user, &pw, 1, fp);
112
113 done:
114 netrc_cleanup();
115
116 fclose(fp);
117
118 do_jump = 0;
119
120 RESTORE_STDERR
121
122 #endif
123 return 0;
124 }
125