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 /epan/dfilter | |
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>
Diffstat (limited to 'epan/dfilter')
-rw-r--r-- | epan/dfilter/gencode.c | 7 | ||||
-rw-r--r-- | epan/dfilter/sttype-set.c | 11 |
2 files changed, 13 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 }; |