dereferences_param: mark more parameters as dereferenced
[smatch.git] / smatch_kernel_user_data.c
blob271941db9feffcaa02fdbaa2cc6f8bb893c47ab6
1 /*
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.
25 #include "smatch.h"
26 #include "smatch_slist.h"
27 #include "smatch_extra.h"
29 static int my_id;
30 static int my_call_id;
32 STATE(called);
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",
48 "kvm_register_read",
51 static struct stree *start_states;
52 static struct stree_stack *saved_stack;
53 static void save_start_states(struct statement *stmt)
55 start_states = clone_stree(__get_cur_stree());
58 static void free_start_states(void)
60 free_stree(&start_states);
63 static void match_save_states(struct expression *expr)
65 push_stree(&saved_stack, start_states);
66 start_states = NULL;
69 static void match_restore_states(struct expression *expr)
71 free_stree(&start_states);
72 start_states = pop_stree(&saved_stack);
75 static struct smatch_state *empty_state(struct sm_state *sm)
77 return alloc_estate_empty();
80 static struct smatch_state *new_state(struct symbol *type)
82 struct smatch_state *state;
84 if (!type || type_is_ptr(type))
85 return NULL;
87 state = alloc_estate_whole(type);
88 estate_set_new(state);
89 return state;
92 static void pre_merge_hook(struct sm_state *cur, struct sm_state *other)
94 struct smatch_state *user = cur->state;
95 struct smatch_state *extra;
96 struct smatch_state *state;
97 struct range_list *rl;
99 extra = __get_state(SMATCH_EXTRA, cur->name, cur->sym);
100 if (!extra)
101 return;
102 rl = rl_intersection(estate_rl(user), estate_rl(extra));
103 state = alloc_estate_rl(clone_rl(rl));
104 if (estate_capped(user) || is_capped_var_sym(cur->name, cur->sym))
105 estate_set_capped(state);
106 if (estate_treat_untagged(user))
107 estate_set_treat_untagged(state);
108 if (estates_equiv(state, cur->state))
109 return;
110 set_state(my_id, cur->name, cur->sym, state);
113 static void extra_nomod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
115 struct smatch_state *user, *new;
116 struct range_list *rl;
118 user = __get_state(my_id, name, sym);
119 if (!user)
120 return;
121 rl = rl_intersection(estate_rl(user), estate_rl(state));
122 if (rl_equiv(rl, estate_rl(user)))
123 return;
124 new = alloc_estate_rl(rl);
125 if (estate_capped(user))
126 estate_set_capped(new);
127 if (estate_treat_untagged(user))
128 estate_set_treat_untagged(new);
129 set_state(my_id, name, sym, new);
132 static bool user_rl_known(struct expression *expr)
134 struct range_list *rl;
135 sval_t close_to_max;
137 if (!get_user_rl(expr, &rl))
138 return true;
140 close_to_max = sval_type_max(rl_type(rl));
141 close_to_max.value -= 100;
143 if (sval_cmp(rl_max(rl), close_to_max) >= 0)
144 return false;
145 return true;
148 static bool binop_capped(struct expression *expr)
150 struct range_list *left_rl;
151 int comparison;
152 sval_t sval;
154 if (expr->op == '-' && get_user_rl(expr->left, &left_rl)) {
155 if (user_rl_capped(expr->left))
156 return true;
157 comparison = get_comparison(expr->left, expr->right);
158 if (comparison && show_special(comparison)[0] == '>')
159 return true;
160 return false;
163 if (expr->op == '&' || expr->op == '%') {
164 bool left_user, left_capped, right_user, right_capped;
166 if (!get_value(expr->right, &sval) && is_capped(expr->right))
167 return true;
168 if (is_capped(expr->left))
169 return true;
170 left_user = is_user_rl(expr->left);
171 right_user = is_user_rl(expr->right);
172 if (!left_user && !right_user)
173 return true;
175 left_capped = user_rl_capped(expr->left);
176 right_capped = user_rl_capped(expr->right);
178 if (left_user && left_capped) {
179 if (!right_user)
180 return true;
181 if (right_user && right_capped)
182 return true;
183 return false;
185 if (right_user && right_capped) {
186 if (!left_user)
187 return true;
188 return false;
190 return false;
194 * Generally "capped" means that we capped it to an unknown value.
195 * This is useful because if Smatch doesn't know what the value is then
196 * we have to trust that it is correct. But if we known cap value is
197 * 100 then we can check if 100 is correct and complain if it's wrong.
199 * So then the problem is with BINOP when we take a capped variable
200 * plus a user variable which is clamped to a known range (uncapped)
201 * the result should be capped.
203 if ((user_rl_capped(expr->left) || user_rl_known(expr->left)) &&
204 (user_rl_capped(expr->right) || user_rl_known(expr->right)))
205 return true;
207 return false;
210 bool user_rl_capped(struct expression *expr)
212 struct smatch_state *state;
213 struct range_list *rl;
214 sval_t sval;
216 expr = strip_expr(expr);
217 if (!expr)
218 return false;
219 if (get_value(expr, &sval))
220 return true;
221 if (expr->type == EXPR_BINOP)
222 return binop_capped(expr);
223 if ((expr->type == EXPR_PREOP || expr->type == EXPR_POSTOP) &&
224 (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT))
225 return user_rl_capped(expr->unop);
226 state = get_state_expr(my_id, expr);
227 if (state)
228 return estate_capped(state);
230 if (!get_user_rl(expr, &rl)) {
232 * The non user data parts of a binop are capped and
233 * also empty user rl states are capped.
235 return true;
238 if (rl_to_sval(rl, &sval))
239 return true;
241 return false; /* uncapped user data */
244 bool user_rl_treat_untagged(struct expression *expr)
246 struct smatch_state *state;
247 struct range_list *rl;
248 sval_t sval;
250 expr = strip_expr(expr);
251 if (!expr)
252 return false;
253 if (get_value(expr, &sval))
254 return true;
256 state = get_state_expr(my_id, expr);
257 if (state)
258 return estate_treat_untagged(state);
260 if (get_user_rl(expr, &rl))
261 return false; /* uncapped user data */
263 return true; /* not actually user data */
266 static void tag_inner_struct_members(struct expression *expr, struct symbol *member)
268 struct expression *edge_member;
269 struct symbol *base = get_real_base_type(member);
270 struct symbol *tmp;
272 if (member->ident)
273 expr = member_expression(expr, '.', member->ident);
275 FOR_EACH_PTR(base->symbol_list, tmp) {
276 struct symbol *type;
278 type = get_real_base_type(tmp);
279 if (!type)
280 continue;
282 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
283 tag_inner_struct_members(expr, tmp);
284 continue;
287 if (!tmp->ident)
288 continue;
290 edge_member = member_expression(expr, '.', tmp->ident);
291 set_state_expr(my_id, edge_member, new_state(type));
292 } END_FOR_EACH_PTR(tmp);
295 void __set_user_string(struct expression *expr);
296 static void tag_struct_members(struct symbol *type, struct expression *expr)
298 struct symbol *tmp;
299 struct expression *member;
300 int op = '*';
302 if (expr->type == EXPR_PREOP && expr->op == '&') {
303 expr = strip_expr(expr->unop);
304 op = '.';
307 FOR_EACH_PTR(type->symbol_list, tmp) {
308 type = get_real_base_type(tmp);
309 if (!type)
310 continue;
312 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
313 tag_inner_struct_members(expr, tmp);
314 continue;
317 if (!tmp->ident)
318 continue;
320 member = member_expression(expr, op, tmp->ident);
321 if (type->type == SYM_ARRAY) {
322 set_points_to_user_data(member);
323 } else {
324 set_state_expr(my_id, member, new_state(get_type(member)));
326 } END_FOR_EACH_PTR(tmp);
329 static void tag_base_type(struct expression *expr)
331 if (expr->type == EXPR_PREOP && expr->op == '&')
332 expr = strip_expr(expr->unop);
333 else
334 expr = deref_expression(expr);
335 set_state_expr(my_id, expr, new_state(get_type(expr)));
338 static void tag_as_user_data(struct expression *expr)
340 struct symbol *type;
342 expr = strip_expr(expr);
344 type = get_type(expr);
345 if (!type || type->type != SYM_PTR)
346 return;
347 type = get_real_base_type(type);
348 if (!type)
349 return;
350 if (type == &void_ctype) {
351 set_state_expr(my_id, deref_expression(expr), new_state(&ulong_ctype));
352 return;
354 if (type->type == SYM_BASETYPE) {
355 if (expr->type != EXPR_PREOP && expr->op != '&')
356 set_points_to_user_data(expr);
357 tag_base_type(expr);
358 return;
360 if (type->type == SYM_STRUCT || type->type == SYM_UNION) {
361 if (expr->type != EXPR_PREOP || expr->op != '&')
362 expr = deref_expression(expr);
363 else
364 set_state_expr(my_id, deref_expression(expr), new_state(&ulong_ctype));
365 tag_struct_members(type, expr);
369 static void match_user_copy(const char *fn, struct expression *expr, void *_param)
371 int param = PTR_INT(_param);
372 struct expression *dest;
374 func_gets_user_data = true;
376 dest = get_argument_from_call_expr(expr->args, param);
377 dest = strip_expr(dest);
378 if (!dest)
379 return;
380 tag_as_user_data(dest);
383 static int is_dev_attr_name(struct expression *expr)
385 char *name;
386 int ret = 0;
388 name = expr_to_str(expr);
389 if (!name)
390 return 0;
391 if (strstr(name, "->attr.name"))
392 ret = 1;
393 free_string(name);
394 return ret;
397 static int ends_in_n(struct expression *expr)
399 struct string *str;
401 if (!expr)
402 return 0;
403 if (expr->type != EXPR_STRING || !expr->string)
404 return 0;
406 str = expr->string;
407 if (str->length < 3)
408 return 0;
410 if (str->data[str->length - 3] == '%' &&
411 str->data[str->length - 2] == 'n')
412 return 1;
413 return 0;
416 static void match_sscanf(const char *fn, struct expression *expr, void *unused)
418 struct expression *str, *format, *arg;
419 int i, last;
421 func_gets_user_data = true;
423 str = get_argument_from_call_expr(expr->args, 0);
424 if (is_dev_attr_name(str))
425 return;
427 format = get_argument_from_call_expr(expr->args, 1);
428 if (is_dev_attr_name(format))
429 return;
431 last = ptr_list_size((struct ptr_list *)expr->args) - 1;
433 i = -1;
434 FOR_EACH_PTR(expr->args, arg) {
435 i++;
436 if (i < 2)
437 continue;
438 if (i == last && ends_in_n(format))
439 continue;
440 tag_as_user_data(arg);
441 } END_FOR_EACH_PTR(arg);
444 static int get_rl_from_function(struct expression *expr, struct range_list **rl)
446 int i;
448 if (expr->type != EXPR_CALL || expr->fn->type != EXPR_SYMBOL ||
449 !expr->fn->symbol_name || !expr->fn->symbol_name->name)
450 return 0;
452 for (i = 0; i < ARRAY_SIZE(returns_user_data); i++) {
453 if (strcmp(expr->fn->symbol_name->name, returns_user_data[i]) == 0) {
454 *rl = alloc_whole_rl(get_type(expr));
455 return 1;
458 return 0;
461 static int comes_from_skb_data(struct expression *expr)
463 expr = strip_expr(expr);
464 if (!expr || expr->type != EXPR_PREOP || expr->op != '*')
465 return 0;
467 expr = strip_expr(expr->unop);
468 if (!expr)
469 return 0;
470 if (expr->type == EXPR_BINOP && expr->op == '+')
471 expr = strip_expr(expr->left);
473 return is_skb_data(expr);
476 static int handle_get_user(struct expression *expr)
478 char *name;
479 int ret = 0;
481 name = get_macro_name(expr->pos);
482 if (!name || strcmp(name, "get_user") != 0)
483 return 0;
485 name = expr_to_var(expr->right);
486 if (!name || (strcmp(name, "__val_gu") != 0 && strcmp(name, "__gu_val") != 0))
487 goto free;
488 set_state_expr(my_id, expr->left, new_state(get_type(expr->left)));
489 ret = 1;
490 free:
491 free_string(name);
492 return ret;
495 static bool state_is_new(struct expression *expr)
497 struct smatch_state *state;
499 state = get_state_expr(my_id, expr);
500 if (estate_new(state))
501 return true;
503 if (expr->type == EXPR_BINOP) {
504 if (state_is_new(expr->left))
505 return true;
506 if (state_is_new(expr->right))
507 return true;
509 return false;
512 static bool handle_op_assign(struct expression *expr)
514 struct expression *binop_expr;
515 struct smatch_state *state;
516 struct range_list *rl;
518 switch (expr->op) {
519 case SPECIAL_ADD_ASSIGN:
520 case SPECIAL_SUB_ASSIGN:
521 case SPECIAL_AND_ASSIGN:
522 case SPECIAL_MOD_ASSIGN:
523 case SPECIAL_SHL_ASSIGN:
524 case SPECIAL_SHR_ASSIGN:
525 case SPECIAL_OR_ASSIGN:
526 case SPECIAL_XOR_ASSIGN:
527 case SPECIAL_MUL_ASSIGN:
528 case SPECIAL_DIV_ASSIGN:
529 binop_expr = binop_expression(expr->left,
530 op_remove_assign(expr->op),
531 expr->right);
532 if (!get_user_rl(binop_expr, &rl))
533 return true;
535 rl = cast_rl(get_type(expr->left), rl);
536 state = alloc_estate_rl(rl);
537 if (user_rl_capped(binop_expr))
538 estate_set_capped(state);
539 if (user_rl_treat_untagged(expr->left))
540 estate_set_treat_untagged(state);
541 if (state_is_new(binop_expr))
542 estate_set_new(state);
543 set_state_expr(my_id, expr->left, state);
544 return true;
546 return false;
549 static void match_assign(struct expression *expr)
551 struct symbol *left_type, *right_type;
552 struct range_list *rl;
553 static struct expression *handled;
554 static struct expression *ignore;
555 struct smatch_state *state;
556 struct expression *faked;
557 bool is_capped = false;
558 bool is_new = false;
560 left_type = get_type(expr->left);
561 if (left_type == &void_ctype)
562 return;
564 faked = get_faked_expression();
565 if (0 && ignore && faked == ignore) {
566 if (local_debug)
567 sm_msg("%s: ignored = '%s'", __func__, expr_to_str(faked));
568 return;
571 /* FIXME: handle fake array assignments frob(&user_array[x]); */
573 if (is_fake_call(expr->right) && faked &&
574 faked->type == EXPR_ASSIGNMENT &&
575 points_to_user_data(faked->right)) {
576 if (is_skb_data(faked->right))
577 func_gets_user_data = true;
578 rl = alloc_whole_rl(get_type(expr->left));
579 is_new = true;
580 goto set;
583 if (local_debug)
584 sm_msg("%s: expr = '%s'", __func__, expr_to_str(expr));
586 if (faked && faked == handled)
587 return;
588 if (is_fake_call(expr->right))
589 goto clear_old_state;
590 if (handle_get_user(expr))
591 return;
592 if (points_to_user_data(expr->right) &&
593 is_struct_ptr(get_type(expr->left))) {
594 handled = expr;
595 // This should be handled by smatch_points_to_user_data.c
596 // set_points_to_user_data(expr->left);
599 if (handle_op_assign(expr))
600 return;
601 if (expr->op != '=')
602 goto clear_old_state;
604 /* Handled by DB code */
605 if (expr->right->type == EXPR_CALL || __in_fake_parameter_assign)
606 return;
608 if (!get_user_rl(expr->right, &rl))
609 goto clear_old_state;
610 is_capped = user_rl_capped(expr->right);
611 is_new = state_is_new(expr->right);
613 set:
614 if (type_is_ptr(left_type)) {
615 right_type = get_type(expr->right);
616 if (right_type && right_type->type == SYM_ARRAY)
617 set_points_to_user_data(expr->left);
618 if (faked)
619 ignore = faked;
620 else
621 ignore = expr;
622 return;
625 rl = cast_rl(left_type, rl);
626 state = alloc_estate_rl(rl);
627 if (is_new)
628 estate_set_new(state);
629 if (is_capped)
630 estate_set_capped(state);
631 if (user_rl_treat_untagged(expr->right))
632 estate_set_treat_untagged(state);
634 if (local_debug)
635 sm_msg("%s: left = '%s' user_state = '%s'", __func__, expr_to_str(expr->left), state->name);
636 set_state_expr(my_id, expr->left, state);
638 return;
640 clear_old_state:
643 * HACK ALERT!!! This should be at the start of the function. The
644 * the problem is that handling "pointer = array;" assignments is
645 * handled in this function instead of in kernel_points_to_user_data.c.
647 if (type_is_ptr(left_type)) {
648 if (faked)
649 ignore = faked;
650 else
651 ignore = expr;
652 return;
655 if (get_state_expr(my_id, expr->left))
656 set_state_expr(my_id, expr->left, alloc_estate_empty());
659 static void handle_eq_noteq(struct expression *expr)
661 struct smatch_state *left_orig, *right_orig;
663 left_orig = get_state_expr(my_id, expr->left);
664 right_orig = get_state_expr(my_id, expr->right);
666 if (!left_orig && !right_orig)
667 return;
668 if (left_orig && right_orig)
669 return;
671 if (left_orig) {
672 set_true_false_states_expr(my_id, expr->left,
673 expr->op == SPECIAL_EQUAL ? alloc_estate_empty() : NULL,
674 expr->op == SPECIAL_EQUAL ? NULL : alloc_estate_empty());
675 } else {
676 set_true_false_states_expr(my_id, expr->right,
677 expr->op == SPECIAL_EQUAL ? alloc_estate_empty() : NULL,
678 expr->op == SPECIAL_EQUAL ? NULL : alloc_estate_empty());
682 static struct range_list *strip_negatives(struct range_list *rl)
684 sval_t min = rl_min(rl);
685 sval_t minus_one = { .type = rl_type(rl), .value = -1 };
686 sval_t over = { .type = rl_type(rl), .value = INT_MAX + 1ULL };
687 sval_t max = sval_type_max(rl_type(rl));
689 if (!rl)
690 return NULL;
692 if (type_unsigned(rl_type(rl)) && type_bits(rl_type(rl)) > 31)
693 return remove_range(rl, over, max);
695 return remove_range(rl, min, minus_one);
698 static void handle_compare(struct expression *expr)
700 struct expression *left, *right;
701 struct range_list *left_rl = NULL;
702 struct range_list *right_rl = NULL;
703 struct range_list *user_rl;
704 struct smatch_state *capped_state;
705 struct smatch_state *left_true = NULL;
706 struct smatch_state *left_false = NULL;
707 struct smatch_state *right_true = NULL;
708 struct smatch_state *right_false = NULL;
709 struct symbol *type;
710 sval_t sval;
712 left = strip_expr(expr->left);
713 right = strip_expr(expr->right);
715 while (left->type == EXPR_ASSIGNMENT)
716 left = strip_expr(left->left);
719 * Conditions are mostly handled by smatch_extra.c, but there are some
720 * times where the exact values are not known so we can't do that.
722 * Normally, we might consider using smatch_capped.c to supliment smatch
723 * extra but that doesn't work when we merge unknown uncapped kernel
724 * data with unknown capped user data. The result is uncapped user
725 * data. We need to keep it separate and say that the user data is
726 * capped. In the past, I would have marked this as just regular
727 * kernel data (not user data) but we can't do that these days because
728 * we need to track user data for Spectre.
730 * The other situation which we have to handle is when we do have an
731 * int and we compare against an unknown unsigned kernel variable. In
732 * that situation we assume that the kernel data is less than INT_MAX.
733 * Otherwise then we get all sorts of array underflow false positives.
737 /* Handled in smatch_extra.c */
738 if (get_implied_value(left, &sval) ||
739 get_implied_value(right, &sval))
740 return;
742 get_user_rl(left, &left_rl);
743 get_user_rl(right, &right_rl);
745 /* nothing to do */
746 if (!left_rl && !right_rl)
747 return;
748 /* if both sides are user data that's not a good limit */
749 if (left_rl && right_rl)
750 return;
752 if (left_rl)
753 user_rl = left_rl;
754 else
755 user_rl = right_rl;
757 type = get_type(expr);
758 if (type_unsigned(type))
759 user_rl = strip_negatives(user_rl);
760 capped_state = alloc_estate_rl(user_rl);
761 estate_set_capped(capped_state);
763 switch (expr->op) {
764 case '<':
765 case SPECIAL_UNSIGNED_LT:
766 case SPECIAL_LTE:
767 case SPECIAL_UNSIGNED_LTE:
768 if (left_rl)
769 left_true = capped_state;
770 else
771 right_false = capped_state;
772 break;
773 case '>':
774 case SPECIAL_UNSIGNED_GT:
775 case SPECIAL_GTE:
776 case SPECIAL_UNSIGNED_GTE:
777 if (left_rl)
778 left_false = capped_state;
779 else
780 right_true = capped_state;
781 break;
784 set_true_false_states_expr(my_id, left, left_true, left_false);
785 set_true_false_states_expr(my_id, right, right_true, right_false);
788 static void match_condition(struct expression *expr)
790 if (expr->type != EXPR_COMPARE)
791 return;
793 if (expr->op == SPECIAL_EQUAL ||
794 expr->op == SPECIAL_NOTEQUAL) {
795 handle_eq_noteq(expr);
796 return;
799 handle_compare(expr);
802 static void match_returns_user_rl(const char *fn, struct expression *expr, void *unused)
804 func_gets_user_data = true;
807 static int get_user_macro_rl(struct expression *expr, struct range_list **rl)
809 struct expression *parent;
810 char *macro;
812 if (!expr)
813 return 0;
815 macro = get_macro_name(expr->pos);
816 if (!macro)
817 return 0;
819 /* handle ntohl(foo[i]) where "i" is trusted */
820 parent = expr_get_parent_expr(expr);
821 while (parent && parent->type != EXPR_BINOP)
822 parent = expr_get_parent_expr(parent);
823 if (parent && parent->type == EXPR_BINOP) {
824 char *parent_macro = get_macro_name(parent->pos);
826 if (parent_macro && strcmp(macro, parent_macro) == 0)
827 return 0;
830 if (strcmp(macro, "ntohl") == 0) {
831 *rl = alloc_whole_rl(&uint_ctype);
832 return 1;
834 if (strcmp(macro, "ntohs") == 0) {
835 *rl = alloc_whole_rl(&ushort_ctype);
836 return 1;
838 return 0;
841 static int has_user_data(struct symbol *sym)
843 struct sm_state *tmp;
845 FOR_EACH_MY_SM(my_id, __get_cur_stree(), tmp) {
846 if (tmp->sym == sym)
847 return 1;
848 } END_FOR_EACH_SM(tmp);
849 return 0;
852 bool we_pass_user_data(struct expression *call)
854 struct expression *arg;
855 struct symbol *sym;
857 FOR_EACH_PTR(call->args, arg) {
858 if (local_debug)
859 sm_msg("%s: arg = '%s' %s", __func__,
860 expr_to_str(arg),
861 points_to_user_data(arg) ? "user pointer" : "not");
862 if (points_to_user_data(arg))
863 return true;
864 sym = expr_to_sym(arg);
865 if (!sym)
866 continue;
867 if (has_user_data(sym))
868 return true;
869 } END_FOR_EACH_PTR(arg);
871 return false;
874 static int db_returned_user_rl(struct expression *call, struct range_list **rl)
876 struct smatch_state *state;
877 char buf[48];
879 if (is_fake_call(call))
880 return 0;
881 snprintf(buf, sizeof(buf), "return %p", call);
882 state = get_state(my_id, buf, NULL);
883 if (!state || !estate_rl(state))
884 return 0;
885 *rl = estate_rl(state);
886 return 1;
889 struct stree *get_user_stree(void)
891 return get_all_states_stree(my_id);
894 static int user_data_flag;
895 static int no_user_data_flag;
896 struct range_list *var_user_rl(struct expression *expr)
898 struct smatch_state *state;
899 struct range_list *rl;
900 struct range_list *absolute_rl;
902 if (expr->type == EXPR_PREOP && expr->op == '&') {
903 no_user_data_flag = 1;
904 return NULL;
907 if (expr->type == EXPR_BINOP && expr->op == '%') {
908 struct range_list *left, *right;
910 if (!get_user_rl(expr->right, &right))
911 return NULL;
912 get_absolute_rl(expr->left, &left);
913 rl = rl_binop(left, '%', right);
914 goto found;
917 if (expr->type == EXPR_BINOP && expr->op == '/') {
918 struct range_list *left = NULL;
919 struct range_list *right = NULL;
920 struct range_list *abs_right;
923 * The specific bug I'm dealing with is:
925 * foo = capped_user / unknown;
927 * Instead of just saying foo is now entirely user_rl we should
928 * probably say instead that it is not at all user data.
932 get_user_rl(expr->left, &left);
933 get_user_rl(expr->right, &right);
934 get_absolute_rl(expr->right, &abs_right);
936 if (left && !right) {
937 rl = rl_binop(left, '/', abs_right);
938 if (sval_cmp(rl_max(left), rl_max(rl)) < 0)
939 no_user_data_flag = 1;
942 return NULL;
945 if (get_rl_from_function(expr, &rl))
946 goto found;
948 if (get_user_macro_rl(expr, &rl))
949 goto found;
951 if (comes_from_skb_data(expr)) {
952 rl = alloc_whole_rl(get_type(expr));
953 goto found;
956 state = get_state_expr(my_id, expr);
957 if (state && estate_rl(state)) {
958 rl = estate_rl(state);
959 goto found;
962 if (expr->type == EXPR_CALL && db_returned_user_rl(expr, &rl))
963 goto found;
965 if (expr->type == EXPR_PREOP && expr->op == '*' &&
966 points_to_user_data(expr->unop)) {
967 rl = var_to_absolute_rl(expr);
968 goto found;
971 if (is_array(expr)) {
972 struct expression *array = get_array_base(expr);
974 if (!get_state_expr(my_id, array)) {
975 no_user_data_flag = 1;
976 return NULL;
980 return NULL;
981 found:
982 user_data_flag = 1;
983 absolute_rl = var_to_absolute_rl(expr);
984 return clone_rl(rl_intersection(rl, absolute_rl));
987 static bool is_ptr_subtract(struct expression *expr)
989 expr = strip_expr(expr);
990 if (!expr)
991 return false;
992 if (expr->type == EXPR_BINOP && expr->op == '-' &&
993 type_is_ptr(get_type(expr->left))) {
994 return true;
996 return false;
999 int get_user_rl(struct expression *expr, struct range_list **rl)
1001 if (is_ptr_subtract(expr))
1002 return 0;
1004 user_data_flag = 0;
1005 no_user_data_flag = 0;
1006 custom_get_absolute_rl(expr, &var_user_rl, rl);
1007 if (!user_data_flag || no_user_data_flag)
1008 *rl = NULL;
1010 return !!*rl;
1013 int is_user_rl(struct expression *expr)
1015 struct range_list *tmp;
1017 return get_user_rl(expr, &tmp) && tmp;
1020 int get_user_rl_var_sym(const char *name, struct symbol *sym, struct range_list **rl)
1022 struct smatch_state *state;
1024 state = get_state(my_id, name, sym);
1025 if (state && estate_rl(state)) {
1026 *rl = estate_rl(state);
1027 return 1;
1029 return 0;
1032 static void return_info_callback(int return_id, char *return_ranges,
1033 struct expression *returned_expr,
1034 int param,
1035 const char *printed_name,
1036 struct sm_state *sm)
1038 struct smatch_state *extra;
1039 struct range_list *rl;
1040 char buf[64];
1042 if (param >= 0) {
1043 if (strcmp(printed_name, "$") == 0)
1044 return;
1045 if (!param_was_set_var_sym(sm->name, sm->sym))
1046 return;
1048 rl = estate_rl(sm->state);
1049 if (!rl)
1050 return;
1051 extra = get_state(SMATCH_EXTRA, sm->name, sm->sym);
1052 if (estate_rl(extra))
1053 rl = rl_intersection(estate_rl(sm->state), estate_rl(extra));
1054 if (!rl)
1055 return;
1057 snprintf(buf, sizeof(buf), "%s%s%s",
1058 show_rl(rl),
1059 estate_capped(sm->state) ? "[c]" : "",
1060 estate_treat_untagged(sm->state) ? "[u]" : "");
1061 sql_insert_return_states(return_id, return_ranges,
1062 estate_new(sm->state) ? USER_DATA_SET : USER_DATA,
1063 param, printed_name, buf);
1066 static void caller_info_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
1068 struct smatch_state *state;
1069 struct range_list *rl;
1070 struct symbol *type;
1071 char buf[64];
1073 if (local_debug)
1074 sm_msg("%s: name = '%s' sm = '%s'", __func__, printed_name, show_sm(sm));
1077 * Smatch uses a hack where if we get an unsigned long we say it's
1078 * both user data and it points to user data. But if we pass it to a
1079 * function which takes an int, then it's just user data. There's not
1080 * enough bytes for it to be a pointer.
1083 type = get_arg_type(call->fn, param);
1084 if (strcmp(printed_name, "$") != 0 && type && type_bits(type) < type_bits(&ptr_ctype))
1085 return;
1087 if (strcmp(sm->state->name, "") == 0)
1088 return;
1090 state = __get_state(SMATCH_EXTRA, sm->name, sm->sym);
1091 if (!state || !estate_rl(state))
1092 rl = estate_rl(sm->state);
1093 else
1094 rl = rl_intersection(estate_rl(sm->state), estate_rl(state));
1096 if (!rl)
1097 return;
1099 snprintf(buf, sizeof(buf), "%s%s%s", show_rl(rl),
1100 estate_capped(sm->state) ? "[c]" : "",
1101 estate_treat_untagged(sm->state) ? "[u]" : "");
1102 sql_insert_caller_info(call, USER_DATA, param, printed_name, buf);
1105 static void db_param_set(struct expression *expr, int param, char *key, char *value)
1107 struct expression *arg;
1108 char *name;
1109 struct symbol *sym;
1110 struct smatch_state *state;
1112 while (expr->type == EXPR_ASSIGNMENT)
1113 expr = strip_expr(expr->right);
1114 if (expr->type != EXPR_CALL)
1115 return;
1117 arg = get_argument_from_call_expr(expr->args, param);
1118 if (!arg)
1119 return;
1120 name = get_variable_from_key(arg, key, &sym);
1121 if (!name || !sym)
1122 goto free;
1124 state = get_state(my_id, name, sym);
1125 if (!state)
1126 goto free;
1128 set_state(my_id, name, sym, alloc_estate_empty());
1129 free:
1130 free_string(name);
1133 static bool param_data_capped(const char *value)
1135 if (strstr(value, ",c") || strstr(value, "[c"))
1136 return true;
1137 return false;
1140 static bool param_data_treat_untagged(const char *value)
1142 if (strstr(value, ",u") || strstr(value, "[u"))
1143 return true;
1144 return false;
1147 static void set_param_user_data(const char *name, struct symbol *sym, char *key, char *value)
1149 struct expression *expr;
1150 struct range_list *rl = NULL;
1151 struct smatch_state *state;
1152 struct symbol *type;
1153 char *fullname;
1155 expr = symbol_expression(sym);
1156 fullname = get_variable_from_key(expr, key, NULL);
1157 if (!fullname)
1158 return;
1160 type = get_member_type_from_key(expr, key);
1161 if (type && type->type == SYM_STRUCT) {
1162 sm_info("%s: user data struct. key='%s' value='%s'",
1163 __func__, key, value);
1164 return;
1167 // FIXME: This is temporary. Just run this on Thursday and then
1168 // let's make it a printf() and then delete it.
1169 if (!type) {
1170 sm_msg("%s: no type for '%s'", __func__, fullname);
1171 return;
1174 str_to_rl(type, value, &rl);
1175 rl = swap_mtag_seed(expr, rl);
1176 state = alloc_estate_rl(rl);
1177 if (param_data_capped(value) || is_capped(expr))
1178 estate_set_capped(state);
1179 if (param_data_treat_untagged(value) || sym->ctype.as == 5)
1180 estate_set_treat_untagged(state);
1181 set_state(my_id, fullname, sym, state);
1184 static void set_called(const char *name, struct symbol *sym, char *key, char *value)
1186 set_state(my_call_id, "this_function", NULL, &called);
1189 static void match_syscall_definition(struct symbol *sym)
1191 struct symbol *arg;
1192 char *macro;
1193 char *name;
1194 int is_syscall = 0;
1196 macro = get_macro_name(sym->pos);
1197 if (macro &&
1198 (strncmp("SYSCALL_DEFINE", macro, strlen("SYSCALL_DEFINE")) == 0 ||
1199 strncmp("COMPAT_SYSCALL_DEFINE", macro, strlen("COMPAT_SYSCALL_DEFINE")) == 0))
1200 is_syscall = 1;
1202 name = get_function();
1203 if (!option_no_db && get_state(my_call_id, "this_function", NULL) != &called) {
1204 if (name && strncmp(name, "sys_", 4) == 0)
1205 is_syscall = 1;
1208 if (name && strncmp(name, "compat_sys_", 11) == 0)
1209 is_syscall = 1;
1211 if (!is_syscall)
1212 return;
1214 FOR_EACH_PTR(sym->ctype.base_type->arguments, arg) {
1215 set_state(my_id, arg->ident->name, arg, alloc_estate_whole(get_real_base_type(arg)));
1216 } END_FOR_EACH_PTR(arg);
1219 #define OLD 0
1220 #define NEW 1
1222 static void store_user_data_return(struct expression *expr, char *key, char *value, bool is_new)
1224 struct smatch_state *state;
1225 struct range_list *rl;
1226 struct symbol *type;
1227 char buf[48];
1229 if (key[0] != '$')
1230 return;
1232 type = get_type(expr);
1233 snprintf(buf, sizeof(buf), "return %p%s", expr, key + 1);
1234 call_results_to_rl(expr, type, value, &rl);
1236 state = alloc_estate_rl(rl);
1237 if (is_new)
1238 estate_set_new(state);
1240 set_state(my_id, buf, NULL, state);
1243 static void set_to_user_data(struct expression *expr, char *key, char *value, bool is_new)
1245 struct smatch_state *state;
1246 char *name;
1247 struct symbol *sym;
1248 struct symbol *type;
1249 struct range_list *rl = NULL;
1251 type = get_member_type_from_key(expr, key);
1252 name = get_variable_from_key(expr, key, &sym);
1253 if (!name || !sym)
1254 goto free;
1256 call_results_to_rl(expr, type, value, &rl);
1258 state = alloc_estate_rl(rl);
1259 if (param_data_capped(value))
1260 estate_set_capped(state);
1261 if (param_data_treat_untagged(value))
1262 estate_set_treat_untagged(state);
1263 if (is_new)
1264 estate_set_new(state);
1265 set_state(my_id, name, sym, state);
1266 free:
1267 free_string(name);
1270 static void returns_param_user_data(struct expression *expr, int param, char *key, char *value)
1272 struct expression *arg;
1273 struct expression *call;
1275 call = expr;
1276 while (call->type == EXPR_ASSIGNMENT)
1277 call = strip_expr(call->right);
1278 if (call->type != EXPR_CALL)
1279 return;
1281 if (!we_pass_user_data(call))
1282 return;
1284 if (param == -1) {
1285 if (expr->type != EXPR_ASSIGNMENT) {
1286 store_user_data_return(expr, key, value, OLD);
1287 return;
1289 set_to_user_data(expr->left, key, value, OLD);
1290 return;
1293 arg = get_argument_from_call_expr(call->args, param);
1294 if (!arg)
1295 return;
1296 set_to_user_data(arg, key, value, OLD);
1299 static void returns_param_user_data_set(struct expression *expr, int param, char *key, char *value)
1301 struct expression *arg;
1303 func_gets_user_data = true;
1305 if (param == -1) {
1306 if (expr->type != EXPR_ASSIGNMENT) {
1307 store_user_data_return(expr, key, value, NEW);
1308 return;
1310 set_to_user_data(expr->left, key, value, NEW);
1311 return;
1314 while (expr->type == EXPR_ASSIGNMENT)
1315 expr = strip_expr(expr->right);
1316 if (expr->type != EXPR_CALL)
1317 return;
1319 arg = get_argument_from_call_expr(expr->args, param);
1320 if (!arg)
1321 return;
1322 set_to_user_data(arg, key, value, NEW);
1325 static void returns_param_capped(struct expression *expr, int param, char *key, char *value)
1327 struct smatch_state *state, *new;
1328 struct symbol *sym;
1329 char *name;
1331 name = return_state_to_var_sym(expr, param, key, &sym);
1332 if (!name || !sym)
1333 goto free;
1335 state = get_state(my_id, name, sym);
1336 if (!state || estate_capped(state))
1337 goto free;
1339 new = clone_estate(state);
1340 estate_set_capped(new);
1342 set_state(my_id, name, sym, new);
1343 free:
1344 free_string(name);
1347 static struct int_stack *gets_data_stack;
1348 static void match_function_def(struct symbol *sym)
1350 func_gets_user_data = false;
1352 if (is_user_data_fn(sym))
1353 func_gets_user_data = true;
1356 static void match_inline_start(struct expression *expr)
1358 push_int(&gets_data_stack, func_gets_user_data);
1361 static void match_inline_end(struct expression *expr)
1363 func_gets_user_data = pop_int(&gets_data_stack);
1366 void register_kernel_user_data(int id)
1368 int i;
1370 my_id = id;
1372 if (option_project != PROJ_KERNEL)
1373 return;
1375 set_dynamic_states(my_id);
1377 add_hook(&match_function_def, FUNC_DEF_HOOK);
1378 add_hook(&match_inline_start, INLINE_FN_START);
1379 add_hook(&match_inline_end, INLINE_FN_END);
1381 add_hook(&save_start_states, AFTER_DEF_HOOK);
1382 add_hook(&free_start_states, AFTER_FUNC_HOOK);
1383 add_hook(&match_save_states, INLINE_FN_START);
1384 add_hook(&match_restore_states, INLINE_FN_END);
1386 add_unmatched_state_hook(my_id, &empty_state);
1387 add_extra_nomod_hook(&extra_nomod_hook);
1388 add_pre_merge_hook(my_id, &pre_merge_hook);
1389 add_merge_hook(my_id, &merge_estates);
1391 add_function_hook("copy_from_user", &match_user_copy, INT_PTR(0));
1392 add_function_hook("__copy_from_user", &match_user_copy, INT_PTR(0));
1393 add_function_hook("memcpy_fromiovec", &match_user_copy, INT_PTR(0));
1394 for (i = 0; i < ARRAY_SIZE(kstr_funcs); i++)
1395 add_function_hook(kstr_funcs[i], &match_user_copy, INT_PTR(2));
1396 add_function_hook("usb_control_msg", &match_user_copy, INT_PTR(6));
1398 for (i = 0; i < ARRAY_SIZE(returns_user_data); i++)
1399 add_function_hook(returns_user_data[i], &match_returns_user_rl, NULL);
1401 add_function_hook("sscanf", &match_sscanf, NULL);
1403 add_hook(&match_syscall_definition, AFTER_DEF_HOOK);
1405 add_hook(&match_assign, ASSIGNMENT_HOOK);
1406 select_return_states_hook(PARAM_SET, &db_param_set);
1407 add_hook(&match_condition, CONDITION_HOOK);
1409 add_caller_info_callback(my_id, caller_info_callback);
1410 add_return_info_callback(my_id, return_info_callback);
1411 select_caller_info_hook(set_param_user_data, USER_DATA);
1412 select_return_states_hook(USER_DATA, &returns_param_user_data);
1413 select_return_states_hook(USER_DATA_SET, &returns_param_user_data_set);
1414 select_return_states_hook(CAPPED_DATA, &returns_param_capped);
1417 void register_kernel_user_data2(int id)
1419 my_call_id = id;
1421 if (option_project != PROJ_KERNEL)
1422 return;
1423 select_caller_info_hook(set_called, INTERNAL);