• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2021 Google LLC
2 Licensed under the Apache License, Version 2.0 (the "License");
3 you may not use this file except in compliance with the License.
4 You may obtain a copy of the License at
5       http://www.apache.org/licenses/LICENSE-2.0
6 Unless required by applicable law or agreed to in writing, software
7 distributed under the License is distributed on an "AS IS" BASIS,
8 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 See the License for the specific language governing permissions and
10 limitations under the License.
11 */
12 #include "apr.h"
13 #include "apr_file_io.h"
14 #include "apr_poll.h"
15 #include "apr_portable.h"
16 #include "apr_proc_mutex.h"
17 #include "apr_signal.h"
18 #include "apr_strings.h"
19 #include "apr_thread_mutex.h"
20 #include "apr_thread_proc.h"
21 
22 #define APR_WANT_STRFUNC
23 #include "apr_file_io.h"
24 #include "apr_fnmatch.h"
25 #include "apr_want.h"
26 
27 #include "apr_poll.h"
28 #include "apr_want.h"
29 
30 #include "ap_config.h"
31 #include "ap_expr.h"
32 #include "ap_listen.h"
33 #include "ap_provider.h"
34 #include "ap_regex.h"
35 
36 #include "ada_fuzz_header.h"
37 
38 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)39 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
40   // Initialize fuzzing garbage collector. We use this to easily
41   // get data types seeded with random input from the fuzzer.
42   af_gb_init();
43 
44   const uint8_t *data2 = data;
45   size_t size2 = size;
46 
47   char *new_str = af_gb_get_null_terminated(&data2, &size2);
48   char *new_dst = af_gb_get_null_terminated(&data2, &size2);
49   if (new_str != NULL && new_dst != NULL) {
50 
51     // Targets that do not require a pool
52     ap_cstr_casecmp(new_str, new_str);
53     ap_getparents(new_str);
54     ap_unescape_url(new_str);
55     ap_unescape_urlencoded(new_str);
56     ap_strcmp_match(new_str, new_dst);
57 
58     char *ns3 = af_gb_get_null_terminated(&data2, &size2);
59     if (ns3 != NULL) {
60       ap_no2slash(ns3);
61     }
62 
63     char *ns11 = af_gb_get_null_terminated(&data2, &size2);
64     if (ns11) {
65       char *ns10 = malloc(strlen(ns11)*3+1); // big enough for worst-case URL-escaped input.
66       ap_escape_path_segment_buffer(ns10, ns11);
67       free(ns10);
68     }
69 
70     // Pool initialisation
71     if (apr_pool_initialize() == APR_SUCCESS) {
72       apr_pool_t *pool = NULL;
73       apr_pool_create(&pool, NULL);
74 
75       // Targets that require a pool
76       ns3 = af_gb_get_null_terminated(&data2, &size2);
77       if (ns3 != NULL) {
78         ap_make_dirstr_parent(pool, ns3);
79       }
80 
81       ap_field_noparam(pool, new_str);
82 
83       ap_escape_shell_cmd(pool, new_str);
84       ap_os_escape_path(pool, new_str, 0);
85       ap_escape_html2(pool, new_str, 0);
86       ap_escape_logitem(pool, new_str);
87 
88       // This line causes some issues if something bad is allocated
89       ap_escape_quotes(pool, new_str);
90 
91       if (size > 2) {
92         ap_cstr_casecmpn(new_str, new_str + 2, size - 2);
93       }
94 
95       char *d = malloc(size * 2);
96       ap_escape_errorlog_item(d, new_str, size * 2);
97       free(d);
98 
99       // base64
100       char *decoded = NULL;
101       decoded = ap_pbase64decode(pool, new_str);
102       ap_pbase64encode(pool, new_str);
103 
104       char *ns12 = af_gb_get_null_terminated(&data2, &size2);
105       if (ns12 != NULL) {
106         char *d;
107         apr_size_t dlen;
108         ap_pbase64decode_strict(pool, ns12, &d, &dlen);
109       }
110 
111       char *tmp_s = new_str;
112       ap_getword_conf2(pool, &tmp_s);
113 
114       // str functions
115       ap_strcasecmp_match(tmp_s, new_dst);
116       ap_strcasestr(tmp_s, new_dst);
117 
118       // List functions
119       tmp_s = new_str;
120       ap_get_list_item(pool, &tmp_s);
121       tmp_s = new_str;
122       ap_find_list_item(pool, &tmp_s, "kjahsdfkj");
123       ap_find_token(pool, tmp_s, "klsjdfk");
124       ap_find_last_token(pool, tmp_s, "sdadf");
125       ap_is_chunked(pool, tmp_s);
126 
127       apr_array_header_t *offers = NULL;
128       ap_parse_token_list_strict(pool, new_str, &offers, 0);
129 
130       char *tmp_null = NULL;
131       ap_pstr2_alnum(pool, new_str, &tmp_null);
132 
133       // Word functions
134       tmp_s = new_str;
135       ap_getword(pool, &tmp_s, 0);
136 
137       tmp_s = new_str;
138       ap_getword_white_nc(pool, &tmp_s);
139 
140       tmp_s = new_str;
141       ap_get_token(pool, &tmp_s, 1);
142 
143       tmp_s = new_str;
144       ap_escape_urlencoded(pool, tmp_s);
145 
146       apr_interval_time_t timeout;
147       ap_timeout_parameter_parse(new_str, &timeout, "ms");
148 
149       tmp_s = new_str;
150       ap_content_type_tolower(tmp_s);
151 
152 
153 			char filename[256];
154 			sprintf(filename, "/tmp/libfuzzer.%d", getpid());
155 			FILE *fp = fopen(filename, "wb");
156 			fwrite(data, size, 1, fp);
157 			fclose(fp);
158 
159 			// Fuzzer logic here
160 			ap_configfile_t *cfg;
161 			ap_pcfg_openfile(&cfg, pool, filename);
162       char tmp_line[100];
163       if ((af_get_short(&data2, &size2) % 2) == 0) {
164         ap_cfg_getline(tmp_line, 100, cfg);
165       }
166       else {
167         cfg->getstr = NULL;
168         ap_cfg_getline(tmp_line, 100, cfg);
169       }
170 			// Fuzzer logic end
171 
172 			unlink(filename);
173 
174       // Cleanup
175       apr_pool_terminate();
176     }
177   }
178 
179   // Cleanup all of the memory allocated by the fuzz headers.
180   af_gb_cleanup();
181   return 0;
182 }
183