3 * Fuzzer variant of Wireshark for oss-fuzz
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/epan-int.h>
34 #include <epan/epan.h>
36 #include <wsutil/cmdarg_err.h>
37 #include <wsutil/crash_info.h>
38 #include <wsutil/filesystem.h>
39 #include <wsutil/privileges.h>
40 #include <wsutil/report_message.h>
41 #include <version_info.h>
43 #include <wiretap/wtap.h>
45 #include <epan/color_filters.h>
46 #include <epan/timestamp.h>
47 #include <epan/prefs.h>
48 #include <epan/column.h>
49 #include <epan/print.h>
50 #include <epan/epan_dissect.h>
53 #include <wsutil/plugins.h>
56 #define EPAN_INIT_FAIL 2
58 static column_info fuzz_cinfo;
59 static epan_t *fuzz_epan;
60 static epan_dissect_t *fuzz_edt;
63 * General errors and warnings are reported with an console message
67 failure_warning_message(const char *msg_format, va_list ap)
69 fprintf(stderr, "oss-fuzzshark: ");
70 vfprintf(stderr, msg_format, ap);
71 fprintf(stderr, "\n");
75 * Open/create errors are reported with an console message in oss-fuzzshark.
78 open_failure_message(const char *filename, int err, gboolean for_writing)
80 fprintf(stderr, "oss-fuzzshark: ");
81 fprintf(stderr, file_open_error_message(err, for_writing), filename);
82 fprintf(stderr, "\n");
86 * Read errors are reported with an console message in oss-fuzzshark.
89 read_failure_message(const char *filename, int err)
91 cmdarg_err("An error occurred while reading from the file \"%s\": %s.", filename, g_strerror(err));
95 * Write errors are reported with an console message in oss-fuzzshark.
98 write_failure_message(const char *filename, int err)
100 cmdarg_err("An error occurred while writing to the file \"%s\": %s.", filename, g_strerror(err));
104 * Report additional information for an error in command-line arguments.
107 failure_message_cont(const char *msg_format, va_list ap)
109 vfprintf(stderr, msg_format, ap);
110 fprintf(stderr, "\n");
113 static const nstime_t *
114 fuzzshark_get_frame_ts(struct packet_provider *prov _U_, guint32 frame_num _U_)
116 static nstime_t empty;
122 fuzzshark_epan_new(void)
124 epan_t *epan = epan_new(NULL);
126 epan->get_frame_ts = fuzzshark_get_frame_ts;
127 epan->get_interface_name = NULL;
128 epan->get_interface_description = NULL;
129 epan->get_user_comment = NULL;
134 static dissector_handle_t
135 get_dissector_handle(const char *table, const char *target)
137 dissector_handle_t fuzz_handle = NULL;
139 if (table != NULL && target != NULL)
141 /* search for handle, cannot use dissector_table_get_dissector_handle() cause it's using short-name, and I already used filter name in samples ;/ */
142 GSList *handle_list = dissector_table_get_dissector_handles(find_dissector_table(table));
145 dissector_handle_t handle = (dissector_handle_t) handle_list->data;
146 const char *handle_filter_name = proto_get_protocol_filter_name(dissector_handle_get_protocol_index(handle));
148 if (!strcmp(handle_filter_name, target))
149 fuzz_handle = handle;
150 handle_list = handle_list->next;
153 else if (target != NULL)
155 fuzz_handle = find_dissector(target);
162 fuzz_init(int argc _U_, char **argv)
164 GString *comp_info_str;
165 GString *runtime_info_str;
166 char *init_progfile_dir_error;
168 char *err_msg = NULL;
170 int ret = EXIT_SUCCESS;
172 dissector_handle_t fuzz_handle = NULL;
174 g_setenv("WIRESHARK_DEBUG_WMEM_OVERRIDE", "simple", 0);
175 g_setenv("G_SLICE", "always-malloc", 0);
177 cmdarg_err_init(failure_warning_message, failure_message_cont);
180 * Get credential information for later use, and drop privileges
181 * before doing anything else.
182 * Let the user know if anything happened.
184 init_process_policies();
185 #if 0 /* disable setresgid(), it fails with -EINVAL https://github.com/google/oss-fuzz/pull/532#issuecomment-294515463 */
186 relinquish_special_privs_perm();
190 * Attempt to get the pathname of the executable file.
192 init_progfile_dir_error = init_progfile_dir(argv[0], fuzz_init);
193 if (init_progfile_dir_error != NULL)
194 fprintf(stderr, "fuzzshark: Can't get pathname of oss-fuzzshark program: %s.\n", init_progfile_dir_error);
196 /* Get the compile-time version information string */
197 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
199 /* Get the run-time version information string */
200 runtime_info_str = get_runtime_version_info(epan_get_runtime_version_info);
202 /* Add it to the information to be reported on a crash. */
203 ws_add_crash_info("OSS Fuzzshark (Wireshark) %s\n"
208 get_ws_vcs_version_info(),
210 runtime_info_str->str);
211 g_string_free(comp_info_str, TRUE);
212 g_string_free(runtime_info_str, TRUE);
214 init_report_message(failure_warning_message, failure_warning_message,
215 open_failure_message, read_failure_message, write_failure_message);
217 timestamp_set_type(TS_RELATIVE);
218 timestamp_set_precision(TS_PREC_AUTO);
219 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
224 /* Register all the plugin types we have. */
225 epan_register_plugin_types(); /* Types known to libwireshark */
227 /* Scan for plugins. This does *not* call their registration routines; that's done later. */
228 scan_plugins(REPORT_LOAD_FAILURE);
230 /* Register all libwiretap plugin modules. */
231 register_all_wiretap_modules();
234 /* Register all dissectors; we must do this before checking for the
235 "-G" flag, as the "-G" flag dumps information registered by the
236 dissectors, and we must do it before we read the preferences, in
237 case any dissectors register preferences. */
238 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL))
240 ret = EPAN_INIT_FAIL;
244 /* Load libwireshark settings from the current profile. */
245 prefs_p = epan_load_settings();
247 if (!color_filters_init(&err_msg, NULL))
249 fprintf(stderr, "%s\n", err_msg);
253 /* Notify all registered modules that have had any of their preferences
254 changed either from one of the preferences file or from the command
255 line that their preferences have changed. */
258 /* Build the column format array */
259 build_column_format_array(&fuzz_cinfo, prefs_p->num_cols, TRUE);
261 #if defined(FUZZ_DISSECTOR_TABLE) && defined(FUZZ_DISSECTOR_TARGET)
263 fprintf(stderr, "oss-fuzzshark: configured for dissector: %s in table: %s\n", FUZZ_DISSECTOR_TARGET, FUZZ_DISSECTOR_TABLE);
264 fuzz_handle = get_dissector_handle(FUZZ_DISSECTOR_TABLE, FUZZ_DISSECTOR_TARGET);
266 #elif defined(FUZZ_DISSECTOR_TARGET)
268 fprintf(stderr, "oss-fuzzshark: configured for dissector: %s\n", FUZZ_DISSECTOR_TARGET);
269 fuzz_handle = get_dissector_handle(FUZZ_DISSECTOR_TARGET);
273 fprintf(stderr, "oss-fuzzshark: target not configured. Using env\n");
274 fuzz_handle = get_dissector_handle(getenv("FUZZSHARK_TABLE"), getenv("FUZZSHARK_TARGET"));
278 g_assert(fuzz_handle != NULL);
279 register_postdissector(fuzz_handle);
282 fuzz_epan = fuzzshark_epan_new();
283 fuzz_edt = epan_dissect_new(fuzz_epan, TRUE, FALSE);
297 LLVMFuzzerTestOneInput(guint8 *buf, size_t real_len)
299 static guint32 framenum = 0;
300 epan_dissect_t *edt = fuzz_edt;
302 guint32 len = (guint32) real_len;
304 struct wtap_pkthdr whdr;
307 memset(&whdr, 0, sizeof(whdr));
309 whdr.rec_type = REC_TYPE_PACKET;
313 /* whdr.pkt_encap = WTAP_ENCAP_ETHERNET; */
314 whdr.pkt_encap = G_MAXINT16;
315 whdr.presence_flags = WTAP_HAS_TS | WTAP_HAS_CAP_LEN; /* most common flags... */
317 frame_data_init(&fdlocal, ++framenum, &whdr, /* offset */ 0, /* cum_bytes */ 0);
318 /* frame_data_set_before_dissect() not needed */
319 epan_dissect_run(edt, WTAP_FILE_TYPE_SUBTYPE_UNKNOWN, &whdr, tvb_new_real_data(buf, len, len), &fdlocal, NULL /* &fuzz_cinfo */);
320 frame_data_destroy(&fdlocal);
322 epan_dissect_reset(edt);
327 # error "Missing fuzz target."
331 LLVMFuzzerInitialize(int *argc, char ***argv)
335 ret = fuzz_init(*argc, *argv);
343 * Editor modelines - http://www.wireshark.org/tools/modelines.html
348 * indent-tabs-mode: t
351 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
352 * :indentSize=8:tabSize=8:noTabs=false: