Print this page
11506 smatch resync
*** 21,37 ****
#include "scope.h"
#include "smatch.h"
#include "smatch_extra.h"
static int implied_err_cast_return(struct expression *call, void *unused, struct range_list **rl)
{
struct expression *arg;
arg = get_argument_from_call_expr(call->args, 0);
! if (!get_implied_rl(arg, rl))
! *rl = alloc_rl(ll_to_sval(-4095), ll_to_sval(-1));
return 1;
}
static void hack_ERR_PTR(struct symbol *sym)
{
--- 21,43 ----
#include "scope.h"
#include "smatch.h"
#include "smatch_extra.h"
+ static sval_t err_ptr_min;
+ static sval_t err_ptr_max;
+ static sval_t null_ptr;
+
static int implied_err_cast_return(struct expression *call, void *unused, struct range_list **rl)
{
struct expression *arg;
arg = get_argument_from_call_expr(call->args, 0);
! if (!get_implied_rl(arg, rl)) {
! *rl = alloc_rl(err_ptr_min, err_ptr_max);
! *rl = cast_rl(get_type(arg), *rl);
! }
return 1;
}
static void hack_ERR_PTR(struct symbol *sym)
{
*** 76,89 ****
{
int param = PTR_INT(_param);
struct expression *arg;
struct smatch_state *pre_state;
struct smatch_state *end_state;
arg = get_argument_from_call_expr(call_expr->args, param);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
! end_state = estate_filter_range(pre_state, ll_to_sval(-4095), ll_to_sval(0));
set_extra_expr_nomod(arg, end_state);
}
static void match_param_err_or_null(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *_param)
--- 82,103 ----
{
int param = PTR_INT(_param);
struct expression *arg;
struct smatch_state *pre_state;
struct smatch_state *end_state;
+ struct range_list *rl;
arg = get_argument_from_call_expr(call_expr->args, param);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
! if (estate_rl(pre_state)) {
! rl = estate_rl(pre_state);
! rl = remove_range(rl, null_ptr, null_ptr);
! rl = remove_range(rl, err_ptr_min, err_ptr_max);
! } else {
! rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
! }
! end_state = alloc_estate_rl(rl);
set_extra_expr_nomod(arg, end_state);
}
static void match_param_err_or_null(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *_param)
*** 94,135 ****
struct smatch_state *pre_state;
struct smatch_state *end_state;
arg = get_argument_from_call_expr(call_expr->args, param);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
! rl = alloc_rl(ll_to_sval(-4095), ll_to_sval(0));
rl = rl_intersection(estate_rl(pre_state), rl);
! rl = cast_rl(estate_type(pre_state), rl);
end_state = alloc_estate_rl(rl);
set_extra_expr_nomod(arg, end_state);
}
static void match_not_err(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *unused)
{
struct expression *arg;
struct smatch_state *pre_state;
! struct smatch_state *new_state;
arg = get_argument_from_call_expr(call_expr->args, 0);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
! new_state = estate_filter_range(pre_state, sval_type_min(&long_ctype), ll_to_sval(-1));
! set_extra_expr_nomod(arg, new_state);
}
static void match_err(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *unused)
{
struct expression *arg;
struct smatch_state *pre_state;
! struct smatch_state *new_state;
arg = get_argument_from_call_expr(call_expr->args, 0);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
! new_state = estate_filter_range(pre_state, sval_type_min(&long_ctype), ll_to_sval(-4096));
! new_state = estate_filter_range(new_state, ll_to_sval(0), sval_type_max(&long_ctype));
! set_extra_expr_nomod(arg, new_state);
}
static void match_container_of_macro(const char *fn, struct expression *expr, void *unused)
{
set_extra_expr_mod(expr->left, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));
--- 108,158 ----
struct smatch_state *pre_state;
struct smatch_state *end_state;
arg = get_argument_from_call_expr(call_expr->args, param);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
! call_results_to_rl(call_expr, &ptr_ctype, "0,(-4095)-(-1)", &rl);
rl = rl_intersection(estate_rl(pre_state), rl);
! rl = cast_rl(get_type(arg), rl);
end_state = alloc_estate_rl(rl);
set_extra_expr_nomod(arg, end_state);
}
static void match_not_err(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *unused)
{
struct expression *arg;
struct smatch_state *pre_state;
! struct range_list *rl;
arg = get_argument_from_call_expr(call_expr->args, 0);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
! if (estate_rl(pre_state)) {
! rl = estate_rl(pre_state);
! rl = remove_range(rl, err_ptr_min, err_ptr_max);
! } else {
! rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
! }
! rl = cast_rl(get_type(arg), rl);
! set_extra_expr_nomod(arg, alloc_estate_rl(rl));
}
static void match_err(const char *fn, struct expression *call_expr,
struct expression *assign_expr, void *unused)
{
struct expression *arg;
struct smatch_state *pre_state;
! struct range_list *rl;
arg = get_argument_from_call_expr(call_expr->args, 0);
pre_state = get_state_expr(SMATCH_EXTRA, arg);
! rl = estate_rl(pre_state);
! if (!rl)
! rl = alloc_rl(err_ptr_min, err_ptr_max);
! rl = rl_intersection(rl, alloc_rl(err_ptr_min, err_ptr_max));
! rl = cast_rl(get_type(arg), rl);
! set_extra_expr_nomod(arg, alloc_estate_rl(rl));
}
static void match_container_of_macro(const char *fn, struct expression *expr, void *unused)
{
set_extra_expr_mod(expr->left, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));
*** 377,391 ****
--- 400,439 ----
__in_fake_assign++;
__split_expr(assign);
__in_fake_assign--;
}
+ bool is_ignored_kernel_data(const char *name)
+ {
+ if (option_project != PROJ_KERNEL)
+ return false;
+
+ /*
+ * On the file I was looking at lockdep was 25% of the DB.
+ */
+ if (strstr(name, ".dep_map."))
+ return true;
+ if (strstr(name, ".lockdep_map."))
+ return true;
+ return false;
+ }
+
void check_kernel(int id)
{
if (option_project != PROJ_KERNEL)
return;
+ err_ptr_min.type = &ptr_ctype;
+ err_ptr_min.value = -4095;
+ err_ptr_max.type = &ptr_ctype;
+ err_ptr_max.value = -1l;
+ null_ptr.type = &ptr_ctype;
+ null_ptr.value = 0;
+
+ err_ptr_min = sval_cast(&ptr_ctype, err_ptr_min);
+ err_ptr_max = sval_cast(&ptr_ctype, err_ptr_max);
+
add_implied_return_hook("ERR_PTR", &implied_err_cast_return, NULL);
add_implied_return_hook("ERR_CAST", &implied_err_cast_return, NULL);
add_implied_return_hook("PTR_ERR", &implied_err_cast_return, NULL);
add_hook(hack_ERR_PTR, AFTER_DEF_HOOK);
return_implies_state("IS_ERR_OR_NULL", 0, 0, &match_param_valid_ptr, (void *)0);