Print this page
11506 smatch resync
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/check_syscall_arg_type.c
+++ new/usr/src/tools/smatch/src/check_syscall_arg_type.c
1 1 /*
2 2 * Copyright (C) 2017 Oracle.
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 /*
19 19 * This is to help create Trinity fuzzer templates.
20 20 *
21 21 */
22 22
23 23 #include "smatch.h"
24 24 #include "smatch_slist.h"
25 25
26 26 static int my_id;
27 27
28 28 STATE(ARG_FD);
29 29 #if 0
30 30 STATE(arg_range);
31 31 STATE(arg_op);
32 32 STATE(arg_list);
33 33 STATE(arg_cpu);
34 34 STATE(arg_pathname);
35 35 #endif
36 36 // nr_segs * sizeof(struct iovec)
37 37 // if (nr_segs > UIO_MAXIOV)
38 38 #if 0
39 39 STATE(arg_ioveclen);
40 40 STATE(arg_sockaddrlen);
41 41 STATE(arg_socketinfo);
42 42 #endif
43 43
44 44 struct smatch_state *merge_states(struct smatch_state *s1, struct smatch_state *s2)
45 45 {
46 46 if (s1 == &undefined)
47 47 return s2;
48 48 return s1;
49 49 }
50 50
51 51 struct typedef_lookup {
52 52 const char *name;
53 53 struct symbol *sym;
54 54 int failed;
55 55 };
56 56
57 57 static struct symbol *_typedef_lookup(const char *name)
58 58 {
59 59 struct ident *id;
60 60 struct symbol *node;
61 61
62 62 id = built_in_ident(name);
63 63 if (!id)
64 64 return NULL;
65 65 node = lookup_symbol(id, NS_TYPEDEF);
66 66 if (!node || node->type != SYM_NODE)
67 67 return NULL;
68 68 return get_real_base_type(node);
69 69 }
70 70
71 71 static void typedef_lookup(struct typedef_lookup *tl)
72 72 {
73 73 if (tl->sym || tl->failed)
74 74 return;
75 75 tl->sym = _typedef_lookup(tl->name);
76 76 if (!tl->sym)
77 77 tl->failed = 1;
78 78 }
79 79
80 80 static int is_mode_t(struct symbol *sym)
81 81 {
82 82 static struct typedef_lookup umode_t = { .name = "umode_t" };
83 83 struct symbol *type;
84 84
85 85 typedef_lookup(&umode_t);
86 86 if (!umode_t.sym)
87 87 return 0;
88 88 type = get_base_type(sym);
89 89 if (type == umode_t.sym)
90 90 return 1;
91 91 return 0;
92 92 }
93 93
94 94 static int is_pid_t(struct symbol *sym)
95 95 {
96 96 static struct typedef_lookup pid_t = { .name = "pid_t" };
97 97 struct symbol *type;
98 98
99 99 typedef_lookup(&pid_t);
100 100 if (!pid_t.sym)
101 101 return 0;
102 102 type = get_base_type(sym);
103 103 if (type == pid_t.sym)
104 104 return 1;
105 105 return 0;
106 106 }
107 107
108 108 static const char *get_arg_type_from_type(struct symbol *sym)
109 109 {
110 110 struct symbol *type;
111 111
112 112 if (is_mode_t(sym))
113 113 return "ARG_MODE_T";
114 114 if (is_pid_t(sym))
115 115 return "ARG_PID";
116 116
117 117 type = get_real_base_type(sym);
118 118 if (!type || type->type != SYM_PTR)
119 119 return NULL;
120 120 type = get_real_base_type(type);
121 121 if (!type)
122 122 return NULL;
123 123 if (type == &char_ctype)
124 124 return "ARG_MMAP";
125 125 if (!type->ident)
126 126 return NULL;
127 127 if (strcmp(type->ident->name, "iovec") == 0)
128 128 return "ARG_IOVEC";
129 129 if (strcmp(type->ident->name, "sockaddr") == 0)
130 130 return "ARG_SOCKADDR";
131 131 return "ARG_ADDRESS";
132 132 }
133 133
134 134 static void match_fdget(const char *fn, struct expression *expr, void *unused)
135 135 {
136 136 struct expression *arg;
137 137
138 138 arg = get_argument_from_call_expr(expr->args, 0);
139 139 set_state_expr(my_id, arg, &ARG_FD);
140 140 }
141 141
142 142 const char *get_syscall_arg_type(struct symbol *sym)
143 143 {
144 144 struct smatch_state *state;
145 145 const char *type;
146 146
147 147 if (!sym || !sym->ident)
148 148 return "ARG_UNDEFINED";
149 149 type = get_arg_type_from_type(sym);
150 150 if (type)
151 151 return type;
152 152 state = get_state(my_id, sym->ident->name, sym);
153 153 if (!state)
↓ open down ↓ |
153 lines elided |
↑ open up ↑ |
154 154 return "ARG_UNDEFINED";
155 155 return state->name;
156 156 }
157 157
158 158 void check_syscall_arg_type(int id)
159 159 {
160 160 my_id = id;
161 161 if (option_project != PROJ_KERNEL)
162 162 return;
163 163
164 + set_dynamic_states(my_id);
164 165 add_merge_hook(my_id, &merge_states);
165 166 add_function_hook("fdget", &match_fdget, NULL);
166 167 }
167 168
168 169
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX