Catch REPORT_DISSECTOR_BUG() calls in dissector registration routines.

Have epan_init() return a success/failure Boolean indication.  Catch
exceptions when calling the dissector registration routines and, if we
get one, report the error and return a failure indication.

If epan_init() fails, quit, but first make sure the reported error is
displayed.

Change-Id: I0300cbb1f66a5644f857a205235124909d684c50
Reviewed-on: https://code.wireshark.org/review/11340
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2015-10-27 17:41:23 -07:00
parent 2831d391ef
commit c7e42be2e5
8 changed files with 73 additions and 26 deletions

View File

@ -95,8 +95,9 @@ main(int argc, char **argv)
"-g" flag, as the "-g" flag dumps a list of fields registered
by the dissectors, and we must do it before we read the preferences,
in case any dissectors register preferences. */
epan_init(register_all_protocols, register_all_protocol_handoffs,
NULL, NULL);
if (!epan_init(register_all_protocols, register_all_protocol_handoffs,
NULL, NULL))
return 2;
/* set the c-language locale to the native environment. */
setlocale(LC_ALL, "");

View File

@ -21,6 +21,8 @@
#include "config.h"
#include <stdarg.h>
#ifdef HAVE_LIBGCRYPT
#include <wsutil/wsgcrypt.h>
#endif /* HAVE_LIBGCRYPT */
@ -31,6 +33,10 @@
#include <glib.h>
#include <wsutil/report_err.h>
#include <epan/exceptions.h>
#include "epan-int.h"
#include "epan.h"
#include "dfilter/dfilter.h"
@ -85,12 +91,14 @@ epan_register_plugin_types(void)
#endif
}
void
gboolean
epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data),
void (*register_all_handoffs_func)(register_cb cb, gpointer client_data),
register_cb cb,
gpointer client_data)
{
gboolean status = TRUE;
/* initialize memory allocation subsystem */
wmem_init();
@ -110,20 +118,42 @@ epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_da
#ifdef HAVE_LIBGNUTLS
gnutls_global_init();
#endif
tap_init();
prefs_init();
expert_init();
packet_init();
proto_init(register_all_protocols_func, register_all_handoffs_func,
cb, client_data);
packet_cache_proto_handles();
dfilter_init();
final_registration_all_protocols();
print_cache_field_handles();
expert_packet_init();
TRY {
tap_init();
prefs_init();
expert_init();
packet_init();
proto_init(register_all_protocols_func, register_all_handoffs_func,
cb, client_data);
packet_cache_proto_handles();
dfilter_init();
final_registration_all_protocols();
print_cache_field_handles();
expert_packet_init();
#ifdef HAVE_LUA
wslua_init(cb, client_data);
wslua_init(cb, client_data);
#endif
}
CATCH(DissectorError) {
/*
* This is probably a dissector, or something it calls,
* calling REPORT_DISSECTOR_ERROR() in a registration
* routine or something else outside the normal dissection
* code path.
*/
const char *exception_message = GET_MESSAGE;
static const char dissector_error_nomsg[] =
"Dissector writer didn't bother saying what the error was";
report_failure("Dissector bug: %s",
exception_message == NULL ?
dissector_error_nomsg : exception_message);
if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
abort();
status = FALSE;
}
ENDTRY;
return status;
}
void

View File

@ -89,11 +89,17 @@ Ref2 for further edits - delete when done
*/
WS_DLL_PUBLIC void epan_register_plugin_types(void);
/** init the whole epan module, this is used to be called only once in a program */
/**
* Init the whole epan module.
*
* Must be called only once in a program.
*
* Returns TRUE on success, FALSE on failure.
*/
WS_DLL_PUBLIC
void epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data),
void (*register_all_handoffs_func)(register_cb cb, gpointer client_data),
register_cb cb, void *client_data);
gboolean epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data),
void (*register_all_handoffs_func)(register_cb cb, gpointer client_data),
register_cb cb, void *client_data);
/** cleanup the whole epan module, this is used to be called only once in a program */
WS_DLL_PUBLIC

View File

@ -529,7 +529,9 @@ DIAG_ON(cast-qual)
"-G" flag, as the "-G" flag dumps information registered by the
dissectors, and we must do it before we read the preferences, in
case any dissectors register preferences. */
epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL);
if (!epan_init(register_all_protocols, register_all_protocol_handoffs,
NULL, NULL))
return 2;
prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
&pf_open_errno, &pf_read_errno, &pf_path);

View File

@ -968,7 +968,9 @@ DIAG_ON(cast-qual)
"-G" flag, as the "-G" flag dumps information registered by the
dissectors, and we must do it before we read the preferences, in
case any dissectors register preferences. */
epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL);
if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
NULL))
return 2;
/* Register all tap listeners; we do this before we parse the arguments,
as the "-z" argument can specify a registered tap. */

View File

@ -1225,7 +1225,9 @@ DIAG_ON(cast-qual)
"-G" flag, as the "-G" flag dumps information registered by the
dissectors, and we must do it before we read the preferences, in
case any dissectors register preferences. */
epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL);
if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
NULL))
return 2;
/* Register all tap listeners; we do this before we parse the arguments,
as the "-z" argument can specify a registered tap. */

View File

@ -2513,8 +2513,9 @@ DIAG_ON(cast-qual)
"-G" flag, as the "-G" flag dumps information registered by the
dissectors, and we must do it before we read the preferences, in
case any dissectors register preferences. */
epan_init(register_all_protocols,register_all_protocol_handoffs,
splash_update, (gpointer) splash_win);
if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
splash_update, (gpointer) splash_win))
return 2;
splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);

View File

@ -836,8 +836,11 @@ DIAG_ON(cast-qual)
"-G" flag, as the "-G" flag dumps information registered by the
dissectors, and we must do it before we read the preferences, in
case any dissectors register preferences. */
epan_init(register_all_protocols,register_all_protocol_handoffs,
splash_update, NULL);
if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
splash_update, NULL)) {
SimpleDialog::displayQueuedMessages(main_w);
return 2;
}
splash_update(RA_LISTENERS, NULL, NULL);