diff options
author | Peter Wu <peter@lekensteyn.nl> | 2019-01-27 18:38:46 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2019-01-28 11:09:35 +0000 |
commit | eec3ce3bb211be10f1804423818f2689b0fa517e (patch) | |
tree | 2f5844f6d78b4cc5a55b7a995b5b4726abba85d7 | |
parent | e8e60df4ce1aeed350c962c329c1eef4c09ce669 (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.c | 7 | ||||
-rw-r--r-- | epan/dfilter/sttype-set.c | 11 | ||||
-rw-r--r-- | test/suite_dfilter/group_membership.py | 10 |
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) |