From f037c694630306a0a70bb922411119fe7bd9a5d9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 11 Oct 2013 10:54:10 +0300 Subject: [PATCH] smatch_clear_buffer: memcpy() should set the destination to unknown In the original code "memcpy(foo, bar, sizeof(foo))" was equivalent to "foo.a = foo.a; foo.b = foo.b;". Most of the time foo starts as uninitialized so it's not a problem, but if it's initialized that doesn't work. Signed-off-by: Dan Carpenter --- smatch_clear_buffer.c | 2 +- smatch_expressions.c | 40 ++++++++++++++++++++++++++++++++++++++++ smatch_extra.h | 1 + 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/smatch_clear_buffer.c b/smatch_clear_buffer.c index 3fdd14c6..3d9d140c 100644 --- a/smatch_clear_buffer.c +++ b/smatch_clear_buffer.c @@ -90,7 +90,7 @@ static void initialize_struct_members(struct symbol *type, struct expression *ex if (to && type_positive_bits(get_type(member)) >= type_positive_bits(get_type(to))) assign = assign_expression(member, to); else - assign = assign_expression(member, member); + assign = assign_expression(member, unknown_value_expression(member)); __pass_to_client(assign, ASSIGNMENT_HOOK); } END_FOR_EACH_PTR(tmp); diff --git a/smatch_expressions.c b/smatch_expressions.c index baa01d00..275c380d 100644 --- a/smatch_expressions.c +++ b/smatch_expressions.c @@ -104,3 +104,43 @@ struct expression *symbol_expression(struct symbol *sym) expr->symbol_name = sym->ident; return expr; } + +#define FAKE_NAME "smatch_fake" +struct ident unknown_value = { + .len = sizeof(FAKE_NAME), + .name = FAKE_NAME, +}; + +static int fake_counter; +static struct ident *fake_ident() +{ + struct ident *ret; + char buf[32]; + int len; + + snprintf(buf, sizeof(buf), "smatch_fake_%d", fake_counter++); + len = strlen(buf) + 1; + ret = malloc(sizeof(*ret) + len); + memset(ret, 0, sizeof(*ret)); + memcpy(ret->name, buf, len); + ret->len = len; + + return ret; +} + +struct expression *unknown_value_expression(struct expression *expr) +{ + struct expression *ret; + struct symbol *type; + + type = get_type(expr); + if (!type || type->type != SYM_BASETYPE) + type = &llong_ctype; + + ret = alloc_expression(expr->pos, EXPR_SYMBOL); + ret->symbol = alloc_symbol(expr->pos, SYM_BASETYPE); + ret->symbol->ctype.base_type = type; + ret->symbol_name = fake_ident(); + + return ret; +} diff --git a/smatch_extra.h b/smatch_extra.h index 937ba88c..a7b27041 100644 --- a/smatch_extra.h +++ b/smatch_extra.h @@ -157,6 +157,7 @@ struct expression *assign_expression(struct expression *left, struct expression struct expression *binop_expression(struct expression *left, int op, struct expression *right); struct expression *array_element_expression(struct expression *array, struct expression *offset); struct expression *symbol_expression(struct symbol *sym); +struct expression *unknown_value_expression(struct expression *expr); /* smatch_param_limit.c */ struct smatch_state *get_orig_estate(const char *name, struct symbol *sym); -- 2.11.4.GIT