Print this page
11506 smatch resync

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/check_buffer_too_small_for_struct.c
          +++ new/usr/src/tools/smatch/src/check_buffer_too_small_for_struct.c
↓ open down ↓ 18 lines elided ↑ open up ↑
  19   19  
  20   20  static int my_id;
  21   21  
  22   22  STATE(too_small);
  23   23  
  24   24  static void match_assign(struct expression *expr)
  25   25  {
  26   26          struct symbol *left_type, *right_type;
  27   27          struct expression *size_expr;
  28   28          sval_t min_size;
       29 +        int limit_type;
       30 +        int bytes;
  29   31  
  30   32          left_type = get_type(expr->left);
  31   33          if (!left_type || left_type->type != SYM_PTR)
  32   34                  return;
  33   35          left_type = get_real_base_type(left_type);
  34   36          if (!left_type || left_type->type != SYM_STRUCT)
  35   37                  return;
  36   38  
  37   39          right_type = get_type(expr->right);
  38   40          if (!right_type || right_type->type != SYM_PTR)
  39   41                  return;
  40   42          right_type = get_real_base_type(right_type);
  41   43          if (!right_type)
  42   44                  return;
  43   45          if (right_type != &void_ctype && type_bits(right_type) != 8)
  44   46                  return;
  45   47  
  46      -        size_expr = get_size_variable(expr->right);
       48 +        bytes = get_array_size_bytes(expr->right);
       49 +        if (bytes >= type_bytes(left_type))
       50 +                return;
       51 +
       52 +        size_expr = get_size_variable(expr->right, &limit_type);
  47   53          if (!size_expr)
  48   54                  return;
       55 +        if (limit_type != ELEM_COUNT)
       56 +                return;
  49   57  
  50   58          get_absolute_min(size_expr, &min_size);
  51   59          if (min_size.value >= type_bytes(left_type))
  52   60                  return;
  53   61  
  54   62          set_state_expr(my_id, expr->left, &too_small);
  55   63  }
  56   64  
  57   65  static void match_dereferences(struct expression *expr)
  58   66  {
  59   67          struct symbol *left_type;
  60   68          struct expression *right;
  61   69          struct smatch_state *state;
  62   70          char *name;
  63   71          struct expression *size_expr;
  64   72          sval_t min_size;
       73 +        int limit_type;
  65   74  
  66   75          if (expr->type != EXPR_PREOP)
  67   76                  return;
  68   77  
  69   78          expr = strip_expr(expr->unop);
  70   79          state = get_state_expr(my_id, expr);
  71   80          if (state != &too_small)
  72   81                  return;
  73   82  
  74   83          left_type = get_type(expr);
  75   84          if (!left_type || left_type->type != SYM_PTR)
  76   85                  return;
  77   86          left_type = get_real_base_type(left_type);
  78   87          if (!left_type || left_type->type != SYM_STRUCT)
  79   88                  return;
  80   89  
  81   90          right = get_assigned_expr(expr);
  82      -        size_expr = get_size_variable(right);
       91 +        size_expr = get_size_variable(right, &limit_type);
  83   92          if (!size_expr)
  84   93                  return;
       94 +        if (limit_type != ELEM_COUNT)
       95 +                return;
  85   96  
  86   97          get_absolute_min(size_expr, &min_size);
  87   98          if (min_size.value >= type_bytes(left_type))
  88   99                  return;
  89  100  
  90  101          name = expr_to_str(right);
  91  102          sm_warning("is '%s' large enough for 'struct %s'? %s", name, left_type->ident ? left_type->ident->name : "<anon>", sval_to_str(min_size));
  92  103          free_string(name);
  93  104          set_state_expr(my_id, expr, &undefined);
  94  105  }
  95  106  
  96  107  void check_buffer_too_small_for_struct(int id)
  97  108  {
  98  109          my_id = id;
  99  110  
 100  111          add_hook(&match_assign, ASSIGNMENT_HOOK);
 101  112          add_hook(&match_dereferences, DEREF_HOOK);
 102  113  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX