Print this page
11972 resync smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/check_access_ok_math.c
+++ new/usr/src/tools/smatch/src/check_access_ok_math.c
1 1 /*
2 2 * Copyright (C) 2010 Dan Carpenter.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6 * as published by the Free Software Foundation; either version 2
7 7 * of the License, or (at your option) any later version.
8 8 *
9 9 * This program is distributed in the hope that it will be useful,
10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 * GNU General Public License for more details.
13 13 *
14 14 * You should have received a copy of the GNU General Public License
15 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 16 */
17 17
18 18 #include "smatch.h"
19 19
20 20 static int my_id;
21 21
22 22 static int can_overflow(struct expression *expr)
23 23 {
24 24 sval_t max;
25 25 int uncapped = 0;
26 26
27 27 expr = strip_expr(expr);
28 28
29 29 if (expr->type == EXPR_BINOP) {
30 30 uncapped += can_overflow(expr->left);
31 31 uncapped += can_overflow(expr->right);
32 32
33 33 if (uncapped &&
34 34 (expr->op == '+' || expr->op == '*' || expr->op == SPECIAL_LEFTSHIFT))
35 35 return 1;
36 36
37 37 return 0;
38 38 }
39 39
40 40 if (get_implied_max(expr, &max))
41 41 return 0;
42 42 if (get_absolute_max(expr, &max) && sval_cmp_val(max, 4096) <= 0)
43 43 return 0;
44 44 return 1;
45 45 }
46 46
47 47 static void match_size(struct expression *size_expr)
48 48 {
49 49 char *name;
50 50
51 51 size_expr = strip_expr(size_expr);
52 52 if (!size_expr)
53 53 return;
54 54 if (size_expr->type != EXPR_BINOP) {
55 55 size_expr = get_assigned_expr(size_expr);
56 56 if (!size_expr || size_expr->type != EXPR_BINOP)
57 57 return;
58 58 }
59 59 if (!can_overflow(size_expr))
60 60 return;
61 61
62 62 name = expr_to_str(size_expr);
63 63 sm_warning("math in access_ok() is dangerous '%s'", name);
64 64
65 65 free_string(name);
66 66 }
67 67
68 68 static void match_access_ok(const char *fn, struct expression *expr, void *data)
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
69 69 {
70 70 struct expression *size_expr;
71 71
72 72 size_expr = get_argument_from_call_expr(expr->args, 1);
73 73 match_size(size_expr);
74 74 }
75 75
76 76 static void split_asm_constraints(struct expression_list *expr_list)
77 77 {
78 78 struct expression *expr;
79 - int state = 0;
80 79 int i;
81 80
82 81 i = 0;
83 82 FOR_EACH_PTR(expr_list, expr) {
84 -
85 - switch (state) {
86 - case 0: /* identifier */
87 - case 1: /* constraint */
88 - state++;
89 - continue;
90 - case 2: /* expression */
91 - state = 0;
92 - if (i == 1)
93 - match_size(expr);
94 - i++;
95 - continue;
96 - }
83 + i++;
84 + if (expr->type != EXPR_ASM_OPERAND)
85 + continue;
86 + if (i == 1)
87 + match_size(expr->expr);
97 88 } END_FOR_EACH_PTR(expr);
98 89 }
99 90
100 91 static void match_asm_stmt(struct statement *stmt)
101 92 {
102 93 char *name;
103 94
104 95 name = get_macro_name(stmt->pos);
105 96 if (!name || strcmp(name, "access_ok") != 0)
106 97 return;
107 98 split_asm_constraints(stmt->asm_inputs);
108 99 }
109 100
110 101 void check_access_ok_math(int id)
111 102 {
112 103 my_id = id;
113 104 if (option_project != PROJ_KERNEL)
114 105 return;
115 106 if (!option_spammy)
116 107 return;
117 108 add_function_hook("__access_ok", &match_access_ok, NULL);
118 109 add_hook(&match_asm_stmt, ASM_HOOK);
119 110 }
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX