From 74ef5b358574c0c13b5962fe9b5694e949470640 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 18 Apr 2009 16:21:23 +0300 Subject: [PATCH] Redo checking for out of range args to ERR_PTR() The old check was almost totally useless. This one still doesn't catch any of this sort of bug, but I believe it's because the current kernel doesn't have any. Signed-off-by: Dan Carpenter --- check_err_ptr.c | 7 ------- check_err_ptr_deref.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/check_err_ptr.c b/check_err_ptr.c index 3368472e..d2ce331f 100644 --- a/check_err_ptr.c +++ b/check_err_ptr.c @@ -27,13 +27,6 @@ static void match_function_def(struct symbol *sym) static void match_err_ptr(const char *fn, struct expression *expr, void *info) { - struct expression *arg; - int value; - - arg = get_argument_from_call_expr(expr->args, 0); - value = get_implied_value(arg); - if (value != UNDEFINED && value < -4095) - smatch_msg("error: the error code is too large for ERR_PTR"); if (!err_ptr) smatch_msg("info: returns_err_ptr"); err_ptr = 1; diff --git a/check_err_ptr_deref.c b/check_err_ptr_deref.c index 396ecf84..1723f055 100644 --- a/check_err_ptr_deref.c +++ b/check_err_ptr_deref.c @@ -9,6 +9,7 @@ #include "smatch.h" #include "smatch_slist.h" +#include "smatch_extra.h" static int my_id; @@ -93,10 +94,47 @@ static void register_err_ptr_funcs(void) clear_token_alloc(); } +static void match_err_ptr(const char *fn, struct expression *expr, void *info) +{ + struct expression *arg; + char *name; + struct symbol *sym; + struct sm_state *sm; + struct sm_state *tmp; + long long tmp_min; + long long tmp_max; + long long min = whole_range.max; + long long max = whole_range.min; + + arg = get_argument_from_call_expr(expr->args, 0); + name = get_variable_from_expr(arg, &sym); + if (!name || !sym) + goto free; + sm = get_sm_state(name, SMATCH_EXTRA, sym); + if (!sm) + goto free; + FOR_EACH_PTR(sm->possible, tmp) { + tmp_min = get_dinfo_min((struct data_info *)tmp->state->data); + if (tmp_min != whole_range.min && tmp_min < min) + min = tmp_min; + tmp_max = get_dinfo_max((struct data_info *)tmp->state->data); + if (tmp_max != whole_range.max && tmp_max > max) + max = tmp_max; + } END_FOR_EACH_PTR(tmp); + if (min < -4095) + smatch_msg("error: %lld too low for ERR_PTR", min); + if (max > 0) + smatch_msg("error: passing non neg %lld to ERR_PTR", max); +free: + free_string(name); +} + void check_err_ptr_deref(int id) { my_id = id; add_conditional_hook("IS_ERR", &match_is_err, NULL); register_err_ptr_funcs(); add_hook(&match_dereferences, DEREF_HOOK); + add_function_hook("ERR_PTR", &match_err_ptr, NULL); } + -- 2.11.4.GIT