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)) {
|