summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2017-02-26 22:18:11 -0500
committerMichael Mann <mmann78@netscape.net>2017-02-27 12:53:14 +0000
commitd4cf57100ce10930551b1985eac77e78bae6361d (patch)
tree0d65e9ad9e462af623623ec201e73f6aaf9412ef
parent220772dc19ef8b9c20a919375b47390a794c4e42 (diff)
downloadwireshark-d4cf57100ce10930551b1985eac77e78bae6361d.tar.gz
Free radius dissector memory on shutdown
Change-Id: I19eef65e8144d7cb6d5c9eea454581a532420c75 Reviewed-on: https://code.wireshark.org/review/20292 Reviewed-by: Dario Lombardo <lomato@gmail.com> Petri-Dish: Dario Lombardo <lomato@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--epan/dissectors/packet-radius.c49
-rw-r--r--epan/dissectors/packet-radius.h5
-rw-r--r--epan/radius_dict.l2
3 files changed, 48 insertions, 8 deletions
diff --git a/epan/dissectors/packet-radius.c b/epan/dissectors/packet-radius.c
index 4c80452949..c57aeae894 100644
--- a/epan/dissectors/packet-radius.c
+++ b/epan/dissectors/packet-radius.c
@@ -2137,6 +2137,29 @@ dissect_radius(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
return tvb_captured_length(tvb);
}
+void
+free_radius_attr_info(gpointer data)
+{
+ radius_attr_info_t* attr = (radius_attr_info_t*)data;
+
+ g_free(attr->name);
+ if (attr->tlvs_by_id)
+ g_hash_table_destroy(attr->tlvs_by_id);
+
+ g_free(attr);
+}
+
+static void
+free_radius_vendor_info(gpointer data)
+{
+ radius_vendor_info_t* vendor = (radius_vendor_info_t*)data;
+
+ g_free(vendor->name);
+ if (vendor->attrs_by_id)
+ g_hash_table_destroy(vendor->attrs_by_id);
+
+ g_free(vendor);
+}
static void
register_attrs(gpointer k _U_, gpointer v, gpointer p)
@@ -2313,7 +2336,7 @@ radius_register_avp_dissector(guint32 vendor_id, guint32 attribute_id, radius_av
val_to_str_ext_const(vendor_id, &sminmpec_values_ext, "Unknown"),
vendor_id);
vendor->code = vendor_id;
- vendor->attrs_by_id = g_hash_table_new(g_direct_hash, g_direct_equal);
+ vendor->attrs_by_id = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_radius_attr_info);
vendor->ett = no_vendor.ett;
/* XXX: Default "standard" values: Should be parameters ? */
@@ -2370,6 +2393,19 @@ radius_init_protocol(void)
}
static void
+radius_shutdown(void)
+{
+ if (dict != NULL) {
+ g_hash_table_destroy(dict->attrs_by_id);
+ g_hash_table_destroy(dict->attrs_by_name);
+ g_hash_table_destroy(dict->vendors_by_id);
+ g_hash_table_destroy(dict->vendors_by_name);
+ g_hash_table_destroy(dict->tlvs_by_name);
+ g_free(dict);
+ }
+}
+
+static void
register_radius_fields(const char *unused _U_)
{
hf_register_info base_hf[] = {
@@ -2634,6 +2670,7 @@ proto_register_radius(void)
proto_radius = proto_register_protocol("RADIUS Protocol", "RADIUS", "radius");
radius_handle = register_dissector("radius", dissect_radius, proto_radius);
register_init_routine(&radius_init_protocol);
+ register_shutdown_routine(radius_shutdown);
radius_module = prefs_register_protocol(proto_radius, NULL);
prefs_register_string_preference(radius_module, "shared_secret", "Shared Secret",
"Shared secret used to decode User Passwords and validate Response Authenticators",
@@ -2650,11 +2687,13 @@ proto_register_radius(void)
proto_register_prefix("radius", register_radius_fields);
dict = (radius_dictionary_t *)g_malloc(sizeof(radius_dictionary_t));
- dict->attrs_by_id = g_hash_table_new(g_direct_hash, g_direct_equal);
- dict->attrs_by_name = g_hash_table_new(g_str_hash, g_str_equal);
- dict->vendors_by_id = g_hash_table_new(g_direct_hash, g_direct_equal);
+ dict->attrs_by_id = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_radius_attr_info);
+ dict->attrs_by_name = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free_radius_attr_info);
+ dict->vendors_by_id = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_radius_vendor_info);
+ /* Both vendors_by_id and vendors_by_name share the same data, so only worry about
+ cleaning up the data from one of them. The other will just clean up its own hash entries */
dict->vendors_by_name = g_hash_table_new(g_str_hash, g_str_equal);
- dict->tlvs_by_name = g_hash_table_new(g_str_hash, g_str_equal);
+ dict->tlvs_by_name = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free_radius_attr_info);
radius_calls = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), radius_call_hash, radius_call_equal);
diff --git a/epan/dissectors/packet-radius.h b/epan/dissectors/packet-radius.h
index c53bb87818..9393f73111 100644
--- a/epan/dissectors/packet-radius.h
+++ b/epan/dissectors/packet-radius.h
@@ -81,7 +81,7 @@
typedef struct _radius_vendor_info_t {
- const gchar *name;
+ gchar *name;
guint code;
GHashTable* attrs_by_id;
gint ett;
@@ -96,7 +96,7 @@ typedef void (radius_attr_dissector_t)(radius_attr_info_t*, proto_tree*, packet_
typedef const gchar* (radius_avp_dissector_t)(proto_tree*,tvbuff_t*, packet_info*);
struct _radius_attr_info_t {
- const gchar *name;
+ gchar *name;
guint code;
guint encrypt; /* 0 or value for "encrypt=" option */
gboolean tagged;
@@ -138,6 +138,7 @@ radius_attr_dissector_t radius_tlv;
extern void radius_register_avp_dissector(guint32 vendor_id, guint32 attribute_id, radius_avp_dissector_t dissector);
void dissect_attribute_value_pairs(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, guint length);
+extern void free_radius_attr_info(gpointer data);
/* from radius_dict.l */
gboolean radius_load_dictionary (radius_dictionary_t* dict, gchar* directory, const gchar* filename, gchar** err_str);
diff --git a/epan/radius_dict.l b/epan/radius_dict.l
index 6ca0008dfb..fd4771e0b6 100644
--- a/epan/radius_dict.l
+++ b/epan/radius_dict.l
@@ -403,7 +403,7 @@ static void add_vendor(Radius_scanner_state_t* state, const gchar* name, guint32
* by-name hash tables.
*/
v = g_new(radius_vendor_info_t,1);
- v->attrs_by_id = g_hash_table_new(g_direct_hash,g_direct_equal);
+ v->attrs_by_id = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_radius_attr_info);
v->code = id;
v->ett = -1;
v->name = g_strdup(name);