2 * Copyright (C) 2012 Oracle.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
19 * The point here is to store that a buffer has x bytes even if we don't know
25 #include "smatch_extra.h"
26 #include "smatch_slist.h"
32 * There is a bunch of code which does this:
37 * So if "size" is non-zero then the size of "foo" is size. But really it's
38 * also true if size is zero. It's just better to assume to not trample over
39 * the data that we have by merging &undefined states.
42 static struct smatch_state
*unmatched_state(struct sm_state
*sm
)
47 static struct smatch_state
*merge_links(struct smatch_state
*s1
, struct smatch_state
*s2
)
49 struct expression
*expr1
, *expr2
;
54 if (expr1
&& expr2
&& expr_equiv(expr1
, expr2
))
59 static struct expression
*ignore_link_mod
;
60 static void match_link_modify(struct sm_state
*sm
, struct expression
*mod_expr
)
62 struct expression
*expr
;
65 if (mod_expr
== ignore_link_mod
)
67 ignore_link_mod
= NULL
;
69 expr
= sm
->state
->data
;
71 set_state_expr(size_id
, expr
, &undefined
);
72 set_state(link_id
, sm
->name
, sm
->sym
, &undefined
);
76 FOR_EACH_PTR(sm
->possible
, tmp
) {
77 expr
= tmp
->state
->data
;
79 set_state_expr(size_id
, expr
, &undefined
);
80 } END_FOR_EACH_PTR(tmp
);
81 set_state(link_id
, sm
->name
, sm
->sym
, &undefined
);
84 static void add_link(struct expression
*size
, struct expression
*buf
, struct expression
*mod_expr
)
86 ignore_link_mod
= mod_expr
;
87 set_state_expr(link_id
, size
, alloc_state_expr(buf
));
90 static const char *limit_map
[] = {
98 int state_to_limit(struct smatch_state
*state
)
102 if (!state
|| !state
->data
)
105 for (i
= 0; i
< ARRAY_SIZE(limit_map
); i
++) {
106 if (strncmp(state
->name
, limit_map
[i
], strlen(limit_map
[i
])) == 0)
107 return i
+ BYTE_COUNT
;
113 const char *limit_type_str(unsigned int limit_type
)
115 if (limit_type
- BYTE_COUNT
>= ARRAY_SIZE(limit_map
)) {
116 sm_msg("internal: wrong size type %u", limit_type
);
120 return limit_map
[limit_type
- BYTE_COUNT
];
123 static struct smatch_state
*alloc_compare_size(int limit_type
, struct expression
*expr
)
125 struct smatch_state
*state
;
129 state
= __alloc_smatch_state(0);
130 expr
= strip_expr(expr
);
131 name
= expr_to_str(expr
);
132 snprintf(buf
, sizeof(buf
), "%s %s", limit_type_str(limit_type
), name
);
133 state
->name
= alloc_sname(buf
);
139 static int bytes_per_element(struct expression
*expr
)
143 type
= get_type(expr
);
147 if (type
->type
!= SYM_PTR
&& type
->type
!= SYM_ARRAY
)
150 type
= get_base_type(type
);
151 return type_bytes(type
);
154 static void db_save_type_links(struct expression
*array
, int type_limit
, struct expression
*size
)
156 const char *array_name
;
158 array_name
= get_data_info_name(array
);
161 sql_insert_data_info(size
, type_limit
, array_name
);
164 static void match_alloc_helper(struct expression
*pointer
, struct expression
*size
, struct expression
*mod_expr
)
166 struct smatch_state
*state
;
167 struct expression
*tmp
;
169 int limit_type
= BYTE_COUNT
;
172 pointer
= strip_expr(pointer
);
173 size
= strip_expr(size
);
174 if (!size
|| !pointer
)
177 tmp
= get_assigned_expr_recurse(size
);
178 if (tmp
&& tmp
->type
== EXPR_BINOP
)
179 size
= strip_expr(tmp
);
181 if (size
->type
== EXPR_BINOP
&& size
->op
== '*') {
182 struct expression
*mult_left
, *mult_right
;
184 mult_left
= strip_expr(size
->left
);
185 mult_right
= strip_expr(size
->right
);
187 if (get_implied_value(mult_left
, &sval
) &&
188 sval
.value
== bytes_per_element(pointer
))
190 else if (get_implied_value(mult_right
, &sval
) &&
191 sval
.value
== bytes_per_element(pointer
))
195 limit_type
= ELEM_COUNT
;
198 /* Only save links to variables, not fixed sizes */
199 if (get_value(size
, &sval
))
202 if (size
->type
== EXPR_BINOP
&& size
->op
== '+' &&
203 get_value(size
->right
, &sval
) && sval
.value
== 1) {
205 limit_type
= ELEM_LAST
;
208 db_save_type_links(pointer
, limit_type
, size
);
209 state
= alloc_compare_size(limit_type
, size
);
210 sm
= set_state_expr(size_id
, pointer
, state
);
213 add_link(size
, pointer
, mod_expr
);
216 static struct expression
*get_struct_size_count(struct expression
*expr
)
219 * There are three ways that struct_size() can be implemented but
220 * we can ignore build time constants so really there are two ways we
222 * 1) Using __ab_c_size()
223 * 2) Using size_add(struct_size, size_mul(elem_count, elem_size))
227 if (expr
->type
!= EXPR_CALL
)
230 if (sym_name_is("__ab_c_size", expr
->fn
))
231 return get_argument_from_call_expr(expr
->args
, 0);
233 if (!sym_name_is("size_add", expr
->fn
))
235 expr
= get_argument_from_call_expr(expr
->args
, 1);
236 expr
= strip_expr(expr
);
237 if (!expr
|| expr
->type
!= EXPR_CALL
||
238 !sym_name_is("size_mul", expr
->fn
))
241 return get_argument_from_call_expr(expr
->args
, 0);
244 static struct expression
*get_variable_struct_member(struct expression
*expr
)
246 struct symbol
*type
, *last_member
;
250 * This is a hack. It should look at how the size is calculated instead
251 * of just assuming that it's the last element. However, ugly hacks are
255 type
= get_type(expr
);
256 if (!type
|| type
->type
!= SYM_PTR
)
258 type
= get_real_base_type(type
);
259 if (!type
|| type
->type
!= SYM_STRUCT
)
261 last_member
= last_ptr_list((struct ptr_list
*)type
->symbol_list
);
262 if (!last_member
|| !last_member
->ident
)
264 type
= get_real_base_type(last_member
);
265 if (!type
|| type
->type
!= SYM_ARRAY
)
267 /* Is non-zero array size */
268 if (type
->array_size
) {
269 if (!get_implied_value(type
->array_size
, &sval
) ||
274 return member_expression(expr
, '*', last_member
->ident
);
277 static void match_struct_size_helper(struct expression
*pointer
, struct expression
*size
, struct expression
*mod_expr
)
279 struct expression
*tmp
, *count
, *member
;
280 struct smatch_state
*state
;
283 if (option_project
!= PROJ_KERNEL
)
286 pointer
= strip_expr(pointer
);
287 tmp
= get_assigned_expr_recurse(size
);
290 size
= strip_expr(size
);
291 if (!size
|| !pointer
)
293 count
= get_struct_size_count(size
);
296 member
= get_variable_struct_member(pointer
);
298 db_save_type_links(member
, ELEM_COUNT
, count
);
299 state
= alloc_compare_size(ELEM_COUNT
, count
);
300 sm
= set_state_expr(size_id
, member
, state
);
303 add_link(count
, member
, mod_expr
);
306 static void match_alloc(const char *fn
, struct expression
*expr
, void *_size_arg
)
308 int size_arg
= PTR_INT(_size_arg
);
309 struct expression
*pointer
, *call
, *arg
;
311 pointer
= strip_expr(expr
->left
);
312 call
= strip_expr(expr
->right
);
313 arg
= get_argument_from_call_expr(call
->args
, size_arg
);
314 match_alloc_helper(pointer
, arg
, expr
);
315 match_struct_size_helper(pointer
, arg
, expr
);
318 static void match_calloc(const char *fn
, struct expression
*expr
, void *_start_arg
)
320 struct smatch_state
*state
;
321 int start_arg
= PTR_INT(_start_arg
);
322 struct expression
*pointer
, *call
, *arg
;
323 struct sm_state
*tmp
;
324 int limit_type
= ELEM_COUNT
;
327 pointer
= strip_expr(expr
->left
);
328 call
= strip_expr(expr
->right
);
329 arg
= get_argument_from_call_expr(call
->args
, start_arg
);
330 if (get_implied_value(arg
, &sval
) &&
331 sval
.value
== bytes_per_element(pointer
))
332 arg
= get_argument_from_call_expr(call
->args
, start_arg
+ 1);
334 if (arg
->type
== EXPR_BINOP
&& arg
->op
== '+' &&
335 get_value(arg
->right
, &sval
) && sval
.value
== 1) {
337 limit_type
= ELEM_LAST
;
340 state
= alloc_compare_size(limit_type
, arg
);
341 db_save_type_links(pointer
, limit_type
, arg
);
342 tmp
= set_state_expr(size_id
, pointer
, state
);
345 add_link(arg
, pointer
, expr
);
348 static struct expression
*get_size_variable_from_binop(struct expression
*expr
, int *limit_type
)
350 struct smatch_state
*state
;
351 struct expression
*ret
;
357 if (!get_value(expr
->right
, &offset
))
359 state
= get_state_expr(size_id
, expr
->left
);
360 if (!state
|| !state
->data
)
363 type
= get_type(expr
->left
);
364 if (!type_is_ptr(type
))
366 type
= get_real_base_type(type
);
367 if (!type_bytes(type
))
369 offset_bytes
= offset
.value
* type_bytes(type
);
372 if (ret
->type
!= EXPR_BINOP
|| ret
->op
!= '+')
375 *limit_type
= state_to_limit(state
);
377 if (get_value(ret
->left
, &orig_fixed
) && orig_fixed
.value
== offset_bytes
)
379 if (get_value(ret
->right
, &orig_fixed
) && orig_fixed
.value
== offset_bytes
)
385 struct expression
*get_size_variable(struct expression
*buf
, int *limit_type
)
387 struct smatch_state
*state
;
388 struct expression
*ret
;
390 buf
= strip_expr(buf
);
393 if (buf
->type
== EXPR_BINOP
&& buf
->op
== '+') {
394 ret
= get_size_variable_from_binop(buf
, limit_type
);
399 state
= get_state_expr(size_id
, buf
);
402 *limit_type
= state_to_limit(state
);
406 struct expression
*get_array_variable(struct expression
*size
)
408 struct smatch_state
*state
;
410 state
= get_state_expr(link_id
, size
);
416 static void array_check(struct expression
*expr
)
418 struct expression
*array
;
419 struct expression
*size
;
420 struct expression
*offset
;
421 char *array_str
, *offset_str
;
424 expr
= strip_expr(expr
);
428 array
= get_array_base(expr
);
429 size
= get_size_variable(array
, &limit_type
);
432 if (limit_type
!= ELEM_COUNT
)
434 offset
= get_array_offset(expr
);
435 if (!possible_comparison(size
, SPECIAL_EQUAL
, offset
))
437 if (getting_address(expr
))
440 array_str
= expr_to_str(array
);
441 offset_str
= expr_to_str(offset
);
442 sm_warning("potentially one past the end of array '%s[%s]'", array_str
, offset_str
);
443 free_string(array_str
);
444 free_string(offset_str
);
452 static int db_limitter_callback(void *_info
, int argc
, char **argv
, char **azColName
)
454 struct db_info
*info
= _info
;
457 * If possible the limitters are tied to the struct they limit. If we
458 * aren't sure which struct they limit then we use them as limitters for
461 if (!info
->name
|| argv
[0][0] == '\0' || strcmp(info
->name
, argv
[0]) == 0)
466 static char *vsl_to_data_info_name(const char *name
, struct var_sym_list
*vsl
)
473 if (ptr_list_size((struct ptr_list
*)vsl
) != 1)
475 vs
= first_ptr_list((struct ptr_list
*)vsl
);
477 type
= get_real_base_type(vs
->sym
);
478 if (!type
|| type
->type
!= SYM_PTR
)
480 type
= get_real_base_type(type
);
481 if (!type
|| type
->type
!= SYM_STRUCT
)
487 while ((name
= strstr(p
, "->")))
490 snprintf(buf
, sizeof(buf
),"(struct %s)->%s", type
->ident
->name
, p
);
491 return alloc_sname(buf
);
494 if (!(vs
->sym
->ctype
.modifiers
& MOD_TOPLEVEL
))
496 if (vs
->sym
->ctype
.modifiers
& MOD_STATIC
)
497 snprintf(buf
, sizeof(buf
),"static %s", name
);
499 snprintf(buf
, sizeof(buf
),"global %s", name
);
500 return alloc_sname(buf
);
503 int db_var_is_array_limit(struct expression
*array
, const char *name
, struct var_sym_list
*vsl
)
506 char *array_name
= get_data_info_name(array
);
507 struct db_info db_info
= {.name
= array_name
,};
509 size_name
= vsl_to_data_info_name(name
, vsl
);
513 run_sql(db_limitter_callback
, &db_info
,
514 "select value from data_info where type = %d and data = '%s';",
515 ARRAY_LEN
, size_name
);
520 int buf_comparison_index_ok(struct expression
*expr
)
522 struct expression
*array
;
523 struct expression
*size
;
524 struct expression
*offset
;
528 array
= get_array_base(expr
);
529 size
= get_size_variable(array
, &limit_type
);
532 offset
= get_array_offset(expr
);
533 comparison
= get_comparison(offset
, size
);
537 if ((limit_type
== ELEM_COUNT
|| limit_type
== ELEM_LAST
) &&
538 (comparison
== '<' || comparison
== SPECIAL_UNSIGNED_LT
))
541 if (limit_type
== BYTE_COUNT
&& bytes_per_element(array
) == 1 &&
542 (comparison
== '<' || comparison
== SPECIAL_UNSIGNED_LT
))
545 if (limit_type
== ELEM_LAST
&&
546 (comparison
== SPECIAL_LTE
||
547 comparison
== SPECIAL_UNSIGNED_LTE
||
548 comparison
== SPECIAL_EQUAL
))
554 bool buf_comp_has_bytes(struct expression
*buf
, struct expression
*var
)
556 struct expression
*size
;
560 if (buf_comp2_has_bytes(buf
, var
))
563 size
= get_size_variable(buf
, &limit_type
);
566 comparison
= get_comparison(size
, var
);
567 if (comparison
== UNKNOWN_COMPARISON
||
568 comparison
== IMPOSSIBLE_COMPARISON
)
571 if (show_special(comparison
)[0] == '<' ||
572 show_special(comparison
)[0] == '=')
578 bool buf_has_bytes(struct expression
*buf
, struct expression
*var
)
580 struct range_list
*rl
;
583 size
= get_array_size_bytes_max(buf
);
584 get_absolute_rl(var
, &rl
);
586 get_implied_rl(var
, &rl
) &&
587 rl_min(rl
).value
<= size
)
590 return buf_comp_has_bytes(buf
, var
);
593 static int known_access_ok_numbers(struct expression
*expr
)
595 struct expression
*array
;
596 struct expression
*offset
;
600 array
= get_array_base(expr
);
601 offset
= get_array_offset(expr
);
603 size
= get_array_size(array
);
607 get_absolute_max(offset
, &max
);
608 if (max
.uvalue
< size
)
613 static void array_check_data_info(struct expression
*expr
)
615 struct expression
*array
;
616 struct expression
*offset
;
617 struct state_list
*slist
;
619 struct compare_data
*comp
;
621 const char *equal_name
= NULL
;
623 expr
= strip_expr(expr
);
627 if (known_access_ok_numbers(expr
))
629 if (buf_comparison_index_ok(expr
))
632 array
= get_array_base(expr
);
633 offset
= get_array_offset(expr
);
634 offset_name
= expr_to_var(offset
);
637 slist
= get_all_possible_equal_comparisons(offset
);
641 FOR_EACH_PTR(slist
, sm
) {
642 comp
= sm
->state
->data
;
643 if (strcmp(comp
->left_var
, offset_name
) == 0) {
644 if (db_var_is_array_limit(array
, comp
->right_var
, comp
->right_vsl
)) {
645 equal_name
= comp
->right_var
;
648 } else if (strcmp(comp
->right_var
, offset_name
) == 0) {
649 if (db_var_is_array_limit(array
, comp
->left_var
, comp
->left_vsl
)) {
650 equal_name
= comp
->left_var
;
654 } END_FOR_EACH_PTR(sm
);
657 char *array_name
= expr_to_str(array
);
659 sm_warning("potential off by one '%s[]' limit '%s'", array_name
, equal_name
);
660 free_string(array_name
);
665 free_string(offset_name
);
668 static void add_allocation_function(const char *func
, void *call_back
, int param
)
670 add_function_assign_hook(func
, call_back
, INT_PTR(param
));
673 static int is_sizeof(struct expression
*expr
)
677 if (expr
->type
== EXPR_SIZEOF
)
679 name
= pos_ident(expr
->pos
);
680 if (name
&& strcmp(name
, "sizeof") == 0)
685 static int match_size_binop(struct expression
*size
, struct expression
*expr
, int *limit_type
)
687 int orig_type
= *limit_type
;
688 struct expression
*left
;
692 if (!expr_equiv(size
, left
))
695 if (expr
->op
== '-' &&
696 get_value(expr
->right
, &sval
) &&
698 orig_type
== ELEM_COUNT
) {
699 *limit_type
= ELEM_LAST
;
703 if (expr
->op
== '+' &&
704 get_value(expr
->right
, &sval
) &&
706 orig_type
== ELEM_LAST
) {
707 *limit_type
= ELEM_COUNT
;
711 if (expr
->op
== '*' &&
712 is_sizeof(expr
->right
) &&
713 orig_type
== ELEM_COUNT
) {
714 *limit_type
= BYTE_COUNT
;
718 if (expr
->op
== '/' &&
719 is_sizeof(expr
->right
) &&
720 orig_type
== BYTE_COUNT
) {
721 *limit_type
= ELEM_COUNT
;
728 static char *buf_size_param_comparison(struct expression
*array
, struct expression_list
*args
, int *limit_type
)
730 struct expression
*tmp
, *arg
;
731 struct expression
*size
;
735 size
= get_size_variable(array
, limit_type
);
739 if (*limit_type
== USED_LAST
)
740 *limit_type
= ELEM_LAST
;
741 if (*limit_type
== USED_COUNT
)
742 *limit_type
= ELEM_COUNT
;
745 FOR_EACH_PTR(args
, tmp
) {
750 if (expr_equiv(arg
, size
) ||
751 (arg
->type
== EXPR_BINOP
&&
752 match_size_binop(size
, arg
, limit_type
))) {
753 snprintf(buf
, sizeof(buf
), "==$%d", i
);
756 } END_FOR_EACH_PTR(tmp
);
761 static void match_call(struct expression
*call
)
763 struct expression
*arg
;
770 FOR_EACH_PTR(call
->args
, arg
) {
772 if (!is_pointer(arg
))
774 compare
= buf_size_param_comparison(arg
, call
->args
, &limit_type
);
777 snprintf(buf
, sizeof(buf
), "%d", limit_type
);
778 sql_insert_caller_info(call
, limit_type
, param
, compare
, buf
);
779 } END_FOR_EACH_PTR(arg
);
782 static int get_param(int param
, char **name
, struct symbol
**sym
)
788 FOR_EACH_PTR(cur_func_sym
->ctype
.base_type
->arguments
, arg
) {
790 * this is a temporary hack to work around a bug (I think in sparse?)
791 * 2.6.37-rc1:fs/reiserfs/journal.o
792 * If there is a function definition without parameter name found
793 * after a function implementation then it causes a crash.
797 if (arg
->ident
->name
< (char *)100)
800 *name
= arg
->ident
->name
;
805 } END_FOR_EACH_PTR(arg
);
810 static void set_param_compare(const char *array_name
, struct symbol
*array_sym
, char *key
, char *value
)
812 struct smatch_state
*state
;
813 struct expression
*array_expr
;
814 struct expression
*size_expr
;
815 struct symbol
*size_sym
;
818 struct sm_state
*tmp
;
821 if (strncmp(key
, "==$", 3) != 0)
823 param
= strtol(key
+ 3, NULL
, 10);
824 if (!get_param(param
, &size_name
, &size_sym
))
826 array_expr
= symbol_expression(array_sym
);
827 size_expr
= symbol_expression(size_sym
);
828 limit_type
= strtol(value
, NULL
, 10);
830 state
= alloc_compare_size(limit_type
, size_expr
);
831 tmp
= set_state_expr(size_id
, array_expr
, state
);
834 add_link(size_expr
, array_expr
, NULL
);
837 static void set_implied(struct expression
*call
, struct expression
*array_expr
, char *key
, char *value
)
839 struct expression
*size_expr
;
840 struct symbol
*size_sym
;
843 struct sm_state
*tmp
;
846 if (strncmp(key
, "==$", 3) != 0)
848 param
= strtol(key
+ 3, NULL
, 10);
849 if (!get_param(param
, &size_name
, &size_sym
))
851 size_expr
= symbol_expression(size_sym
);
853 limit_type
= strtol(value
, NULL
, 10);
854 tmp
= set_state_expr(size_id
, array_expr
, alloc_compare_size(limit_type
, size_expr
));
857 add_link(size_expr
, array_expr
, call
);
860 static void munge_start_states(struct statement
*stmt
)
862 struct state_list
*slist
= NULL
;
864 struct sm_state
*poss
;
866 FOR_EACH_MY_SM(size_id
, __get_cur_stree(), sm
) {
867 if (sm
->state
!= &merged
)
870 * screw it. let's just assume that if one caller passes the
871 * size then they all do.
873 FOR_EACH_PTR(sm
->possible
, poss
) {
874 if (poss
->state
!= &merged
&&
875 poss
->state
!= &undefined
) {
876 add_ptr_list(&slist
, poss
);
879 } END_FOR_EACH_PTR(poss
);
880 } END_FOR_EACH_SM(sm
);
882 FOR_EACH_PTR(slist
, sm
) {
883 set_state(size_id
, sm
->name
, sm
->sym
, sm
->state
);
884 } END_FOR_EACH_PTR(sm
);
889 static void set_used(struct expression
*expr
)
891 struct expression
*parent
;
892 struct expression
*array
;
893 struct expression
*offset
;
894 struct sm_state
*tmp
;
897 if (expr
->op
!= SPECIAL_INCREMENT
)
900 limit_type
= USED_LAST
;
901 if (expr
->type
== EXPR_POSTOP
)
902 limit_type
= USED_COUNT
;
904 parent
= expr_get_parent_expr(expr
);
905 if (!parent
|| parent
->type
!= EXPR_BINOP
)
907 parent
= expr_get_parent_expr(parent
);
908 if (!parent
|| !is_array(parent
))
911 array
= get_array_base(parent
);
912 offset
= get_array_offset(parent
);
916 tmp
= set_state_expr(size_id
, array
, alloc_compare_size(limit_type
, offset
->unop
));
919 add_link(offset
->unop
, array
, expr
);
922 static int match_assign_array(struct expression
*expr
)
928 static int match_assign_size(struct expression
*expr
)
930 struct expression
*right
, *size
, *array
;
931 struct smatch_state
*state
;
932 struct sm_state
*tmp
;
937 if (size
->type
== EXPR_BINOP
)
940 array
= get_array_variable(size
);
943 state
= get_state_expr(size_id
, array
);
944 if (!state
|| !state
->data
)
947 limit_type
= state_to_limit(state
);
951 if (right
->type
== EXPR_BINOP
&& !match_size_binop(size
, right
, &limit_type
))
954 tmp
= set_state_expr(size_id
, array
, alloc_compare_size(limit_type
, expr
->left
));
957 add_link(expr
->left
, array
, expr
);
961 static bool match_assign_smaller(struct expression
*expr
)
963 struct expression
*array
;
967 array
= get_array_variable(expr
->left
);
971 if (get_value(expr
->right
, &sval
))
974 comparison
= get_comparison(expr
->left
, expr
->right
);
975 if (comparison
== UNKNOWN_COMPARISON
||
976 comparison
== IMPOSSIBLE_COMPARISON
)
979 /* This is assigning a smaller value to the variable than what it was. */
980 if (show_special(comparison
)[0] != '>')
984 * This module doesn't have a way to say that it's less than the limit
985 * only that it *is* the limit. So you might expect to set a state here
986 * but there is already a state so all we can do is ignore the
989 ignore_link_mod
= expr
;
993 static void match_assign(struct expression
*expr
)
998 if (is_fake_var_assign(expr
))
1001 if (match_assign_array(expr
))
1003 if (match_assign_size(expr
))
1005 if (match_assign_smaller(expr
))
1009 static void match_copy(const char *fn
, struct expression
*expr
, void *unused
)
1011 struct expression
*src
, *size
;
1012 int src_param
, size_param
;
1014 src
= get_argument_from_call_expr(expr
->args
, 1);
1015 size
= get_argument_from_call_expr(expr
->args
, 2);
1016 src
= strip_expr(src
);
1017 size
= strip_expr(size
);
1020 if (src
->type
!= EXPR_SYMBOL
|| size
->type
!= EXPR_SYMBOL
)
1023 src_param
= get_param_num_from_sym(src
->symbol
);
1024 size_param
= get_param_num_from_sym(size
->symbol
);
1025 if (src_param
< 0 || size_param
< 0)
1028 sql_insert_cache(call_implies
, "'%s', '%s', 0, %d, %d, %d, '==$%d', '%d'",
1029 get_base_file(), get_function(), fn_static(),
1030 BYTE_COUNT
, src_param
, size_param
, BYTE_COUNT
);
1033 void register_buf_comparison(int id
)
1039 set_dynamic_states(size_id
);
1041 add_unmatched_state_hook(size_id
, &unmatched_state
);
1043 add_allocation_function("malloc", &match_alloc
, 0);
1044 add_allocation_function("memdup", &match_alloc
, 1);
1045 add_allocation_function("realloc", &match_alloc
, 1);
1046 if (option_project
== PROJ_KERNEL
) {
1047 add_allocation_function("kmalloc", &match_alloc
, 0);
1048 add_allocation_function("kzalloc", &match_alloc
, 0);
1049 add_allocation_function("vmalloc", &match_alloc
, 0);
1050 add_allocation_function("__vmalloc", &match_alloc
, 0);
1051 add_allocation_function("sock_kmalloc", &match_alloc
, 1);
1052 add_allocation_function("kmemdup", &match_alloc
, 1);
1053 add_allocation_function("memdup_user", &match_alloc
, 1);
1054 add_allocation_function("dma_alloc_attrs", &match_alloc
, 1);
1055 add_allocation_function("dma_alloc_coherent", &match_alloc
, 1);
1056 add_allocation_function("devm_kmalloc", &match_alloc
, 1);
1057 add_allocation_function("devm_kzalloc", &match_alloc
, 1);
1058 add_allocation_function("kcalloc", &match_calloc
, 0);
1059 add_allocation_function("devm_kcalloc", &match_calloc
, 1);
1060 add_allocation_function("kmalloc_array", &match_calloc
, 0);
1061 add_allocation_function("krealloc", &match_alloc
, 1);
1063 add_function_hook("copy_from_user", &match_copy
, NULL
);
1064 add_function_hook("__copy_from_user", &match_copy
, NULL
);
1067 add_hook(&array_check
, OP_HOOK
);
1068 add_hook(&array_check_data_info
, OP_HOOK
);
1069 add_hook(&set_used
, OP_HOOK
);
1071 add_hook(&match_call
, FUNCTION_CALL_HOOK
);
1072 add_hook(&munge_start_states
, AFTER_DEF_HOOK
);
1074 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
1076 for (i
= BYTE_COUNT
; i
<= USED_COUNT
; i
++) {
1077 select_call_implies_hook(i
, &set_implied
);
1078 select_caller_info_hook(set_param_compare
, i
);
1079 select_return_implies_hook(i
, &set_implied
);
1083 void register_buf_comparison_links(int id
)
1086 set_dynamic_states(link_id
);
1087 add_merge_hook(link_id
, &merge_links
);
1088 add_modification_hook_late(link_id
, &match_link_modify
);