When some memory is allocated, a common pattern is to use a tmp variable to check if the allocation has succeeded or not. This tmp variable is then stored in another variable for future use. ptr = devm_kmalloc(...); if (!ptr) return -ENOMEM; another_val = ptr; So trying to see if this 'alias' is incorrectly freed with kfree makes sense. To do that, add a new hook that check, when an assignment is detected if the right part of the expression is already recorded. If so, also record the right part, so that bogus kfree can check both reference. Signed-off-by: Christophe JAILLET <christophe.jaillet@xxxxxxxxxx> --- This is my first 'real' code proposal for smatch. It is likely to be wrong/incomplete/imperfect. Maybe this functionality is already implemented somewhere else and I just try to duplicate it. All I know is that it seams to work for me, even if it has not detected any issue yet :) (compiling takes SO MUCH time on my machine) --- check_freeing_devm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/check_freeing_devm.c b/check_freeing_devm.c index 11e8d8bc30b6..51fa990f1b4a 100644 --- a/check_freeing_devm.c +++ b/check_freeing_devm.c @@ -26,6 +26,29 @@ static void match_assign(const char *fn, struct expression *expr, void *unused) set_state_expr(my_id, expr->left, &devm); } +/* + * This hook deals with things like: + * ptr = devm_kmalloc(...); + * if (!ptr) + * return -ENOMEM; + * another_val = ptr; <== + */ +static void match_reassign(struct expression *expr) +{ + struct expression *left, *right; + + if (expr->op != '=') + return; + + right = strip_expr(expr->right); + if (!get_state_expr(my_id, right)) + return; + + left = strip_expr(expr->left); + + set_state_expr(my_id, left, &devm); +} + static void match_free_func(const char *fn, struct expression *expr, void *_arg) { struct expression *arg_expr; @@ -86,4 +109,6 @@ void check_freeing_devm(int id) add_function_hook("kfree", &match_free_func, INT_PTR(0)); add_function_hook("krealloc", &match_free_func, INT_PTR(0)); register_funcs_from_file(); + + add_hook(&match_reassign, ASSIGNMENT_HOOK); } -- 2.34.1