diff options
author | Peter Wu <peter@lekensteyn.nl> | 2016-08-28 22:19:29 +0200 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2016-08-29 22:08:50 +0000 |
commit | a04b6fcb3db901734ed948134c973996786be8b7 (patch) | |
tree | 26e574116c07f1301634feefe9078adf100ffbb7 | |
parent | 14312835c63a3e2ec9d311ed1ffee5285141f4f9 (diff) |
diameter: fix 400kb leaked memory on exit
Before:
SUMMARY: AddressSanitizer: 399684 byte(s) leaked in 17208 allocation(s).
After addressing to-do by calling ddict_free:
SUMMARY: AddressSanitizer: 3024 byte(s) leaked in 256 allocation(s).
After fixing all remaining leaks cases in the flex file for diameter:
SUMMARY: AddressSanitizer: 735 byte(s) leaked in 58 allocation(s).
Not bad huh :-)
Ping-Bug: 12790
Change-Id: I0c730ad77ae15c69390bc6cf0a3a985395a64771
Reviewed-on: https://code.wireshark.org/review/17364
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Reviewed-by: Jeff Morriss <jeff.morriss.ws@gmail.com>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
-rw-r--r-- | epan/diam_dict.l | 35 | ||||
-rw-r--r-- | epan/dissectors/packet-diameter.c | 12 |
2 files changed, 38 insertions, 9 deletions
diff --git a/epan/diam_dict.l b/epan/diam_dict.l index 75a320a69f..0fbb3e697f 100644 --- a/epan/diam_dict.l +++ b/epan/diam_dict.l @@ -749,8 +749,8 @@ ddict_scan(const char* system_directory, const char* filename, int dbg) state.dict = g_new(ddict_t,1); state.dict->applications = NULL; - state.dict->cmds = NULL; state.dict->vendors = NULL; + state.dict->cmds = NULL; state.dict->typedefns = NULL; state.dict->avps = NULL; state.dict->xmlpis = NULL; @@ -796,6 +796,7 @@ ddict_scan(const char* system_directory, const char* filename, int dbg) } if (DiamDict_lex_init(&scanner) != 0) { + /* Note: cannot be reached since memory allocation failure terminates early */ D(("Can't initialize scanner: %s\n", g_strerror(errno))); fclose(in); g_free(state.dict); @@ -827,6 +828,7 @@ ddict_scan(const char* system_directory, const char* filename, int dbg) state.current_yyinput = string_input; if (DiamDict_lex_init(&scanner) != 0) { + /* Note: cannot be reached since memory allocation failure terminates early */ D(("Can't initialize scanner: %s\n", g_strerror(errno))); g_free(state.dict); g_free(state.strbuf); @@ -840,6 +842,16 @@ ddict_scan(const char* system_directory, const char* filename, int dbg) DiamDict_lex(scanner); DiamDict_lex_destroy(scanner); + { + entity_t *e, *en; + + for (e = state.ents; e; e = en) { + en = e->next; + g_free(e->name); + g_free(e->file); + g_free(e); + } + } g_free(state.strbuf); return state.dict; @@ -853,8 +865,9 @@ ddict_free(ddict_t* d) ddict_cmd_t *c, *cn; ddict_typedefn_t *t, *tn; ddict_avp_t *a, *an; + ddict_xmlpi_t *x, *xn; -#define FREE_NAMEANDOBJ(n) do { if(n->name) g_free(n->name); g_free(n); } while(0) +#define FREE_NAMEANDOBJ(n) do { g_free(n->name); g_free(n); } while(0) for (p = d->applications; p; p = pn ) { pn = p->next; @@ -863,18 +876,19 @@ ddict_free(ddict_t* d) for (v = d->vendors; v; v = vn) { vn = v->next; - if (v->desc) g_free(v->desc); + g_free(v->desc); FREE_NAMEANDOBJ(v); } for (c = d->cmds; c; c = cn ) { cn = c->next; + g_free(c->vendor); FREE_NAMEANDOBJ(c); } for (t = d->typedefns; t; t = tn) { tn = t->next; - if (t->parent) g_free(t->parent); + g_free(t->parent); FREE_NAMEANDOBJ(t); } @@ -893,12 +907,19 @@ ddict_free(ddict_t* d) FREE_NAMEANDOBJ(e); } - if (a->vendor) g_free(a->vendor); - if (a->type) g_free(a->type); - if (a->description) g_free(a->description); + g_free(a->vendor); + g_free(a->type); + g_free(a->description); FREE_NAMEANDOBJ(a); } + for (x = d->xmlpis; x; x = xn) { + xn = x->next; + g_free(x->key); + g_free(x->value); + FREE_NAMEANDOBJ(x); + } + g_free(d); } diff --git a/epan/dissectors/packet-diameter.c b/epan/dissectors/packet-diameter.c index ab7bbd3093..ad021cbe75 100644 --- a/epan/dissectors/packet-diameter.c +++ b/epan/dissectors/packet-diameter.c @@ -680,7 +680,7 @@ dissect_diameter_avp(diam_ctx_t *c, tvbuff_t *tvb, int offset, diam_sub_dis_t *d wmem_array_sort(vendor->vs_avps, compare_avps); vendor->vs_avps_ext = value_string_ext_new(VND_AVP_VS(vendor), VND_AVP_VS_LEN(vendor)+1, - g_strdup_printf("diameter_vendor_%s", + wmem_strdup_printf(wmem_epan_scope(), "diameter_vendor_%s", val_to_str_ext_const(vendorid, &sminmpec_values_ext, "Unknown"))); @@ -1838,6 +1838,14 @@ strcase_equal(gconstpointer ka, gconstpointer kb) return g_ascii_strcasecmp(a,b) == 0; } +static gboolean +ddict_cleanup_cb(wmem_allocator_t* allocator _U_, wmem_cb_event_t event _U_, void *user_data) +{ + ddict_t *d = (ddict_t *)user_data; + ddict_free(d); + return FALSE; +} + /* Note: Dynamic "value string arrays" (e.g., vs_cmds, vs_avps, ...) are constructed using */ /* "zero-terminated" GArrays so that they will have the same form as standard */ @@ -1896,7 +1904,6 @@ dictionary_load(void) /* load the dictionary */ dir = wmem_strdup_printf(NULL, "%s" G_DIR_SEPARATOR_S "diameter" G_DIR_SEPARATOR_S, get_datafile_dir()); - /* XXX We don't call ddict_free anywhere. */ d = ddict_scan(dir,"dictionary.xml",do_debug_parser); wmem_free(NULL, dir); if (d == NULL) { @@ -1904,6 +1911,7 @@ dictionary_load(void) g_array_free(vnd_shrt_arr, TRUE); return 0; } + wmem_register_callback(wmem_epan_scope(), ddict_cleanup_cb, d); if (do_dump_dict) ddict_print(stdout, d); |