Fix bug #8979: Comparing function call and a range in the filter crashes Wireshark

store whole node, don't assume it's always STTYPE_FIELD

svn path=/trunk/; revision=50949
This commit is contained in:
Jakub Zawadzki 2013-07-27 17:17:15 +00:00
parent 9e33a6bade
commit da170f1d04
4 changed files with 68 additions and 38 deletions

View File

@ -133,15 +133,17 @@ dfw_append_put_fvalue(dfwork_t *dfw, fvalue_t *fv)
/* returns register number */
static int
dfw_append_mk_range(dfwork_t *dfw, stnode_t *node)
dfw_append_mk_range(dfwork_t *dfw, stnode_t *node, dfvm_value_t **p_jmp)
{
int hf_reg, reg;
header_field_info *hfinfo;
stnode_t *entity;
dfvm_insn_t *insn;
dfvm_value_t *val;
hfinfo = sttype_range_hfinfo(node);
hf_reg = dfw_append_read_tree(dfw, hfinfo);
entity = sttype_range_entity(node);
/* XXX, check if p_jmp logic is OK */
hf_reg = gen_entity(dfw, entity, p_jmp);
insn = dfvm_insn_new(MK_RANGE);
@ -304,7 +306,7 @@ gen_entity(dfwork_t *dfw, stnode_t *st_arg, dfvm_value_t **p_jmp)
reg = dfw_append_put_fvalue(dfw, (fvalue_t *)stnode_data(st_arg));
}
else if (e_type == STTYPE_RANGE) {
reg = dfw_append_mk_range(dfw, st_arg);
reg = dfw_append_mk_range(dfw, st_arg, p_jmp);
}
else if (e_type == STTYPE_FUNCTION) {
reg = dfw_append_function(dfw, st_arg, p_jmp);

View File

@ -382,14 +382,14 @@ struct check_drange_sanity_args {
gboolean err;
};
/* Q: Where are sttype_range_drange() and sttype_range_hfinfo() defined?
/* Q: Where are sttype_range_drange() and sttype_range_entity() defined?
*
* A: Those functions are defined by macros in epan/dfilter/sttype-range.h
*
* The macro which creates them, STTYPE_ACCESSOR, is defined in
* epan/dfilter/syntax-tree.h.
*
* From http://www.ethereal.com/lists/ethereal-dev/200308/msg00070.html
* From http://www.wireshark.org/lists/ethereal-dev/200308/msg00070.html
*/
static void
@ -398,6 +398,7 @@ check_drange_node_sanity(gpointer data, gpointer user_data)
drange_node* drnode = (drange_node*)data;
struct check_drange_sanity_args *args = (struct check_drange_sanity_args*)user_data;
gint start_offset, end_offset, length;
stnode_t *entity;
header_field_info *hfinfo;
switch (drange_node_get_ending(drnode)) {
@ -408,12 +409,20 @@ check_drange_node_sanity(gpointer data, gpointer user_data)
if (!args->err) {
args->err = TRUE;
start_offset = drange_node_get_start_offset(drnode);
hfinfo = sttype_range_hfinfo(args->st);
dfilter_fail("Range %d:%d specified for \"%s\" isn't valid, "
"as length %d isn't positive",
start_offset, length,
hfinfo->abbrev,
length);
entity = sttype_range_entity(args->st);
if (entity && stnode_type_id(entity) == STTYPE_FIELD) {
hfinfo = stnode_data(entity);
dfilter_fail("Range %d:%d specified for \"%s\" isn't valid, "
"as length %d isn't positive",
start_offset, length,
hfinfo->abbrev,
length);
} else
dfilter_fail("Range %d:%d isn't valid, "
"as length %d isn't positive",
start_offset, length,
length);
}
}
break;
@ -434,12 +443,21 @@ check_drange_node_sanity(gpointer data, gpointer user_data)
if (start_offset > end_offset) {
if (!args->err) {
args->err = TRUE;
hfinfo = sttype_range_hfinfo(args->st);
dfilter_fail("Range %d-%d specified for \"%s\" isn't valid, "
"as %d is greater than %d",
start_offset, end_offset,
hfinfo->abbrev,
start_offset, end_offset);
entity = sttype_range_entity(args->st);
if (entity && stnode_type_id(entity) == STTYPE_FIELD) {
hfinfo = stnode_data(entity);
dfilter_fail("Range %d-%d specified for \"%s\" isn't valid, "
"as %d is greater than %d",
start_offset, end_offset,
hfinfo->abbrev,
start_offset, end_offset);
} else
dfilter_fail("Range %d-%d isn't valid, "
"as %d is greater than %d",
start_offset, end_offset,
start_offset, end_offset);
}
}
break;
@ -830,6 +848,7 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
{
stnode_t *new_st;
sttype_id_t type2;
stnode_t *entity1;
header_field_info *hfinfo1, *hfinfo2;
df_func_def_t *funcdef;
ftenum_t ftype1, ftype2;
@ -838,15 +857,22 @@ check_relation_LHS_RANGE(const char *relation_string, FtypeCanFunc can_func _U_,
drange_node *rn;
int len_range;
type2 = stnode_type_id(st_arg2);
hfinfo1 = sttype_range_hfinfo(st_arg1);
ftype1 = hfinfo1->type;
DebugLog((" 5 check_relation_LHS_RANGE(%s)\n", relation_string));
if (!ftype_can_slice(ftype1)) {
dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
hfinfo1->abbrev, ftype_pretty_name(ftype1));
type2 = stnode_type_id(st_arg2);
entity1 = sttype_range_entity(st_arg1);
if (entity1 && stnode_type_id(entity1) == STTYPE_FIELD) {
hfinfo1 = stnode_data(entity1);
ftype1 = hfinfo1->type;
if (!ftype_can_slice(ftype1)) {
dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
hfinfo1->abbrev, ftype_pretty_name(ftype1));
THROW(TypeError);
}
} else {
dfilter_fail("Range is not supported, details: " G_STRLOC " entity: %p of type %d",
entity1, entity1 ? stnode_type_id(entity1) : -1);
THROW(TypeError);
}

View File

@ -34,9 +34,9 @@
#include "sttype-range.h"
typedef struct {
guint32 magic;
header_field_info *hfinfo;
drange_t *drange;
guint32 magic;
stnode_t *entity;
drange_t *drange;
} range_t;
#define RANGE_MAGIC 0xec0990ce
@ -51,7 +51,7 @@ range_new(gpointer junk)
range = g_new(range_t, 1);
range->magic = RANGE_MAGIC;
range->hfinfo = NULL;
range->entity = NULL;
range->drange = NULL;
return (gpointer) range;
@ -64,7 +64,7 @@ range_dup(gconstpointer data)
range_t *range;
range = (range_t *)range_new(NULL);
range->hfinfo = org->hfinfo;
range->entity = stnode_dup(org->entity);
range->drange = drange_dup(org->drange);
return (gpointer) range;
@ -79,6 +79,9 @@ range_free(gpointer value)
if (range->drange)
drange_free(range->drange);
if (range->entity)
stnode_free(range->entity);
g_free(range);
}
@ -96,26 +99,25 @@ sttype_range_remove_drange(stnode_t *node)
/* Set a range */
void
sttype_range_set(stnode_t *node, stnode_t *field, GSList* drange_list)
sttype_range_set(stnode_t *node, stnode_t *entity, GSList* drange_list)
{
range_t *range;
range = (range_t*)stnode_data(node);
assert_magic(range, RANGE_MAGIC);
range->hfinfo = (header_field_info *)stnode_data(field);
stnode_free(field);
range->entity = entity;
range->drange = drange_new_from_list(drange_list);
}
void
sttype_range_set1(stnode_t *node, stnode_t *field, drange_node *rn)
sttype_range_set1(stnode_t *node, stnode_t *entity, drange_node *rn)
{
sttype_range_set(node, field, g_slist_append(NULL, rn));
sttype_range_set(node, entity, g_slist_append(NULL, rn));
}
STTYPE_ACCESSOR(header_field_info*, range, hfinfo, RANGE_MAGIC)
STTYPE_ACCESSOR(stnode_t*, range, entity, RANGE_MAGIC)
STTYPE_ACCESSOR(drange_t*, range, drange, RANGE_MAGIC)

View File

@ -27,7 +27,7 @@
#include "syntax-tree.h"
#include "drange.h"
STTYPE_ACCESSOR_PROTOTYPE(header_field_info*, range, hfinfo)
STTYPE_ACCESSOR_PROTOTYPE(stnode_t*, range, entity)
STTYPE_ACCESSOR_PROTOTYPE(drange_t*, range, drange)
/* Set a range */