aboutsummaryrefslogtreecommitdiffstats
path: root/epan/prefs.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-08-08 20:00:48 +0200
committerAnders Broman <a.broman58@gmail.com>2018-08-09 04:52:53 +0000
commit0be9d149d0feaac8697b993926ffa87e156d7fa4 (patch)
treefb5b8710e4373ed3085d2324e0b76abb0e7f2f6b /epan/prefs.c
parent5e2e9de9302f43de899d6d450ed75a17a6d73035 (diff)
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>
Diffstat (limited to 'epan/prefs.c')
-rw-r--r--epan/prefs.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/epan/prefs.c b/epan/prefs.c
index bce63b44d3..adfc91685b 100644
--- a/epan/prefs.c
+++ b/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;
}