From 5e55933d8a7d742d19034b3f29d9e5c7957be2d4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 21 Nov 2017 14:45:31 +0300 Subject: [PATCH] buf_comparison: copy the code from smatch_constraints.c This code is basically the same as smatch_constraints.c. We're trying to link the size variable and the buffer. So I've copied the improvements from smatch_constraints.c to here as well. Signed-off-by: Dan Carpenter --- smatch_buf_comparison.c | 71 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/smatch_buf_comparison.c b/smatch_buf_comparison.c index 51674827..64fe039b 100644 --- a/smatch_buf_comparison.c +++ b/smatch_buf_comparison.c @@ -121,52 +121,71 @@ static void db_save_type_links(struct expression *array, struct expression *size sql_insert_data_info(size, ARRAY_LEN, array_name); } -static void match_alloc(const char *fn, struct expression *expr, void *_size_arg) +static void match_alloc_helper(struct expression *pointer, struct expression *size) { - int size_arg = PTR_INT(_size_arg); - struct expression *pointer, *call, *arg; - struct sm_state *tmp; + struct expression *tmp; + struct sm_state *sm; + sval_t sval; + int cnt = 0; - pointer = strip_expr(expr->left); - call = strip_expr(expr->right); - arg = get_argument_from_call_expr(call->args, size_arg); - arg = strip_expr(arg); + pointer = strip_expr(pointer); + size = strip_expr(size); + if (!size || !pointer) + return; - if (arg->type == EXPR_BINOP && arg->op == '*') { - struct expression *left, *right; - sval_t sval; + while ((tmp = get_assigned_expr(size))) { + size = strip_expr(tmp); + if (cnt++ > 5) + break; + } - left = strip_expr(arg->left); - right = strip_expr(arg->right); + if (size->type == EXPR_BINOP && size->op == '*') { + struct expression *mult_left, *mult_right; - if (get_implied_value(left, &sval) && - sval.value == bytes_per_element(pointer)) - arg = right; + mult_left = strip_expr(size->left); + mult_right = strip_expr(size->right); - if (get_implied_value(right, &sval) && + if (get_implied_value(mult_left, &sval) && + sval.value == bytes_per_element(pointer)) + size = mult_right; + else if (get_implied_value(mult_right, &sval) && sval.value == bytes_per_element(pointer)) - arg = left; + size = mult_left; + else + return; } - db_save_type_links(pointer, arg); - tmp = set_state_expr(size_id, pointer, alloc_expr_state(arg)); - if (!tmp) + db_save_type_links(pointer, size); + sm = set_state_expr(size_id, pointer, alloc_expr_state(size)); + if (!sm) return; - set_state_expr(link_id, arg, alloc_expr_state(pointer)); + set_state_expr(link_id, size, alloc_expr_state(pointer)); +} + +static void match_alloc(const char *fn, struct expression *expr, void *_size_arg) +{ + int size_arg = PTR_INT(_size_arg); + struct expression *pointer, *call, *arg; + + pointer = strip_expr(expr->left); + call = strip_expr(expr->right); + arg = get_argument_from_call_expr(call->args, size_arg); + match_alloc_helper(pointer, arg); } -static void match_calloc(const char *fn, struct expression *expr, void *unused) +static void match_calloc(const char *fn, struct expression *expr, void *_start_arg) { + int start_arg = PTR_INT(_start_arg); struct expression *pointer, *call, *arg; struct sm_state *tmp; sval_t sval; pointer = strip_expr(expr->left); call = strip_expr(expr->right); - arg = get_argument_from_call_expr(call->args, 0); + arg = get_argument_from_call_expr(call->args, start_arg); if (get_implied_value(arg, &sval) && sval.value == bytes_per_element(pointer)) - arg = get_argument_from_call_expr(call->args, 1); + arg = get_argument_from_call_expr(call->args, start_arg + 1); db_save_type_links(pointer, arg); tmp = set_state_expr(size_id, pointer, alloc_expr_state(arg)); @@ -560,6 +579,8 @@ void register_buf_comparison(int id) add_allocation_function("devm_kmalloc", &match_alloc, 1); add_allocation_function("devm_kzalloc", &match_alloc, 1); add_allocation_function("kcalloc", &match_calloc, 0); + add_allocation_function("devm_kcalloc", &match_calloc, 1); + add_allocation_function("kmalloc_array", &match_calloc, 0); add_allocation_function("krealloc", &match_alloc, 1); } -- 2.11.4.GIT