Print this page
11506 smatch resync

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/check_zero_to_err_ptr.c
          +++ new/usr/src/tools/smatch/src/check_zero_to_err_ptr.c
↓ open down ↓ 66 lines elided ↑ open up ↑
  67   67                  return 0;
  68   68          if (next->fn->type != EXPR_SYMBOL || !next->fn->symbol ||
  69   69              !next->fn->symbol->ident ||
  70   70              (strcmp(next->fn->symbol->ident->name, "IS_ERR") != 0 &&
  71   71               strcmp(next->fn->symbol->ident->name, "IS_ERR_OR_NULL") != 0))
  72   72                  return 0;
  73   73          next = get_argument_from_call_expr(next->args, 0);
  74   74          return expr_equiv(next, arg);
  75   75  }
  76   76  
       77 +static int is_non_zero_int(struct range_list *rl)
       78 +{
       79 +        struct data_range *tmp;
       80 +        int cnt = -1;
       81 +
       82 +        FOR_EACH_PTR(rl, tmp) {
       83 +                cnt++;
       84 +
       85 +                if (cnt == 0) {
       86 +                        if (tmp->min.value == INT_MIN &&
       87 +                            tmp->max.value == -1)
       88 +                                continue;
       89 +                } else if (cnt == 1) {
       90 +                        if (tmp->min.value == 1 &&
       91 +                            tmp->max.value == INT_MAX)
       92 +                                return 1;
       93 +                }
       94 +                return 0;
       95 +        } END_FOR_EACH_PTR(tmp);
       96 +        return 0;
       97 +}
       98 +
  77   99  static int is_valid_ptr(sval_t sval)
  78  100  {
  79      -        if (sval.type == &int_ctype &&
  80      -            (sval.value == INT_MIN || sval.value == INT_MAX))
      101 +        if (sval.value == INT_MIN || sval.value == INT_MAX)
  81  102                  return 0;
  82  103  
  83  104          if (sval_cmp(valid_ptr_min_sval, sval) <= 0 &&
  84      -            sval_cmp(valid_ptr_max_sval, sval) >= 0)
      105 +            sval_cmp(valid_ptr_max_sval, sval) >= 0) {
  85  106                  return 1;
      107 +        }
  86  108          return 0;
  87  109  }
  88  110  
      111 +static int has_distinct_zero(struct range_list *rl)
      112 +{
      113 +        struct data_range *tmp;
      114 +
      115 +        FOR_EACH_PTR(rl, tmp) {
      116 +                if (tmp->min.value == 0 || tmp->max.value == 0)
      117 +                        return 1;
      118 +        } END_FOR_EACH_PTR(tmp);
      119 +        return 0;
      120 +}
      121 +
  89  122  static void match_err_ptr(const char *fn, struct expression *expr, void *data)
  90  123  {
  91  124          struct expression *arg_expr;
  92  125          struct sm_state *sm, *tmp;
  93      -        sval_t sval;
  94  126  
      127 +        if (is_impossible_path())
      128 +                return;
      129 +
  95  130          arg_expr = get_argument_from_call_expr(expr->args, 0);
  96  131          sm = get_sm_state_expr(SMATCH_EXTRA, arg_expr);
  97  132          if (!sm)
  98  133                  return;
  99  134  
 100  135          if (is_comparison_call(expr))
 101  136                  return;
 102  137  
 103  138          if (next_line_checks_IS_ERR(expr, arg_expr))
 104  139                  return;
 105  140          if (strcmp(fn, "ERR_PTR") == 0 &&
 106  141              next_line_is_if(arg_expr))
 107  142                  return;
 108  143  
 109  144          FOR_EACH_PTR(sm->possible, tmp) {
 110  145                  if (!estate_rl(tmp->state))
 111  146                          continue;
      147 +                if (is_non_zero_int(estate_rl(tmp->state)))
      148 +                        continue;
      149 +                if (has_distinct_zero(estate_rl(tmp->state))) {
      150 +                        sm_warning("passing zero to '%s'", fn);
      151 +                        return;
      152 +                }
      153 +                if (strcmp(fn, "PTR_ERR") != 0)
      154 +                        continue;
 112  155                  if (is_valid_ptr(estate_min(tmp->state)) &&
 113  156                      is_valid_ptr(estate_max(tmp->state))) {
 114  157                          sm_warning("passing a valid pointer to '%s'", fn);
 115  158                          return;
 116  159                  }
 117      -                if (!rl_to_sval(estate_rl(tmp->state), &sval))
 118      -                        continue;
 119      -                if (sval.value != 0)
 120      -                        continue;
 121      -                sm_warning("passing zero to '%s'", fn);
 122      -                return;
 123  160          } END_FOR_EACH_PTR(tmp);
 124  161  }
 125  162  
 126  163  void check_zero_to_err_ptr(int id)
 127  164  {
 128  165          if (option_project != PROJ_KERNEL)
 129  166                  return;
 130  167  
 131  168          my_id = id;
 132  169          add_function_hook("ERR_PTR", &match_err_ptr, NULL);
 133  170          add_function_hook("ERR_CAST", &match_err_ptr, NULL);
 134  171          add_function_hook("PTR_ERR", &match_err_ptr, NULL);
 135  172  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX