aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2019-01-27 18:38:46 +0100
committerPeter Wu <peter@lekensteyn.nl>2019-01-28 11:09:35 +0000
commiteec3ce3bb211be10f1804423818f2689b0fa517e (patch)
tree2f5844f6d78b4cc5a55b7a995b5b4726abba85d7
parente8e60df4ce1aeed350c962c329c1eef4c09ce669 (diff)
dfilter: fix memory leaks on dfilter compile errors involving a set
If a display filter contains a set for the set membership operator and an error occurs, then gen_relation_in() (called via dfw_gencode() will not take ownership of the set and a memory leak occurs. Fix this by implementing a free callback for STTYPE_SET nodes which frees unclaimed data. Add tests to verify the effectiveness, ASAN no longer complains after this fix. Bug: 15442 Change-Id: If37cf047660464b2d0304748034d0bc22111e5d6 Reviewed-on: https://code.wireshark.org/review/31758 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu <peter@lekensteyn.nl>
-rw-r--r--epan/dfilter/gencode.c7
-rw-r--r--epan/dfilter/sttype-set.c11
-rw-r--r--test/suite_dfilter/group_membership.py10
3 files changed, 23 insertions, 5 deletions
diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c
index a7122e99da..c6736296e4 100644
--- a/epan/dfilter/gencode.c
+++ b/epan/dfilter/gencode.c
@@ -297,14 +297,14 @@ gen_relation_in(dfwork_t *dfw, stnode_t *st_arg1, stnode_t *st_arg2)
dfvm_value_t *jmp1 = NULL, *jmp2 = NULL, *jmp3 = NULL;
int reg1 = -1, reg2 = -1, reg3 = -1;
stnode_t *node1, *node2;
- GSList *nodelist;
+ GSList *nodelist_head, *nodelist;
GSList *jumplist = NULL;
/* Create code for the LHS of the relation */
reg1 = gen_entity(dfw, st_arg1, &jmp1);
/* Create code for the set on the RHS of the relation */
- nodelist = (GSList*)stnode_data(st_arg2);
+ nodelist_head = nodelist = (GSList*)stnode_steal_data(st_arg2);
while (nodelist) {
node1 = (stnode_t*)nodelist->data;
nodelist = g_slist_next(nodelist);
@@ -365,8 +365,7 @@ gen_relation_in(dfwork_t *dfw, stnode_t *st_arg1, stnode_t *st_arg2)
/* Clean up */
g_slist_free(jumplist);
- nodelist = (GSList*)stnode_data(st_arg2);
- set_nodelist_free(nodelist);
+ set_nodelist_free(nodelist_head);
}
/* Parse an entity, returning the reg that it gets put into.
diff --git a/epan/dfilter/sttype-set.c b/epan/dfilter/sttype-set.c
index 6705c42f13..34c1852002 100644
--- a/epan/dfilter/sttype-set.c
+++ b/epan/dfilter/sttype-set.c
@@ -31,6 +31,15 @@ set_nodelist_free(GSList *params)
g_slist_free_full(params, slist_stnode_free);
}
+static void
+sttype_set_free(gpointer value)
+{
+ /* If the data was not claimed with stnode_steal_data(), free it. */
+ if (value) {
+ set_nodelist_free((GSList *)value);
+ }
+}
+
void
sttype_set_replace_element(stnode_t *node, stnode_t *oldnode, stnode_t *newnode)
{
@@ -55,7 +64,7 @@ sttype_register_set(void)
STTYPE_SET,
"SET",
NULL,
- NULL,
+ sttype_set_free,
NULL
};
diff --git a/test/suite_dfilter/group_membership.py b/test/suite_dfilter/group_membership.py
index 1c5b267b59..43f285a7f0 100644
--- a/test/suite_dfilter/group_membership.py
+++ b/test/suite_dfilter/group_membership.py
@@ -48,3 +48,13 @@ class case_membership(unittest.TestCase):
# expression should be parsed as "0.1 .. .7"
dfilter = 'frame.time_delta in {0.1...7}'
checkDFilterCount(dfilter, 0)
+
+ def test_membership_10_bad_lhs_number(self, checkDFilterFail):
+ dfilter = '123 in {ip}'
+ error = 'Only a field may be tested for membership in a set.'
+ checkDFilterFail(dfilter, error)
+
+ def test_membership_11_bad_rhs_string(self, checkDFilterFail):
+ dfilter = 'frame.number in {1 "foo"}'
+ error = '"foo" cannot be converted to Unsigned integer, 4 bytes.'
+ checkDFilterFail(dfilter, error)