Print this page
11506 smatch resync


  16  */
  17 
  18 /*
  19  * The point here is to store that a buffer has x bytes even if we don't know
  20  * the value of x.
  21  *
  22  */
  23 
  24 #include "smatch.h"
  25 #include "smatch_slist.h"
  26 #include "smatch_extra.h"
  27 
  28 static int my_id;
  29 
  30 static void array_check(struct expression *expr)
  31 {
  32         struct expression *array;
  33         struct expression *size;
  34         struct expression *offset;
  35         char *array_str, *offset_str;

  36 
  37         expr = strip_expr(expr);
  38         if (!is_array(expr))
  39                 return;
  40 
  41         array = get_array_base(expr);
  42         size = get_size_variable(array);
  43         if (!size)
  44                 return;
  45         offset = get_array_offset(expr);
  46         if (!possible_comparison(size, SPECIAL_EQUAL, offset))
  47                 return;
  48 



  49         array_str = expr_to_str(array);
  50         offset_str = expr_to_str(offset);
  51         sm_warning("potentially one past the end of array '%s[%s]'", array_str, offset_str);
  52         free_string(array_str);
  53         free_string(offset_str);
  54 }
  55 
  56 static int known_access_ok_comparison(struct expression *expr)
  57 {
  58         struct expression *array;
  59         struct expression *size;
  60         struct expression *offset;
  61         int comparison;
  62 
  63         array = get_array_base(expr);
  64         size = get_size_variable(array);
  65         if (!size)
  66                 return 0;
  67         offset = get_array_offset(expr);
  68         comparison = get_comparison(size, offset);
  69         if (comparison == '>' || comparison == SPECIAL_UNSIGNED_GT)
  70                 return 1;
  71 
  72         return 0;
  73 }
  74 
  75 static int known_access_ok_numbers(struct expression *expr)
  76 {
  77         struct expression *array;
  78         struct expression *offset;
  79         sval_t max;
  80         int size;
  81 
  82         array = get_array_base(expr);
  83         offset = get_array_offset(expr);
  84 
  85         size = get_array_size(array);
  86         if (size <= 0)
  87                 return 0;
  88 
  89         get_absolute_max(offset, &max);
  90         if (max.uvalue < size)
  91                 return 1;
  92         return 0;
  93 }
  94 
  95 static void array_check_data_info(struct expression *expr)
  96 {
  97         struct expression *array;
  98         struct expression *offset;
  99         struct state_list *slist;
 100         struct sm_state *sm;
 101         struct compare_data *comp;
 102         char *offset_name;
 103         const char *equal_name = NULL;
 104 
 105         expr = strip_expr(expr);
 106         if (!is_array(expr))
 107                 return;
 108 
 109         if (known_access_ok_numbers(expr))
 110                 return;
 111         if (known_access_ok_comparison(expr))
 112                 return;
 113 
 114         array = get_array_base(expr);
 115         offset = get_array_offset(expr);
 116         offset_name = expr_to_var(offset);
 117         if (!offset_name)
 118                 return;
 119         slist = get_all_possible_equal_comparisons(offset);
 120         if (!slist)
 121                 goto free;
 122 
 123         FOR_EACH_PTR(slist, sm) {
 124                 comp = sm->state->data;
 125                 if (strcmp(comp->left_var, offset_name) == 0) {
 126                         if (db_var_is_array_limit(array, comp->right_var, comp->right_vsl)) {
 127                                 equal_name = comp->right_var;
 128                                 break;
 129                         }
 130                 } else if (strcmp(comp->right_var, offset_name) == 0) {
 131                         if (db_var_is_array_limit(array, comp->left_var, comp->left_vsl)) {




  16  */
  17 
  18 /*
  19  * The point here is to store that a buffer has x bytes even if we don't know
  20  * the value of x.
  21  *
  22  */
  23 
  24 #include "smatch.h"
  25 #include "smatch_slist.h"
  26 #include "smatch_extra.h"
  27 
  28 static int my_id;
  29 
  30 static void array_check(struct expression *expr)
  31 {
  32         struct expression *array;
  33         struct expression *size;
  34         struct expression *offset;
  35         char *array_str, *offset_str;
  36         int limit_type;
  37 
  38         expr = strip_expr(expr);
  39         if (!is_array(expr))
  40                 return;
  41 
  42         array = get_array_base(expr);
  43         size = get_size_variable(array, &limit_type);
  44         if (!size || limit_type != ELEM_COUNT)
  45                 return;
  46         offset = get_array_offset(expr);
  47         if (!possible_comparison(size, SPECIAL_EQUAL, offset))
  48                 return;
  49 
  50         if (buf_comparison_index_ok(expr))
  51                 return;
  52 
  53         array_str = expr_to_str(array);
  54         offset_str = expr_to_str(offset);
  55         sm_warning("potentially one past the end of array '%s[%s]'", array_str, offset_str);
  56         free_string(array_str);
  57         free_string(offset_str);
  58 }
  59 



















  60 static int known_access_ok_numbers(struct expression *expr)
  61 {
  62         struct expression *array;
  63         struct expression *offset;
  64         sval_t max;
  65         int size;
  66 
  67         array = get_array_base(expr);
  68         offset = get_array_offset(expr);
  69 
  70         size = get_array_size(array);
  71         if (size <= 0)
  72                 return 0;
  73 
  74         get_absolute_max(offset, &max);
  75         if (max.uvalue < size)
  76                 return 1;
  77         return 0;
  78 }
  79 
  80 static void array_check_data_info(struct expression *expr)
  81 {
  82         struct expression *array;
  83         struct expression *offset;
  84         struct state_list *slist;
  85         struct sm_state *sm;
  86         struct compare_data *comp;
  87         char *offset_name;
  88         const char *equal_name = NULL;
  89 
  90         expr = strip_expr(expr);
  91         if (!is_array(expr))
  92                 return;
  93 
  94         if (known_access_ok_numbers(expr))
  95                 return;
  96         if (buf_comparison_index_ok(expr))
  97                 return;
  98 
  99         array = get_array_base(expr);
 100         offset = get_array_offset(expr);
 101         offset_name = expr_to_var(offset);
 102         if (!offset_name)
 103                 return;
 104         slist = get_all_possible_equal_comparisons(offset);
 105         if (!slist)
 106                 goto free;
 107 
 108         FOR_EACH_PTR(slist, sm) {
 109                 comp = sm->state->data;
 110                 if (strcmp(comp->left_var, offset_name) == 0) {
 111                         if (db_var_is_array_limit(array, comp->right_var, comp->right_vsl)) {
 112                                 equal_name = comp->right_var;
 113                                 break;
 114                         }
 115                 } else if (strcmp(comp->right_var, offset_name) == 0) {
 116                         if (db_var_is_array_limit(array, comp->left_var, comp->left_vsl)) {