prefs: fix range preferences-related crash after switching profiles
The HTTP dissector could crash (use-after-free) after switching profiles. In reinit_http, it would assign the return value from prefs_get_range_value to a global variable which is consulted during dissection. This value is invalidated while switching profiles (via the "prefs_reset" function), but is not reinitialized (because the reinit_http function was not called). A similar issue exists in the Kafka, UAUDP, VNC, TFTP, Gopher and TDS dissectors. To reproduce using a capture from the SampleCaptures wiki, start "wireshark -r vnc-sample.pcap -ovnc.tcp.port:1" and switch profiles. For the HTTP crash, load any HTTP pcap and switch profiles. Change-Id: I8725615504a8a82ae46255625a41e2188c07320a Fixes: v2.3.0rc0-2097-g21a3b8cc71 ("Internalize struct preference") Reviewed-on: https://code.wireshark.org/review/29030 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
5e2e9de930
commit
0be9d149d0
28
epan/prefs.c
28
epan/prefs.c
|
@ -4216,26 +4216,36 @@ reset_pref(pref_t *pref)
|
|||
}
|
||||
|
||||
static void
|
||||
reset_pref_cb(gpointer data, gpointer user_data _U_)
|
||||
reset_pref_cb(gpointer data, gpointer user_data)
|
||||
{
|
||||
pref_t *pref = (pref_t *) data;
|
||||
module_t *module = (module_t *)user_data;
|
||||
|
||||
if (pref && (pref->type == PREF_RANGE || pref->type == PREF_DECODE_AS_RANGE)) {
|
||||
/*
|
||||
* Some dissectors expect the range (returned via prefs_get_range_value)
|
||||
* to remain valid if it has not changed. If it did change, then we
|
||||
* should set "prefs_changed_flags" to ensure that the preference apply
|
||||
* callback is invoked. That callback will notify dissectors that it
|
||||
* should no longer assume the range to be valid.
|
||||
*/
|
||||
if (ranges_are_equal(*pref->varp.range, pref->default_val.range)) {
|
||||
/* Optimization: do not invoke apply callback if nothing changed. */
|
||||
return;
|
||||
}
|
||||
module->prefs_changed_flags |= prefs_get_effect_flags(pref);
|
||||
}
|
||||
reset_pref(pref);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
module_t *module;
|
||||
} reset_pref_arg_t;
|
||||
|
||||
/*
|
||||
* Reset all preferences for a module.
|
||||
*/
|
||||
static gboolean
|
||||
reset_module_prefs(const void *key _U_, void *value, void *data _U_)
|
||||
{
|
||||
reset_pref_arg_t arg;
|
||||
|
||||
arg.module = (module_t *)value;
|
||||
g_list_foreach(arg.module->prefs, reset_pref_cb, &arg);
|
||||
module_t *module = (module_t *)value;
|
||||
g_list_foreach(module->prefs, reset_pref_cb, module);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue