2 * Copyright (C) 2011 Dan Carpenter.
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 * There are a couple checks that try to see if a variable
20 * comes from the user. It would be better to unify them
21 * into one place. Also it we should follow the data down
22 * the call paths. Hence this file.
26 #include "smatch_slist.h"
27 #include "smatch_extra.h"
30 static int my_call_id
;
33 static bool func_gets_user_data
;
35 static const char *kstr_funcs
[] = {
36 "kstrtoull", "kstrtoll", "kstrtoul", "kstrtol", "kstrtouint",
37 "kstrtoint", "kstrtou64", "kstrtos64", "kstrtou32", "kstrtos32",
38 "kstrtou16", "kstrtos16", "kstrtou8", "kstrtos8", "kstrtoull_from_user"
39 "kstrtoll_from_user", "kstrtoul_from_user", "kstrtol_from_user",
40 "kstrtouint_from_user", "kstrtoint_from_user", "kstrtou16_from_user",
41 "kstrtos16_from_user", "kstrtou8_from_user", "kstrtos8_from_user",
42 "kstrtou64_from_user", "kstrtos64_from_user", "kstrtou32_from_user",
43 "kstrtos32_from_user",
46 static const char *returns_user_data
[] = {
47 "simple_strtol", "simple_strtoll", "simple_strtoul", "simple_strtoull",
51 static const char *returns_pointer_to_user_data
[] = {
52 "nlmsg_data", "nla_data", "memdup_user", "kmap_atomic", "skb_network_header",
55 static void set_points_to_user_data(struct expression
*expr
);
57 static struct stree
*start_states
;
58 static struct stree_stack
*saved_stack
;
59 static void save_start_states(struct statement
*stmt
)
61 start_states
= clone_stree(__get_cur_stree());
64 static void free_start_states(void)
66 free_stree(&start_states
);
69 static void match_save_states(struct expression
*expr
)
71 push_stree(&saved_stack
, start_states
);
75 static void match_restore_states(struct expression
*expr
)
77 free_stree(&start_states
);
78 start_states
= pop_stree(&saved_stack
);
81 static struct smatch_state
*empty_state(struct sm_state
*sm
)
83 return alloc_estate_empty();
86 static void pre_merge_hook(struct sm_state
*sm
)
88 struct smatch_state
*user
;
89 struct smatch_state
*extra
;
90 struct range_list
*rl
;
93 user
= get_state(my_id
, sm
->name
, sm
->sym
);
94 if (!user
|| !estate_rl(user
))
97 if (!__in_function_def
&& !estate_rl(sm
->state
)) {
98 /* The situation here looks like:
100 * if (user_var > trusted)
101 * user_var = trusted; <-- empty state
103 * <-- capped (but to an unknown)
105 * The one side is capped and the other side is set to an
106 * unknown limit. In that case, we want to set the capped side
109 * The difficulty lies in knowing that the limit is unknown
110 * because we just have a binary capped vs uncapped. Also the
111 * API doesn't let us select the extra state from the other
115 max
= estate_max(user
);
117 if (is_capped_var_sym(sm
->name
, sm
->sym
) && sval_is_a_max(max
)) {
118 set_state(my_id
, sm
->name
, sm
->sym
, alloc_estate_empty());
122 extra
= get_state(SMATCH_EXTRA
, sm
->name
, sm
->sym
);
125 rl
= rl_intersection(estate_rl(user
), estate_rl(extra
));
126 if (rl_to_sval(rl
, &dummy
))
128 set_state(my_id
, sm
->name
, sm
->sym
, alloc_estate_rl(clone_rl(rl
)));
131 static void extra_nomod_hook(const char *name
, struct symbol
*sym
, struct expression
*expr
, struct smatch_state
*state
)
133 struct smatch_state
*user
;
134 struct range_list
*rl
;
136 user
= get_state(my_id
, name
, sym
);
139 rl
= rl_intersection(estate_rl(user
), estate_rl(state
));
140 if (rl_equiv(rl
, estate_rl(user
)))
142 set_state(my_id
, name
, sym
, alloc_estate_rl(rl
));
145 static void tag_inner_struct_members(struct expression
*expr
, struct symbol
*member
)
147 struct expression
*edge_member
;
148 struct symbol
*base
= get_real_base_type(member
);
152 expr
= member_expression(expr
, '.', member
->ident
);
154 FOR_EACH_PTR(base
->symbol_list
, tmp
) {
157 type
= get_real_base_type(tmp
);
161 if (type
->type
== SYM_UNION
|| type
->type
== SYM_STRUCT
) {
162 tag_inner_struct_members(expr
, tmp
);
169 edge_member
= member_expression(expr
, '.', tmp
->ident
);
170 set_state_expr(my_id
, edge_member
, alloc_estate_whole(type
));
171 } END_FOR_EACH_PTR(tmp
);
174 static void tag_struct_members(struct symbol
*type
, struct expression
*expr
)
177 struct expression
*member
;
180 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '&') {
181 expr
= strip_expr(expr
->unop
);
185 FOR_EACH_PTR(type
->symbol_list
, tmp
) {
186 type
= get_real_base_type(tmp
);
190 if (type
->type
== SYM_UNION
|| type
->type
== SYM_STRUCT
) {
191 tag_inner_struct_members(expr
, tmp
);
198 member
= member_expression(expr
, op
, tmp
->ident
);
199 set_state_expr(my_id
, member
, alloc_estate_whole(get_type(member
)));
201 if (type
->type
== SYM_ARRAY
)
202 set_points_to_user_data(member
);
203 } END_FOR_EACH_PTR(tmp
);
206 static void tag_base_type(struct expression
*expr
)
208 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '&')
209 expr
= strip_expr(expr
->unop
);
211 expr
= deref_expression(expr
);
212 set_state_expr(my_id
, expr
, alloc_estate_whole(get_type(expr
)));
215 static void tag_as_user_data(struct expression
*expr
)
219 expr
= strip_expr(expr
);
221 type
= get_type(expr
);
222 if (!type
|| type
->type
!= SYM_PTR
)
224 type
= get_real_base_type(type
);
227 if (type
== &void_ctype
) {
228 set_state_expr(my_id
, deref_expression(expr
), alloc_estate_whole(&ulong_ctype
));
231 if (type
->type
== SYM_BASETYPE
)
233 if (type
->type
== SYM_STRUCT
|| type
->type
== SYM_UNION
) {
234 if (expr
->type
!= EXPR_PREOP
|| expr
->op
!= '&')
235 expr
= deref_expression(expr
);
237 set_state_expr(my_id
, deref_expression(expr
), alloc_estate_whole(&ulong_ctype
));
238 tag_struct_members(type
, expr
);
242 static void match_user_copy(const char *fn
, struct expression
*expr
, void *_param
)
244 int param
= PTR_INT(_param
);
245 struct expression
*dest
;
247 func_gets_user_data
= true;
249 dest
= get_argument_from_call_expr(expr
->args
, param
);
250 dest
= strip_expr(dest
);
253 tag_as_user_data(dest
);
256 static int is_dev_attr_name(struct expression
*expr
)
261 name
= expr_to_str(expr
);
264 if (strstr(name
, "->attr.name"))
270 static int ends_in_n(struct expression
*expr
)
276 if (expr
->type
!= EXPR_STRING
|| !expr
->string
)
283 if (str
->data
[str
->length
- 3] == '%' &&
284 str
->data
[str
->length
- 2] == 'n')
289 static void match_sscanf(const char *fn
, struct expression
*expr
, void *unused
)
291 struct expression
*str
, *format
, *arg
;
294 func_gets_user_data
= true;
296 str
= get_argument_from_call_expr(expr
->args
, 0);
297 if (is_dev_attr_name(str
))
300 format
= get_argument_from_call_expr(expr
->args
, 1);
301 if (is_dev_attr_name(format
))
304 last
= ptr_list_size((struct ptr_list
*)expr
->args
) - 1;
307 FOR_EACH_PTR(expr
->args
, arg
) {
311 if (i
== last
&& ends_in_n(format
))
313 tag_as_user_data(arg
);
314 } END_FOR_EACH_PTR(arg
);
317 static int is_skb_data(struct expression
*expr
)
324 if (expr
->type
== EXPR_BINOP
&& expr
->op
== '+')
325 return is_skb_data(expr
->left
);
327 expr
= strip_expr(expr
);
330 if (expr
->type
!= EXPR_DEREF
|| expr
->op
!= '.')
335 if (strcmp(expr
->member
->name
, "data") != 0)
338 sym
= expr_to_sym(expr
->deref
);
341 sym
= get_real_base_type(sym
);
342 if (!sym
|| sym
->type
!= SYM_PTR
)
344 sym
= get_real_base_type(sym
);
345 if (!sym
|| sym
->type
!= SYM_STRUCT
|| !sym
->ident
)
347 if (strcmp(sym
->ident
->name
, "sk_buff") != 0)
353 static bool is_points_to_user_data_fn(struct expression
*expr
)
357 expr
= strip_expr(expr
);
358 if (expr
->type
!= EXPR_CALL
|| expr
->fn
->type
!= EXPR_SYMBOL
||
362 for (i
= 0; i
< ARRAY_SIZE(returns_pointer_to_user_data
); i
++) {
363 if (sym_name_is(returns_pointer_to_user_data
[i
], expr
))
369 static int get_rl_from_function(struct expression
*expr
, struct range_list
**rl
)
373 if (expr
->type
!= EXPR_CALL
|| expr
->fn
->type
!= EXPR_SYMBOL
||
374 !expr
->fn
->symbol_name
|| !expr
->fn
->symbol_name
->name
)
377 for (i
= 0; i
< ARRAY_SIZE(returns_user_data
); i
++) {
378 if (strcmp(expr
->fn
->symbol_name
->name
, returns_user_data
[i
]) == 0) {
379 *rl
= alloc_whole_rl(get_type(expr
));
386 int points_to_user_data(struct expression
*expr
)
388 struct smatch_state
*state
;
389 struct range_list
*rl
;
395 expr
= strip_expr(expr
);
398 if (is_skb_data(expr
))
400 if (is_points_to_user_data_fn(expr
))
402 if (get_rl_from_function(expr
, &rl
))
405 if (expr
->type
== EXPR_BINOP
&& expr
->op
== '+') {
406 if (points_to_user_data(expr
->left
))
408 if (points_to_user_data(expr
->right
))
413 name
= expr_to_var_sym(expr
, &sym
);
416 snprintf(buf
, sizeof(buf
), "*%s", name
);
417 state
= get_state(my_id
, buf
, sym
);
418 if (state
&& estate_rl(state
))
425 static void set_points_to_user_data(struct expression
*expr
)
432 name
= expr_to_var_sym(expr
, &sym
);
435 snprintf(buf
, sizeof(buf
), "*%s", name
);
436 type
= get_type(expr
);
437 if (type
&& type
->type
== SYM_PTR
)
438 type
= get_real_base_type(type
);
439 if (!type
|| type
->type
!= SYM_BASETYPE
)
441 set_state(my_id
, buf
, sym
, alloc_estate_whole(type
));
446 static int comes_from_skb_data(struct expression
*expr
)
448 expr
= strip_expr(expr
);
449 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
452 expr
= strip_expr(expr
->unop
);
455 if (expr
->type
== EXPR_BINOP
&& expr
->op
== '+')
456 expr
= strip_expr(expr
->left
);
458 return is_skb_data(expr
);
461 static int handle_struct_assignment(struct expression
*expr
)
463 struct expression
*right
;
464 struct symbol
*left_type
, *right_type
;
466 left_type
= get_type(expr
->left
);
467 if (!left_type
|| left_type
->type
!= SYM_PTR
)
469 left_type
= get_real_base_type(left_type
);
472 if (left_type
->type
!= SYM_STRUCT
&&
473 left_type
->type
!= SYM_UNION
)
477 * Ignore struct to struct assignments because for those we look at the
478 * individual members.
480 right
= strip_expr(expr
->right
);
481 right_type
= get_type(right
);
482 if (!right_type
|| right_type
->type
!= SYM_PTR
)
485 /* If we are assigning struct members then normally that is handled
486 * by fake assignments, however if we cast one struct to a different
487 * of struct then we handle that here.
489 right_type
= get_real_base_type(right_type
);
490 if (right_type
== left_type
)
493 if (!points_to_user_data(right
))
496 tag_as_user_data(expr
->left
);
500 static int handle_get_user(struct expression
*expr
)
505 name
= get_macro_name(expr
->pos
);
506 if (!name
|| strcmp(name
, "get_user") != 0)
509 name
= expr_to_var(expr
->right
);
510 if (!name
|| strcmp(name
, "__val_gu") != 0)
512 set_state_expr(my_id
, expr
->left
, alloc_estate_whole(get_type(expr
->left
)));
519 static void match_assign(struct expression
*expr
)
521 struct range_list
*rl
;
522 static struct expression
*handled
;
523 struct expression
*faked
;
525 faked
= get_faked_expression();
526 if (faked
&& faked
== handled
)
528 if (is_fake_call(expr
->right
))
529 goto clear_old_state
;
530 if (handle_get_user(expr
))
532 if (points_to_user_data(expr
->right
)) {
534 set_points_to_user_data(expr
->left
);
536 if (handle_struct_assignment(expr
))
539 if (!get_user_rl(expr
->right
, &rl
))
540 goto clear_old_state
;
542 rl
= cast_rl(get_type(expr
->left
), rl
);
543 set_state_expr(my_id
, expr
->left
, alloc_estate_rl(rl
));
548 if (get_state_expr(my_id
, expr
->left
))
549 set_state_expr(my_id
, expr
->left
, alloc_estate_empty());
552 static void handle_eq_noteq(struct expression
*expr
)
554 struct smatch_state
*left_orig
, *right_orig
;
556 left_orig
= get_state_expr(my_id
, expr
->left
);
557 right_orig
= get_state_expr(my_id
, expr
->right
);
559 if (!left_orig
&& !right_orig
)
561 if (left_orig
&& right_orig
)
565 set_true_false_states_expr(my_id
, expr
->left
,
566 expr
->op
== SPECIAL_EQUAL
? alloc_estate_empty() : NULL
,
567 expr
->op
== SPECIAL_EQUAL
? NULL
: alloc_estate_empty());
569 set_true_false_states_expr(my_id
, expr
->right
,
570 expr
->op
== SPECIAL_EQUAL
? alloc_estate_empty() : NULL
,
571 expr
->op
== SPECIAL_EQUAL
? NULL
: alloc_estate_empty());
575 static void handle_unsigned_lt_gt(struct expression
*expr
)
578 struct range_list
*left
;
579 struct range_list
*right
;
580 struct range_list
*non_negative
;
581 sval_t min
, minus_one
;
584 * conditions are mostly handled by smatch_extra.c. The special case
585 * here is that say you have if (user_int < unknown_u32) {
586 * In Smatch extra we say that, We have no idea what value
587 * unknown_u32 is so the only thin we can say for sure is that
588 * user_int is not -1 (UINT_MAX). But in check_user_data2.c we should
589 * assume that unless unknown_u32 is user data, it's probably less than
594 type
= get_type(expr
);
595 if (!type_unsigned(type
))
599 * Assume if (user < trusted) { ... because I am lazy and because this
600 * is the correct way to write code.
602 if (!get_user_rl(expr
->left
, &left
))
604 if (get_user_rl(expr
->right
, &right
))
607 if (!sval_is_negative(rl_min(left
)))
610 minus_one
.type
= rl_type(left
);
611 minus_one
.value
= -1;
612 non_negative
= remove_range(left
, min
, minus_one
);
616 case SPECIAL_UNSIGNED_LT
:
618 case SPECIAL_UNSIGNED_LTE
:
619 set_true_false_states_expr(my_id
, expr
->left
,
620 alloc_estate_rl(non_negative
), NULL
);
623 case SPECIAL_UNSIGNED_GT
:
625 case SPECIAL_UNSIGNED_GTE
:
626 set_true_false_states_expr(my_id
, expr
->left
,
627 NULL
, alloc_estate_rl(non_negative
));
632 static void match_condition(struct expression
*expr
)
634 if (expr
->type
!= EXPR_COMPARE
)
637 if (expr
->op
== SPECIAL_EQUAL
||
638 expr
->op
== SPECIAL_NOTEQUAL
) {
639 handle_eq_noteq(expr
);
643 handle_unsigned_lt_gt(expr
);
646 static void match_user_assign_function(const char *fn
, struct expression
*expr
, void *unused
)
648 tag_as_user_data(expr
->left
);
649 set_points_to_user_data(expr
->left
);
652 static void match_returns_user_rl(const char *fn
, struct expression
*expr
, void *unused
)
654 func_gets_user_data
= true;
657 static int get_user_macro_rl(struct expression
*expr
, struct range_list
**rl
)
659 struct expression
*parent
;
665 macro
= get_macro_name(expr
->pos
);
669 /* handle ntohl(foo[i]) where "i" is trusted */
670 parent
= expr_get_parent_expr(expr
);
671 while (parent
&& parent
->type
!= EXPR_BINOP
)
672 parent
= expr_get_parent_expr(parent
);
673 if (parent
&& parent
->type
== EXPR_BINOP
) {
674 char *parent_macro
= get_macro_name(parent
->pos
);
676 if (parent_macro
&& strcmp(macro
, parent_macro
) == 0)
680 if (strcmp(macro
, "ntohl") == 0) {
681 *rl
= alloc_whole_rl(&uint_ctype
);
684 if (strcmp(macro
, "ntohs") == 0) {
685 *rl
= alloc_whole_rl(&ushort_ctype
);
692 struct range_list
*rl
;
693 struct expression
*call
;
695 static int returned_rl_callback(void *_info
, int argc
, char **argv
, char **azColName
)
697 struct db_info
*db_info
= _info
;
698 struct range_list
*rl
;
699 char *return_ranges
= argv
[0];
700 char *user_ranges
= argv
[1];
701 struct expression
*arg
;
707 call_results_to_rl(db_info
->call
, get_type(db_info
->call
), user_ranges
, &rl
);
708 if (str_to_comparison_arg(return_ranges
, db_info
->call
, &comparison
, &arg
) &&
709 comparison
== SPECIAL_EQUAL
) {
710 struct range_list
*orig_rl
;
712 if (!get_user_rl(arg
, &orig_rl
))
714 rl
= rl_intersection(rl
, orig_rl
);
718 db_info
->rl
= rl_union(db_info
->rl
, rl
);
723 static int has_user_data(struct symbol
*sym
)
725 struct sm_state
*tmp
;
727 FOR_EACH_MY_SM(my_id
, __get_cur_stree(), tmp
) {
730 } END_FOR_EACH_SM(tmp
);
734 static int we_pass_user_data(struct expression
*call
)
736 struct expression
*arg
;
739 FOR_EACH_PTR(call
->args
, arg
) {
740 sym
= expr_to_sym(arg
);
743 if (has_user_data(sym
))
745 } END_FOR_EACH_PTR(arg
);
750 static int db_returned_user_rl(struct expression
*call
, struct range_list
**rl
)
752 struct db_info db_info
= {};
754 /* for function pointers assume everything is used */
755 if (call
->fn
->type
!= EXPR_SYMBOL
|| !call
->fn
->symbol
)
757 if (is_fake_call(call
))
761 run_sql(&returned_rl_callback
, &db_info
,
762 "select return, value from return_states where %s and type = %d and parameter = -1 and key = '$';",
763 get_static_filter(call
->fn
->symbol
), USER_DATA3_SET
);
765 func_gets_user_data
= true;
770 run_sql(&returned_rl_callback
, &db_info
,
771 "select return, value from return_states where %s and type = %d and parameter = -1 and key = '$';",
772 get_static_filter(call
->fn
->symbol
), USER_DATA3
);
774 if (!we_pass_user_data(call
))
783 struct stree
*get_user_stree(void)
785 return get_all_states_stree(my_id
);
788 static int user_data_flag
;
789 static int no_user_data_flag
;
790 static struct range_list
*var_user_rl(struct expression
*expr
)
792 struct smatch_state
*state
;
793 struct range_list
*rl
;
794 struct range_list
*absolute_rl
;
796 if (expr
->type
== EXPR_BINOP
&& expr
->op
== '%') {
797 struct range_list
*left
, *right
;
799 if (!get_user_rl(expr
->right
, &right
))
801 get_absolute_rl(expr
->left
, &left
);
802 rl
= rl_binop(left
, '%', right
);
806 if (!option_spammy
&& expr
->type
== EXPR_BINOP
&& expr
->op
== '/') {
807 struct range_list
*left
= NULL
;
808 struct range_list
*right
= NULL
;
809 struct range_list
*abs_right
;
812 * The specific bug I'm dealing with is:
814 * foo = capped_user / unknown;
816 * Instead of just saying foo is now entirely user_rl we should
817 * probably say instead that it is not at all user data.
821 get_user_rl(expr
->left
, &left
);
822 get_user_rl(expr
->right
, &right
);
823 get_absolute_rl(expr
->right
, &abs_right
);
825 if (left
&& !right
) {
826 rl
= rl_binop(left
, '/', abs_right
);
827 if (sval_cmp(rl_max(left
), rl_max(rl
)) < 0)
828 no_user_data_flag
= 1;
834 if (get_rl_from_function(expr
, &rl
))
837 if (get_user_macro_rl(expr
, &rl
))
840 if (comes_from_skb_data(expr
)) {
841 rl
= alloc_whole_rl(get_type(expr
));
845 state
= get_state_expr(my_id
, expr
);
846 if (state
&& estate_rl(state
)) {
847 rl
= estate_rl(state
);
851 if (expr
->type
== EXPR_CALL
&& db_returned_user_rl(expr
, &rl
))
854 if (is_array(expr
)) {
855 struct expression
*array
= get_array_base(expr
);
857 if (!get_state_expr(my_id
, array
)) {
858 no_user_data_flag
= 1;
863 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '*' &&
864 is_user_rl(expr
->unop
)) {
865 rl
= var_to_absolute_rl(expr
);
872 absolute_rl
= var_to_absolute_rl(expr
);
873 return clone_rl(rl_intersection(rl
, absolute_rl
));
876 int get_user_rl(struct expression
*expr
, struct range_list
**rl
)
879 no_user_data_flag
= 0;
880 custom_get_absolute_rl(expr
, &var_user_rl
, rl
);
881 if (!user_data_flag
|| no_user_data_flag
)
887 int get_user_rl_spammy(struct expression
*expr
, struct range_list
**rl
)
892 ret
= get_user_rl(expr
, rl
);
898 int is_user_rl(struct expression
*expr
)
900 struct range_list
*tmp
;
902 return get_user_rl_spammy(expr
, &tmp
);
905 int get_user_rl_var_sym(const char *name
, struct symbol
*sym
, struct range_list
**rl
)
907 struct smatch_state
*state
;
909 state
= get_state(my_id
, name
, sym
);
910 if (state
&& estate_rl(state
)) {
911 *rl
= estate_rl(state
);
917 static void match_call_info(struct expression
*expr
)
919 struct range_list
*rl
;
920 struct expression
*arg
;
925 FOR_EACH_PTR(expr
->args
, arg
) {
927 type
= get_arg_type(expr
->fn
, i
);
929 if (!get_user_rl(arg
, &rl
))
932 rl
= cast_rl(type
, rl
);
933 sql_insert_caller_info(expr
, USER_DATA3
, i
, "$", show_rl(rl
));
934 } END_FOR_EACH_PTR(arg
);
937 static int is_struct_ptr(struct symbol
*sym
)
943 type
= get_real_base_type(sym
);
944 if (!type
|| type
->type
!= SYM_PTR
)
946 type
= get_real_base_type(type
);
947 if (!type
|| type
->type
!= SYM_STRUCT
)
952 static void struct_member_callback(struct expression
*call
, int param
, char *printed_name
, struct sm_state
*sm
)
954 struct smatch_state
*state
;
955 struct range_list
*rl
;
959 * Smatch uses a hack where if we get an unsigned long we say it's
960 * both user data and it points to user data. But if we pass it to a
961 * function which takes an int, then it's just user data. There's not
962 * enough bytes for it to be a pointer.
965 type
= get_arg_type(call
->fn
, param
);
966 if (type
&& type_bits(type
) < type_bits(&ptr_ctype
))
969 if (strcmp(sm
->state
->name
, "") == 0)
972 if (strcmp(printed_name
, "*$") == 0 &&
973 is_struct_ptr(sm
->sym
))
976 state
= get_state(SMATCH_EXTRA
, sm
->name
, sm
->sym
);
977 if (!state
|| !estate_rl(state
))
978 rl
= estate_rl(sm
->state
);
980 rl
= rl_intersection(estate_rl(sm
->state
), estate_rl(state
));
982 sql_insert_caller_info(call
, USER_DATA3
, param
, printed_name
, show_rl(rl
));
985 static void set_param_user_data(const char *name
, struct symbol
*sym
, char *key
, char *value
)
987 struct range_list
*rl
= NULL
;
988 struct smatch_state
*state
;
992 if (strcmp(key
, "*$") == 0)
993 snprintf(fullname
, sizeof(fullname
), "*%s", name
);
994 else if (strncmp(key
, "$", 1) == 0)
995 snprintf(fullname
, 256, "%s%s", name
, key
+ 1);
999 type
= get_member_type_from_key(symbol_expression(sym
), key
);
1001 /* if the caller passes a void pointer with user data */
1002 if (strcmp(key
, "*$") == 0 && type
&& type
!= &void_ctype
) {
1003 struct expression
*expr
= symbol_expression(sym
);
1005 tag_as_user_data(expr
);
1006 set_points_to_user_data(expr
);
1009 str_to_rl(type
, value
, &rl
);
1010 state
= alloc_estate_rl(rl
);
1011 set_state(my_id
, fullname
, sym
, state
);
1014 static void set_called(const char *name
, struct symbol
*sym
, char *key
, char *value
)
1016 set_state(my_call_id
, "this_function", NULL
, &called
);
1019 static void match_syscall_definition(struct symbol
*sym
)
1026 macro
= get_macro_name(sym
->pos
);
1028 (strncmp("SYSCALL_DEFINE", macro
, strlen("SYSCALL_DEFINE")) == 0 ||
1029 strncmp("COMPAT_SYSCALL_DEFINE", macro
, strlen("COMPAT_SYSCALL_DEFINE")) == 0))
1032 name
= get_function();
1033 if (!option_no_db
&& get_state(my_call_id
, "this_function", NULL
) != &called
) {
1034 if (name
&& strncmp(name
, "sys_", 4) == 0)
1038 if (name
&& strncmp(name
, "compat_sys_", 11) == 0)
1044 FOR_EACH_PTR(sym
->ctype
.base_type
->arguments
, arg
) {
1045 set_state(my_id
, arg
->ident
->name
, arg
, alloc_estate_whole(get_real_base_type(arg
)));
1046 } END_FOR_EACH_PTR(arg
);
1049 static void set_to_user_data(struct expression
*expr
, char *key
, char *value
)
1053 struct symbol
*type
;
1054 struct range_list
*rl
= NULL
;
1056 type
= get_member_type_from_key(expr
, key
);
1057 name
= get_variable_from_key(expr
, key
, &sym
);
1061 call_results_to_rl(expr
, type
, value
, &rl
);
1063 set_state(my_id
, name
, sym
, alloc_estate_rl(rl
));
1069 static void returns_param_user_data(struct expression
*expr
, int param
, char *key
, char *value
)
1071 struct expression
*arg
;
1072 struct expression
*call
;
1075 while (call
->type
== EXPR_ASSIGNMENT
)
1076 call
= strip_expr(call
->right
);
1077 if (call
->type
!= EXPR_CALL
)
1080 if (!we_pass_user_data(call
))
1084 if (expr
->type
!= EXPR_ASSIGNMENT
)
1086 set_to_user_data(expr
->left
, key
, value
);
1090 arg
= get_argument_from_call_expr(call
->args
, param
);
1093 set_to_user_data(arg
, key
, value
);
1096 static void returns_param_user_data_set(struct expression
*expr
, int param
, char *key
, char *value
)
1098 struct expression
*arg
;
1100 func_gets_user_data
= true;
1103 if (expr
->type
!= EXPR_ASSIGNMENT
)
1105 if (strcmp(key
, "*$") == 0) {
1106 set_points_to_user_data(expr
->left
);
1107 tag_as_user_data(expr
->left
);
1109 set_to_user_data(expr
->left
, key
, value
);
1114 while (expr
->type
== EXPR_ASSIGNMENT
)
1115 expr
= strip_expr(expr
->right
);
1116 if (expr
->type
!= EXPR_CALL
)
1119 arg
= get_argument_from_call_expr(expr
->args
, param
);
1122 set_to_user_data(arg
, key
, value
);
1125 static int has_empty_state(struct sm_state
*sm
)
1127 struct sm_state
*tmp
;
1129 FOR_EACH_PTR(sm
->possible
, tmp
) {
1130 if (!estate_rl(tmp
->state
))
1132 } END_FOR_EACH_PTR(tmp
);
1137 static void param_set_to_user_data(int return_id
, char *return_ranges
, struct expression
*expr
)
1139 struct sm_state
*sm
;
1140 struct smatch_state
*start_state
;
1141 struct range_list
*rl
;
1144 const char *param_name
;
1145 struct symbol
*ret_sym
;
1146 bool return_found
= false;
1148 expr
= strip_expr(expr
);
1149 return_str
= expr_to_str(expr
);
1150 ret_sym
= expr_to_sym(expr
);
1152 FOR_EACH_MY_SM(my_id
, __get_cur_stree(), sm
) {
1153 if (has_empty_state(sm
))
1156 param
= get_param_num_from_sym(sm
->sym
);
1160 /* The logic here was that if we were passed in a user data then
1161 * we don't record that. It's like the difference between
1162 * param_filter and param_set. When I think about it, I'm not
1163 * sure it actually works. It's probably harmless because we
1164 * checked earlier that we're not returning a parameter...
1165 * Let's mark this as a TODO.
1167 start_state
= get_state_stree(start_states
, my_id
, sm
->name
, sm
->sym
);
1168 if (start_state
&& rl_equiv(estate_rl(sm
->state
), estate_rl(start_state
)))
1171 param_name
= get_param_name(sm
);
1174 if (strcmp(param_name
, "$") == 0) /* The -1 param is handled after the loop */
1177 sql_insert_return_states(return_id
, return_ranges
,
1178 func_gets_user_data
? USER_DATA3_SET
: USER_DATA3
,
1179 param
, param_name
, show_rl(estate_rl(sm
->state
)));
1180 } END_FOR_EACH_SM(sm
);
1182 if (points_to_user_data(expr
)) {
1183 sql_insert_return_states(return_id
, return_ranges
,
1184 (is_skb_data(expr
) || !func_gets_user_data
) ?
1185 USER_DATA3_SET
: USER_DATA3
,
1191 FOR_EACH_MY_SM(my_id
, __get_cur_stree(), sm
) {
1194 if (ret_sym
!= sm
->sym
)
1197 param_name
= state_name_to_param_name(sm
->name
, return_str
);
1200 if (strcmp(param_name
, "$") == 0)
1201 return_found
= true;
1202 sql_insert_return_states(return_id
, return_ranges
,
1203 func_gets_user_data
? USER_DATA3_SET
: USER_DATA3
,
1204 -1, param_name
, show_rl(estate_rl(sm
->state
)));
1205 } END_FOR_EACH_SM(sm
);
1208 if (!return_found
&& get_user_rl(expr
, &rl
)) {
1209 sql_insert_return_states(return_id
, return_ranges
,
1210 func_gets_user_data
? USER_DATA3_SET
: USER_DATA3
,
1211 -1, "$", show_rl(rl
));
1216 free_string(return_str
);
1219 static struct int_stack
*gets_data_stack
;
1220 static void match_function_def(struct symbol
*sym
)
1222 func_gets_user_data
= false;
1225 static void match_inline_start(struct expression
*expr
)
1227 push_int(&gets_data_stack
, func_gets_user_data
);
1230 static void match_inline_end(struct expression
*expr
)
1232 func_gets_user_data
= pop_int(&gets_data_stack
);
1235 void register_kernel_user_data2(int id
)
1241 if (option_project
!= PROJ_KERNEL
)
1244 set_dynamic_states(my_id
);
1246 add_hook(&match_function_def
, FUNC_DEF_HOOK
);
1247 add_hook(&match_inline_start
, INLINE_FN_START
);
1248 add_hook(&match_inline_end
, INLINE_FN_END
);
1250 add_hook(&save_start_states
, AFTER_DEF_HOOK
);
1251 add_hook(&free_start_states
, AFTER_FUNC_HOOK
);
1252 add_hook(&match_save_states
, INLINE_FN_START
);
1253 add_hook(&match_restore_states
, INLINE_FN_END
);
1255 add_unmatched_state_hook(my_id
, &empty_state
);
1256 add_extra_nomod_hook(&extra_nomod_hook
);
1257 add_pre_merge_hook(my_id
, &pre_merge_hook
);
1258 add_merge_hook(my_id
, &merge_estates
);
1260 add_function_hook("copy_from_user", &match_user_copy
, INT_PTR(0));
1261 add_function_hook("__copy_from_user", &match_user_copy
, INT_PTR(0));
1262 add_function_hook("memcpy_fromiovec", &match_user_copy
, INT_PTR(0));
1263 for (i
= 0; i
< ARRAY_SIZE(kstr_funcs
); i
++)
1264 add_function_hook(kstr_funcs
[i
], &match_user_copy
, INT_PTR(2));
1265 add_function_hook("usb_control_msg", &match_user_copy
, INT_PTR(6));
1267 for (i
= 0; i
< ARRAY_SIZE(returns_user_data
); i
++) {
1268 add_function_assign_hook(returns_user_data
[i
], &match_user_assign_function
, NULL
);
1269 add_function_hook(returns_user_data
[i
], &match_returns_user_rl
, NULL
);
1272 add_function_hook("sscanf", &match_sscanf
, NULL
);
1274 add_hook(&match_syscall_definition
, AFTER_DEF_HOOK
);
1276 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
1277 add_hook(&match_condition
, CONDITION_HOOK
);
1279 add_hook(&match_call_info
, FUNCTION_CALL_HOOK
);
1280 add_member_info_callback(my_id
, struct_member_callback
);
1281 select_caller_info_hook(set_param_user_data
, USER_DATA3
);
1282 select_return_states_hook(USER_DATA3
, &returns_param_user_data
);
1283 select_return_states_hook(USER_DATA3_SET
, &returns_param_user_data_set
);
1284 add_split_return_callback(¶m_set_to_user_data
);
1287 void register_kernel_user_data3(int id
)
1291 if (option_project
!= PROJ_KERNEL
)
1293 select_caller_info_hook(set_called
, INTERNAL
);