packet: duplicate short_name to fix UAF in wslua

The "short_name" parameter of heur_dissector_add is defined as const
(and was assumed to be a string literal). This was no longer the case
though since a change in Lua where "short_name" is a dynamically
allocated string.

This "simple" fix clones the memory for internal use to avoid a
heap-use-after-free when heur_dissector_delete tries to access
"short_name".

An alternative option is to make Proto_register_heuristic track the
memory, but since there are multiple possible heuristics lists for a
protocol, the Proto (struct _wslua_field_t) structure is not
appropriate. A possible working alternative is to store the string into
lua_heur_dissectors_table_ref (replacing the value (function) by a tuple
{function,short_name}).

Change-Id: I6c6b393f4d304dd847e864da6ad17b54c8cd80e2
Fixes: v2.3.0rc0-1474-g7f2a838922 ("lua: Allow proto:register_heuristic to be used on multiple list names")
Reviewed-on: https://code.wireshark.org/review/19365
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Franklin Mathieu <snaipe@diacritic.io>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
This commit is contained in:
Peter Wu 2016-12-21 02:23:35 +01:00
parent 92cd2c3ccb
commit a8b68205a4
2 changed files with 5 additions and 4 deletions

View File

@ -2457,18 +2457,18 @@ heur_dissector_add(const char *name, heur_dissector_t dissector, const char *dis
hdtbl_entry->dissector = dissector;
hdtbl_entry->protocol = find_protocol_by_id(proto);
hdtbl_entry->display_name = display_name;
hdtbl_entry->short_name = short_name;
hdtbl_entry->short_name = g_strdup(short_name);
hdtbl_entry->list_name = g_strdup(name);
hdtbl_entry->enabled = (enable == HEURISTIC_ENABLE);
/* do the table insertion */
g_hash_table_insert(heuristic_short_names, (gpointer)short_name, hdtbl_entry);
g_hash_table_insert(heuristic_short_names, (gpointer)hdtbl_entry->short_name, hdtbl_entry);
sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors,
(gpointer)hdtbl_entry);
/* XXX - could be optimized to pass hdtbl_entry directly */
proto_add_heuristic_dissector(hdtbl_entry->protocol, short_name);
proto_add_heuristic_dissector(hdtbl_entry->protocol, hdtbl_entry->short_name);
/* Add the dissector as a dependency
(some heuristic tables don't have protocol association, so there is
@ -2507,6 +2507,7 @@ heur_dissector_delete(const char *name, heur_dissector_t dissector, const int pr
heur_dtbl_entry_t *found_hdtbl_entry = (heur_dtbl_entry_t *)(found_entry->data);
g_free(found_hdtbl_entry->list_name);
g_hash_table_remove(heuristic_short_names, found_hdtbl_entry->short_name);
g_free(found_hdtbl_entry->short_name);
g_slice_free(heur_dtbl_entry_t, found_entry->data);
sub_dissectors->dissectors = g_slist_delete_link(sub_dissectors->dissectors,
found_entry);

View File

@ -410,7 +410,7 @@ typedef struct heur_dtbl_entry {
protocol_t *protocol; /* this entry's protocol */
gchar *list_name; /* the list name this entry is in the list of */
const gchar *display_name; /* the string used to present heuristic to user */
const gchar *short_name; /* string used for "internal" use to uniquely identify heuristic */
gchar *short_name; /* string used for "internal" use to uniquely identify heuristic */
gboolean enabled;
} heur_dtbl_entry_t;