Print this page
new smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/check_rosenberg.c
          +++ new/usr/src/tools/smatch/src/check_rosenberg.c
↓ open down ↓ 20 lines elided ↑ open up ↑
  21   21  /* function is called that clears the struct */
  22   22  
  23   23  #include "scope.h"
  24   24  #include "smatch.h"
  25   25  #include "smatch_function_hashtable.h"
  26   26  #include "smatch_slist.h"
  27   27  #include "smatch_extra.h"
  28   28  
  29   29  static int my_whole_id;
  30   30  static int my_member_id;
       31 +static int skb_put_id;
  31   32  
  32   33  STATE(cleared);
  33   34  
  34   35  static void extra_mod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
  35   36  {
  36   37          struct symbol *type;
  37   38  
  38   39          type = get_real_base_type(sym);
  39   40          if (!type || type->type != SYM_STRUCT)
  40   41                  return;
↓ open down ↓ 76 lines elided ↑ open up ↑
 117  118          struct symbol *sym;
 118  119  
 119  120          if (expr->type != EXPR_SYMBOL)
 120  121                  return FALSE;
 121  122          sym = expr->symbol;
 122  123          if (!sym)
 123  124                  return FALSE;
 124  125          return toplevel(sym->scope);
 125  126  }
 126  127  
 127      -static int was_initialized(struct expression *expr)
 128      -{
 129      -        struct symbol *sym;
 130      -        char *name;
 131      -
 132      -        name = expr_to_var_sym(expr, &sym);
 133      -        if (!name)
 134      -                return 0;
 135      -        if (sym->initializer)
 136      -                return 1;
 137      -        return 0;
 138      -}
 139      -
 140  128  static void match_clear(const char *fn, struct expression *expr, void *_arg_no)
 141  129  {
 142  130          struct expression *ptr;
 143  131          int arg_no = PTR_INT(_arg_no);
 144  132  
 145  133          ptr = get_argument_from_call_expr(expr->args, arg_no);
 146  134          if (!ptr)
 147  135                  return;
 148  136          ptr = strip_expr(ptr);
 149  137          if (ptr->type != EXPR_PREOP || ptr->op != '&')
↓ open down ↓ 101 lines elided ↑ open up ↑
 251  239          data = strip_expr(data);
 252  240          if (!data)
 253  241                  return;
 254  242          if (data->type == EXPR_PREOP && data->op == '&')
 255  243                  data = strip_expr(data->unop);
 256  244          if (data->type != EXPR_SYMBOL)
 257  245                  return;
 258  246  
 259  247          if (has_global_scope(data))
 260  248                  return;
 261      -        if (was_initialized(data))
      249 +        if (was_memset(data))
 262  250                  return;
      251 +        if (warn_on_holey_struct(data))
      252 +                return;
      253 +        check_members_initialized(data);
      254 +}
      255 +
      256 +static void check_skb_put(struct expression *data)
      257 +{
      258 +        data = strip_expr(data);
      259 +        if (!data)
      260 +                return;
      261 +        if (data->type == EXPR_PREOP && data->op == '&')
      262 +                data = strip_expr(data->unop);
      263 +
 263  264          if (was_memset(data))
 264  265                  return;
 265  266          if (warn_on_holey_struct(data))
 266  267                  return;
 267  268          check_members_initialized(data);
 268  269  }
 269  270  
 270  271  static void match_copy_to_user(const char *fn, struct expression *expr, void *_arg)
 271  272  {
 272  273          int arg = PTR_INT(_arg);
↓ open down ↓ 11 lines elided ↑ open up ↑
 284  285  static void db_param_cleared(struct expression *expr, int param, char *key, char *value)
 285  286  {
 286  287          while (expr->type == EXPR_ASSIGNMENT)
 287  288                  expr = strip_expr(expr->right);
 288  289          if (expr->type != EXPR_CALL)
 289  290                  return;
 290  291  
 291  292          match_clear(NULL, expr, INT_PTR(param));
 292  293  }
 293  294  
 294      -static void match_assign(struct expression *expr)
      295 +static struct smatch_state *alloc_expr_state(struct expression *expr)
 295  296  {
      297 +        struct smatch_state *state;
      298 +        char *name;
      299 +
      300 +        name = expr_to_str(expr);
      301 +        if (!name)
      302 +                return NULL;
      303 +
      304 +        state = __alloc_smatch_state(0);
      305 +        expr = strip_expr(expr);
      306 +        state->name = alloc_sname(name);
      307 +        free_string(name);
      308 +        state->data = expr;
      309 +        return state;
      310 +}
      311 +
      312 +static void match_skb_put(const char *fn, struct expression *expr, void *unused)
      313 +{
 296  314          struct symbol *type;
      315 +        struct smatch_state *state;
 297  316  
 298  317          type = get_type(expr->left);
      318 +        type = get_real_base_type(type);
 299  319          if (!type || type->type != SYM_STRUCT)
 300  320                  return;
 301      -        set_state_expr(my_whole_id, expr->left, &cleared);
      321 +        state = alloc_expr_state(expr->left);
      322 +        set_state_expr(skb_put_id, expr->left, state);
 302  323  }
 303  324  
      325 +static void match_return_skb_put(struct expression *expr)
      326 +{
      327 +        struct sm_state *sm;
      328 +        struct stree *stree;
      329 +
      330 +        if (is_error_return(expr))
      331 +                return;
      332 +
      333 +        stree = __get_cur_stree();
      334 +
      335 +        FOR_EACH_MY_SM(skb_put_id, stree, sm) {
      336 +                check_skb_put(sm->state->data);
      337 +        } END_FOR_EACH_SM(sm);
      338 +}
      339 +
 304  340  static void register_clears_argument(void)
 305  341  {
 306  342          struct token *token;
 307  343          const char *func;
 308  344          int arg;
 309  345  
 310  346          token = get_tokens_file("kernel.clears_argument");
 311  347          if (!token)
 312  348                  return;
 313  349          if (token_type(token) != TOKEN_STREAMBEGIN)
↓ open down ↓ 48 lines elided ↑ open up ↑
 362  398  
 363  399          add_function_hook("memset", &match_clear, INT_PTR(0));
 364  400          add_function_hook("memcpy", &match_clear, INT_PTR(0));
 365  401          add_function_hook("memzero", &match_clear, INT_PTR(0));
 366  402          add_function_hook("__memset", &match_clear, INT_PTR(0));
 367  403          add_function_hook("__memcpy", &match_clear, INT_PTR(0));
 368  404          add_function_hook("__memzero", &match_clear, INT_PTR(0));
 369  405          add_function_hook("__builtin_memset", &match_clear, INT_PTR(0));
 370  406          add_function_hook("__builtin_memcpy", &match_clear, INT_PTR(0));
 371  407  
 372      -        add_hook(&match_assign, ASSIGNMENT_HOOK);
 373  408          register_clears_argument();
 374  409          select_return_states_hook(PARAM_CLEARED, &db_param_cleared);
 375  410  
 376  411          register_copy_funcs_from_file();
 377  412  }
 378  413  
 379  414  void check_rosenberg2(int id)
 380  415  {
 381  416          if (option_project != PROJ_KERNEL)
 382  417                  return;
 383  418  
 384  419          my_member_id = id;
 385  420          set_dynamic_states(my_member_id);
 386  421          add_extra_mod_hook(&extra_mod_hook);
 387  422  }
 388  423  
      424 +void check_rosenberg3(int id)
      425 +{
      426 +        if (option_project != PROJ_KERNEL)
      427 +                return;
      428 +
      429 +        skb_put_id = id;
      430 +        set_dynamic_states(skb_put_id);
      431 +        add_function_assign_hook("skb_put", &match_skb_put, NULL);
      432 +        add_hook(&match_return_skb_put, RETURN_HOOK);
      433 +}
      434 +
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX