Print this page
12013 fix GCC4 as primary compiler
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_kernel_user_data.c
+++ new/usr/src/tools/smatch/src/smatch_kernel_user_data.c
1 1 /*
2 2 * Copyright (C) 2011 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 /*
19 19 * There are a couple checks that try to see if a variable
20 20 * comes from the user. It would be better to unify them
21 21 * into one place. Also it we should follow the data down
22 22 * the call paths. Hence this file.
23 23 */
24 24
25 25 #include "smatch.h"
26 26 #include "smatch_slist.h"
27 27 #include "smatch_extra.h"
28 28
29 29 static int my_id;
30 30 static int my_call_id;
31 31
32 32 STATE(called);
33 33 static bool func_gets_user_data;
34 34
35 35 static const char *kstr_funcs[] = {
36 36 "kstrtoull", "kstrtoll", "kstrtoul", "kstrtol", "kstrtouint",
37 37 "kstrtoint", "kstrtou64", "kstrtos64", "kstrtou32", "kstrtos32",
38 38 "kstrtou16", "kstrtos16", "kstrtou8", "kstrtos8", "kstrtoull_from_user"
39 39 "kstrtoll_from_user", "kstrtoul_from_user", "kstrtol_from_user",
40 40 "kstrtouint_from_user", "kstrtoint_from_user", "kstrtou16_from_user",
41 41 "kstrtos16_from_user", "kstrtou8_from_user", "kstrtos8_from_user",
42 42 "kstrtou64_from_user", "kstrtos64_from_user", "kstrtou32_from_user",
43 43 "kstrtos32_from_user",
44 44 };
45 45
46 46 static const char *returns_user_data[] = {
47 47 "simple_strtol", "simple_strtoll", "simple_strtoul", "simple_strtoull",
48 48 "kvm_register_read",
49 49 };
50 50
51 51 static const char *returns_pointer_to_user_data[] = {
52 52 "nlmsg_data", "nla_data", "memdup_user", "kmap_atomic", "skb_network_header",
53 53 };
54 54
55 55 static void set_points_to_user_data(struct expression *expr);
56 56
57 57 static struct stree *start_states;
58 58 static struct stree_stack *saved_stack;
59 59 static void save_start_states(struct statement *stmt)
60 60 {
61 61 start_states = clone_stree(__get_cur_stree());
62 62 }
63 63
64 64 static void free_start_states(void)
65 65 {
66 66 free_stree(&start_states);
67 67 }
68 68
69 69 static void match_save_states(struct expression *expr)
70 70 {
71 71 push_stree(&saved_stack, start_states);
72 72 start_states = NULL;
73 73 }
74 74
75 75 static void match_restore_states(struct expression *expr)
76 76 {
77 77 free_stree(&start_states);
78 78 start_states = pop_stree(&saved_stack);
79 79 }
80 80
81 81 static struct smatch_state *empty_state(struct sm_state *sm)
82 82 {
83 83 return alloc_estate_empty();
84 84 }
85 85
86 86 static void pre_merge_hook(struct sm_state *cur, struct sm_state *other)
87 87 {
88 88 struct smatch_state *user = cur->state;
89 89 struct smatch_state *extra;
90 90 struct smatch_state *state;
91 91 struct range_list *rl;
92 92
93 93 extra = __get_state(SMATCH_EXTRA, cur->name, cur->sym);
94 94 if (!extra)
95 95 return;
96 96 rl = rl_intersection(estate_rl(user), estate_rl(extra));
97 97 state = alloc_estate_rl(clone_rl(rl));
98 98 if (estate_capped(user) || is_capped_var_sym(cur->name, cur->sym))
99 99 estate_set_capped(state);
100 100 if (estate_treat_untagged(user))
101 101 estate_set_treat_untagged(state);
102 102 set_state(my_id, cur->name, cur->sym, state);
103 103 }
104 104
105 105 static void extra_nomod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
106 106 {
107 107 struct smatch_state *user, *new;
108 108 struct range_list *rl;
109 109
110 110 user = __get_state(my_id, name, sym);
111 111 if (!user)
112 112 return;
113 113 rl = rl_intersection(estate_rl(user), estate_rl(state));
114 114 if (rl_equiv(rl, estate_rl(user)))
115 115 return;
116 116 new = alloc_estate_rl(rl);
117 117 if (estate_capped(user))
118 118 estate_set_capped(new);
119 119 if (estate_treat_untagged(user))
120 120 estate_set_treat_untagged(new);
121 121 set_state(my_id, name, sym, new);
122 122 }
123 123
124 124 static bool binop_capped(struct expression *expr)
125 125 {
126 126 struct range_list *left_rl;
127 127 int comparison;
128 128
129 129 if (expr->op == '-' && get_user_rl(expr->left, &left_rl)) {
130 130 if (user_rl_capped(expr->left))
131 131 return true;
132 132 comparison = get_comparison(expr->left, expr->right);
133 133 if (comparison && show_special(comparison)[0] == '>')
134 134 return true;
135 135 return false;
136 136 }
137 137
138 138 if (expr->op == '&' || expr->op == '%') {
139 139 if (is_capped(expr->left) || is_capped(expr->right))
140 140 return true;
141 141 if (user_rl_capped(expr->left) || user_rl_capped(expr->right))
142 142 return true;
143 143 return false;
144 144 }
145 145
146 146 if (user_rl_capped(expr->left) &&
147 147 user_rl_capped(expr->right))
148 148 return true;
149 149 return false;
150 150 }
151 151
152 152 bool user_rl_capped(struct expression *expr)
153 153 {
154 154 struct smatch_state *state;
155 155 struct range_list *rl;
156 156 sval_t sval;
157 157
158 158 expr = strip_expr(expr);
159 159 if (!expr)
160 160 return false;
161 161 if (get_value(expr, &sval))
162 162 return true;
163 163 if (expr->type == EXPR_BINOP)
164 164 return binop_capped(expr);
165 165 if ((expr->type == EXPR_PREOP || expr->type == EXPR_POSTOP) &&
166 166 (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT))
167 167 return user_rl_capped(expr->unop);
168 168 state = get_state_expr(my_id, expr);
169 169 if (state)
170 170 return estate_capped(state);
171 171
172 172 if (get_user_rl(expr, &rl))
173 173 return false; /* uncapped user data */
174 174
175 175 return true; /* not actually user data */
176 176 }
177 177
178 178 bool user_rl_treat_untagged(struct expression *expr)
179 179 {
180 180 struct smatch_state *state;
181 181 struct range_list *rl;
182 182 sval_t sval;
183 183
184 184 expr = strip_expr(expr);
185 185 if (!expr)
186 186 return false;
187 187 if (get_value(expr, &sval))
188 188 return true;
189 189
190 190 state = get_state_expr(my_id, expr);
191 191 if (state)
192 192 return estate_treat_untagged(state);
193 193
194 194 if (get_user_rl(expr, &rl))
195 195 return false; /* uncapped user data */
196 196
197 197 return true; /* not actually user data */
198 198 }
199 199
200 200 static void tag_inner_struct_members(struct expression *expr, struct symbol *member)
201 201 {
202 202 struct expression *edge_member;
203 203 struct symbol *base = get_real_base_type(member);
204 204 struct symbol *tmp;
205 205
206 206 if (member->ident)
207 207 expr = member_expression(expr, '.', member->ident);
208 208
209 209 FOR_EACH_PTR(base->symbol_list, tmp) {
210 210 struct symbol *type;
211 211
212 212 type = get_real_base_type(tmp);
213 213 if (!type)
214 214 continue;
215 215
216 216 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
217 217 tag_inner_struct_members(expr, tmp);
218 218 continue;
219 219 }
220 220
221 221 if (!tmp->ident)
222 222 continue;
223 223
224 224 edge_member = member_expression(expr, '.', tmp->ident);
225 225 set_state_expr(my_id, edge_member, alloc_estate_whole(type));
226 226 } END_FOR_EACH_PTR(tmp);
227 227 }
228 228
229 229 static void tag_struct_members(struct symbol *type, struct expression *expr)
230 230 {
231 231 struct symbol *tmp;
232 232 struct expression *member;
233 233 int op = '*';
234 234
235 235 if (expr->type == EXPR_PREOP && expr->op == '&') {
236 236 expr = strip_expr(expr->unop);
237 237 op = '.';
238 238 }
239 239
240 240 FOR_EACH_PTR(type->symbol_list, tmp) {
241 241 type = get_real_base_type(tmp);
242 242 if (!type)
243 243 continue;
244 244
245 245 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
246 246 tag_inner_struct_members(expr, tmp);
247 247 continue;
248 248 }
249 249
250 250 if (!tmp->ident)
251 251 continue;
252 252
253 253 member = member_expression(expr, op, tmp->ident);
254 254 set_state_expr(my_id, member, alloc_estate_whole(get_type(member)));
255 255
256 256 if (type->type == SYM_ARRAY)
257 257 set_points_to_user_data(member);
258 258 } END_FOR_EACH_PTR(tmp);
259 259 }
260 260
261 261 static void tag_base_type(struct expression *expr)
262 262 {
263 263 if (expr->type == EXPR_PREOP && expr->op == '&')
264 264 expr = strip_expr(expr->unop);
265 265 else
266 266 expr = deref_expression(expr);
267 267 set_state_expr(my_id, expr, alloc_estate_whole(get_type(expr)));
268 268 }
269 269
270 270 static void tag_as_user_data(struct expression *expr)
271 271 {
272 272 struct symbol *type;
273 273
274 274 expr = strip_expr(expr);
275 275
276 276 type = get_type(expr);
277 277 if (!type || type->type != SYM_PTR)
278 278 return;
279 279 type = get_real_base_type(type);
280 280 if (!type)
281 281 return;
282 282 if (type == &void_ctype) {
283 283 set_state_expr(my_id, deref_expression(expr), alloc_estate_whole(&ulong_ctype));
284 284 return;
285 285 }
286 286 if (type->type == SYM_BASETYPE)
287 287 tag_base_type(expr);
288 288 if (type->type == SYM_STRUCT || type->type == SYM_UNION) {
289 289 if (expr->type != EXPR_PREOP || expr->op != '&')
290 290 expr = deref_expression(expr);
291 291 else
292 292 set_state_expr(my_id, deref_expression(expr), alloc_estate_whole(&ulong_ctype));
293 293 tag_struct_members(type, expr);
294 294 }
295 295 }
296 296
297 297 static void match_user_copy(const char *fn, struct expression *expr, void *_param)
298 298 {
299 299 int param = PTR_INT(_param);
300 300 struct expression *dest;
301 301
302 302 func_gets_user_data = true;
303 303
304 304 dest = get_argument_from_call_expr(expr->args, param);
305 305 dest = strip_expr(dest);
306 306 if (!dest)
307 307 return;
308 308 tag_as_user_data(dest);
309 309 }
310 310
311 311 static int is_dev_attr_name(struct expression *expr)
312 312 {
313 313 char *name;
314 314 int ret = 0;
315 315
316 316 name = expr_to_str(expr);
317 317 if (!name)
318 318 return 0;
319 319 if (strstr(name, "->attr.name"))
320 320 ret = 1;
321 321 free_string(name);
322 322 return ret;
323 323 }
324 324
325 325 static int ends_in_n(struct expression *expr)
326 326 {
327 327 struct string *str;
328 328
329 329 if (!expr)
330 330 return 0;
331 331 if (expr->type != EXPR_STRING || !expr->string)
332 332 return 0;
333 333
334 334 str = expr->string;
335 335 if (str->length < 3)
336 336 return 0;
337 337
338 338 if (str->data[str->length - 3] == '%' &&
339 339 str->data[str->length - 2] == 'n')
340 340 return 1;
341 341 return 0;
342 342 }
343 343
344 344 static void match_sscanf(const char *fn, struct expression *expr, void *unused)
345 345 {
346 346 struct expression *str, *format, *arg;
347 347 int i, last;
348 348
349 349 func_gets_user_data = true;
350 350
351 351 str = get_argument_from_call_expr(expr->args, 0);
352 352 if (is_dev_attr_name(str))
353 353 return;
354 354
355 355 format = get_argument_from_call_expr(expr->args, 1);
356 356 if (is_dev_attr_name(format))
357 357 return;
358 358
359 359 last = ptr_list_size((struct ptr_list *)expr->args) - 1;
360 360
361 361 i = -1;
362 362 FOR_EACH_PTR(expr->args, arg) {
363 363 i++;
364 364 if (i < 2)
365 365 continue;
366 366 if (i == last && ends_in_n(format))
367 367 continue;
368 368 tag_as_user_data(arg);
369 369 } END_FOR_EACH_PTR(arg);
370 370 }
371 371
372 372 static int is_skb_data(struct expression *expr)
373 373 {
374 374 struct symbol *sym;
375 375
376 376 if (!expr)
377 377 return 0;
378 378
379 379 if (expr->type == EXPR_BINOP && expr->op == '+')
380 380 return is_skb_data(expr->left);
381 381
382 382 expr = strip_expr(expr);
383 383 if (!expr)
384 384 return 0;
385 385 if (expr->type != EXPR_DEREF || expr->op != '.')
386 386 return 0;
387 387
388 388 if (!expr->member)
389 389 return 0;
390 390 if (strcmp(expr->member->name, "data") != 0)
391 391 return 0;
392 392
393 393 sym = expr_to_sym(expr->deref);
394 394 if (!sym)
395 395 return 0;
396 396 sym = get_real_base_type(sym);
397 397 if (!sym || sym->type != SYM_PTR)
398 398 return 0;
399 399 sym = get_real_base_type(sym);
400 400 if (!sym || sym->type != SYM_STRUCT || !sym->ident)
401 401 return 0;
402 402 if (strcmp(sym->ident->name, "sk_buff") != 0)
403 403 return 0;
404 404
405 405 return 1;
406 406 }
407 407
408 408 static bool is_points_to_user_data_fn(struct expression *expr)
409 409 {
410 410 int i;
411 411
412 412 expr = strip_expr(expr);
413 413 if (expr->type != EXPR_CALL || expr->fn->type != EXPR_SYMBOL ||
414 414 !expr->fn->symbol)
415 415 return false;
416 416 expr = expr->fn;
417 417 for (i = 0; i < ARRAY_SIZE(returns_pointer_to_user_data); i++) {
418 418 if (sym_name_is(returns_pointer_to_user_data[i], expr))
419 419 return true;
420 420 }
421 421 return false;
422 422 }
423 423
424 424 static int get_rl_from_function(struct expression *expr, struct range_list **rl)
425 425 {
426 426 int i;
427 427
428 428 if (expr->type != EXPR_CALL || expr->fn->type != EXPR_SYMBOL ||
429 429 !expr->fn->symbol_name || !expr->fn->symbol_name->name)
430 430 return 0;
431 431
432 432 for (i = 0; i < ARRAY_SIZE(returns_user_data); i++) {
433 433 if (strcmp(expr->fn->symbol_name->name, returns_user_data[i]) == 0) {
434 434 *rl = alloc_whole_rl(get_type(expr));
435 435 return 1;
436 436 }
437 437 }
438 438 return 0;
439 439 }
440 440
441 441 int points_to_user_data(struct expression *expr)
442 442 {
443 443 struct smatch_state *state;
444 444 struct range_list *rl;
445 445 char buf[256];
446 446 struct symbol *sym;
447 447 char *name;
448 448 int ret = 0;
449 449
450 450 expr = strip_expr(expr);
451 451 if (!expr)
452 452 return 0;
453 453 if (is_skb_data(expr))
454 454 return 1;
455 455 if (is_points_to_user_data_fn(expr))
456 456 return 1;
457 457 if (get_rl_from_function(expr, &rl))
458 458 return 1;
459 459
460 460 if (expr->type == EXPR_BINOP && expr->op == '+') {
461 461 if (points_to_user_data(expr->left))
462 462 return 1;
463 463 if (points_to_user_data(expr->right))
464 464 return 1;
465 465 return 0;
466 466 }
467 467
468 468 name = expr_to_var_sym(expr, &sym);
469 469 if (!name || !sym)
470 470 goto free;
471 471 snprintf(buf, sizeof(buf), "*%s", name);
472 472 state = __get_state(my_id, buf, sym);
473 473 if (state && estate_rl(state))
474 474 ret = 1;
475 475 free:
476 476 free_string(name);
477 477 return ret;
478 478 }
479 479
480 480 static void set_points_to_user_data(struct expression *expr)
481 481 {
482 482 char *name;
483 483 struct symbol *sym;
484 484 char buf[256];
485 485 struct symbol *type;
486 486
487 487 name = expr_to_var_sym(expr, &sym);
488 488 if (!name || !sym)
489 489 goto free;
490 490 snprintf(buf, sizeof(buf), "*%s", name);
491 491 type = get_type(expr);
492 492 if (type && type->type == SYM_PTR)
493 493 type = get_real_base_type(type);
494 494 if (!type || type->type != SYM_BASETYPE)
495 495 type = &llong_ctype;
496 496 set_state(my_id, buf, sym, alloc_estate_whole(type));
497 497 free:
498 498 free_string(name);
499 499 }
500 500
501 501 static int comes_from_skb_data(struct expression *expr)
502 502 {
503 503 expr = strip_expr(expr);
504 504 if (!expr || expr->type != EXPR_PREOP || expr->op != '*')
505 505 return 0;
506 506
507 507 expr = strip_expr(expr->unop);
508 508 if (!expr)
509 509 return 0;
510 510 if (expr->type == EXPR_BINOP && expr->op == '+')
511 511 expr = strip_expr(expr->left);
512 512
513 513 return is_skb_data(expr);
514 514 }
515 515
516 516 static int handle_struct_assignment(struct expression *expr)
517 517 {
518 518 struct expression *right;
519 519 struct symbol *left_type, *right_type;
520 520
521 521 left_type = get_type(expr->left);
522 522 if (!left_type || left_type->type != SYM_PTR)
523 523 return 0;
524 524 left_type = get_real_base_type(left_type);
525 525 if (!left_type)
526 526 return 0;
527 527 if (left_type->type != SYM_STRUCT &&
528 528 left_type->type != SYM_UNION)
529 529 return 0;
530 530
531 531 /*
532 532 * Ignore struct to struct assignments because for those we look at the
533 533 * individual members.
534 534 */
535 535 right = strip_expr(expr->right);
536 536 right_type = get_type(right);
537 537 if (!right_type || right_type->type != SYM_PTR)
538 538 return 0;
539 539
540 540 /* If we are assigning struct members then normally that is handled
541 541 * by fake assignments, however if we cast one struct to a different
542 542 * of struct then we handle that here.
543 543 */
544 544 right_type = get_real_base_type(right_type);
545 545 if (right_type == left_type)
546 546 return 0;
547 547
548 548 if (!points_to_user_data(right))
549 549 return 0;
550 550
551 551 tag_as_user_data(expr->left);
552 552 return 1;
553 553 }
554 554
555 555 static int handle_get_user(struct expression *expr)
556 556 {
557 557 char *name;
558 558 int ret = 0;
559 559
560 560 name = get_macro_name(expr->pos);
561 561 if (!name || strcmp(name, "get_user") != 0)
562 562 return 0;
563 563
564 564 name = expr_to_var(expr->right);
565 565 if (!name || (strcmp(name, "__val_gu") != 0 && strcmp(name, "__gu_val") != 0))
566 566 goto free;
567 567 set_state_expr(my_id, expr->left, alloc_estate_whole(get_type(expr->left)));
568 568 ret = 1;
569 569 free:
570 570 free_string(name);
571 571 return ret;
572 572 }
573 573
574 574 static bool handle_op_assign(struct expression *expr)
575 575 {
576 576 struct expression *binop_expr;
577 577 struct smatch_state *state;
578 578 struct range_list *rl;
579 579
580 580 switch (expr->op) {
581 581 case SPECIAL_ADD_ASSIGN:
582 582 case SPECIAL_SUB_ASSIGN:
583 583 case SPECIAL_AND_ASSIGN:
584 584 case SPECIAL_MOD_ASSIGN:
585 585 case SPECIAL_SHL_ASSIGN:
586 586 case SPECIAL_SHR_ASSIGN:
587 587 case SPECIAL_OR_ASSIGN:
588 588 case SPECIAL_XOR_ASSIGN:
589 589 case SPECIAL_MUL_ASSIGN:
590 590 case SPECIAL_DIV_ASSIGN:
591 591 binop_expr = binop_expression(expr->left,
592 592 op_remove_assign(expr->op),
593 593 expr->right);
594 594 if (!get_user_rl(binop_expr, &rl))
595 595 return true;
596 596
597 597 rl = cast_rl(get_type(expr->left), rl);
598 598 state = alloc_estate_rl(rl);
599 599 if (user_rl_capped(binop_expr))
600 600 estate_set_capped(state);
601 601 if (user_rl_treat_untagged(expr->left))
602 602 estate_set_treat_untagged(state);
603 603 set_state_expr(my_id, expr->left, state);
604 604 return true;
605 605 }
606 606 return false;
607 607 }
608 608
609 609 static void match_assign(struct expression *expr)
610 610 {
611 611 struct range_list *rl;
612 612 static struct expression *handled;
613 613 struct smatch_state *state;
614 614 struct expression *faked;
615 615
616 616 faked = get_faked_expression();
617 617 if (faked && faked == handled)
618 618 return;
619 619 if (is_fake_call(expr->right))
620 620 goto clear_old_state;
621 621 if (handle_get_user(expr))
622 622 return;
623 623 if (points_to_user_data(expr->right)) {
624 624 handled = expr;
625 625 set_points_to_user_data(expr->left);
626 626 }
627 627 if (handle_struct_assignment(expr))
628 628 return;
629 629
630 630 if (handle_op_assign(expr))
631 631 return;
632 632 if (expr->op != '=')
633 633 goto clear_old_state;
634 634
635 635 /* Handled by DB code */
636 636 if (expr->right->type == EXPR_CALL || __in_fake_parameter_assign)
637 637 return;
638 638
639 639 if (!get_user_rl(expr->right, &rl))
640 640 goto clear_old_state;
641 641
642 642 rl = cast_rl(get_type(expr->left), rl);
643 643 state = alloc_estate_rl(rl);
644 644
645 645 if (user_rl_capped(expr->right))
646 646 estate_set_capped(state);
647 647 if (user_rl_treat_untagged(expr->right))
648 648 estate_set_treat_untagged(state);
649 649 set_state_expr(my_id, expr->left, state);
650 650
651 651 return;
652 652
653 653 clear_old_state:
654 654 if (get_state_expr(my_id, expr->left))
655 655 set_state_expr(my_id, expr->left, alloc_estate_empty());
656 656 }
657 657
658 658 static void handle_eq_noteq(struct expression *expr)
659 659 {
660 660 struct smatch_state *left_orig, *right_orig;
661 661
662 662 left_orig = get_state_expr(my_id, expr->left);
663 663 right_orig = get_state_expr(my_id, expr->right);
664 664
665 665 if (!left_orig && !right_orig)
666 666 return;
667 667 if (left_orig && right_orig)
668 668 return;
669 669
670 670 if (left_orig) {
671 671 set_true_false_states_expr(my_id, expr->left,
672 672 expr->op == SPECIAL_EQUAL ? alloc_estate_empty() : NULL,
673 673 expr->op == SPECIAL_EQUAL ? NULL : alloc_estate_empty());
↓ open down ↓ |
673 lines elided |
↑ open up ↑ |
674 674 } else {
675 675 set_true_false_states_expr(my_id, expr->right,
676 676 expr->op == SPECIAL_EQUAL ? alloc_estate_empty() : NULL,
677 677 expr->op == SPECIAL_EQUAL ? NULL : alloc_estate_empty());
678 678 }
679 679 }
680 680
681 681 static struct range_list *strip_negatives(struct range_list *rl)
682 682 {
683 683 sval_t min = rl_min(rl);
684 - sval_t minus_one = { .type = rl_type(rl), .value = -1 };
685 - sval_t over = { .type = rl_type(rl), .value = INT_MAX + 1ULL };
684 + sval_t minus_one;
685 + sval_t over;
686 686 sval_t max = sval_type_max(rl_type(rl));
687 687
688 + minus_one.type = rl_type(rl);
689 + minus_one.value = -1;
690 + over.type = rl_type(rl);
691 + over.value = INT_MAX + 1ULL;
692 +
688 693 if (!rl)
689 694 return NULL;
690 695
691 696 if (type_unsigned(rl_type(rl)) && type_bits(rl_type(rl)) > 31)
692 697 return remove_range(rl, over, max);
693 698
694 699 return remove_range(rl, min, minus_one);
695 700 }
696 701
697 702 static void handle_compare(struct expression *expr)
698 703 {
699 704 struct expression *left, *right;
700 705 struct range_list *left_rl = NULL;
701 706 struct range_list *right_rl = NULL;
702 707 struct range_list *user_rl;
703 708 struct smatch_state *capped_state;
704 709 struct smatch_state *left_true = NULL;
705 710 struct smatch_state *left_false = NULL;
706 711 struct smatch_state *right_true = NULL;
707 712 struct smatch_state *right_false = NULL;
708 713 struct symbol *type;
709 714 sval_t sval;
710 715
711 716 left = strip_expr(expr->left);
712 717 right = strip_expr(expr->right);
713 718
714 719 while (left->type == EXPR_ASSIGNMENT)
715 720 left = strip_expr(left->left);
716 721
717 722 /*
718 723 * Conditions are mostly handled by smatch_extra.c, but there are some
719 724 * times where the exact values are not known so we can't do that.
720 725 *
721 726 * Normally, we might consider using smatch_capped.c to supliment smatch
722 727 * extra but that doesn't work when we merge unknown uncapped kernel
723 728 * data with unknown capped user data. The result is uncapped user
724 729 * data. We need to keep it separate and say that the user data is
725 730 * capped. In the past, I would have marked this as just regular
726 731 * kernel data (not user data) but we can't do that these days because
727 732 * we need to track user data for Spectre.
728 733 *
729 734 * The other situation which we have to handle is when we do have an
730 735 * int and we compare against an unknown unsigned kernel variable. In
731 736 * that situation we assume that the kernel data is less than INT_MAX.
732 737 * Otherwise then we get all sorts of array underflow false positives.
733 738 *
734 739 */
735 740
736 741 /* Handled in smatch_extra.c */
737 742 if (get_implied_value(left, &sval) ||
738 743 get_implied_value(right, &sval))
739 744 return;
740 745
741 746 get_user_rl(left, &left_rl);
742 747 get_user_rl(right, &right_rl);
743 748
744 749 /* nothing to do */
745 750 if (!left_rl && !right_rl)
746 751 return;
747 752 /* if both sides are user data that's not a good limit */
748 753 if (left_rl && right_rl)
749 754 return;
750 755
751 756 if (left_rl)
752 757 user_rl = left_rl;
753 758 else
754 759 user_rl = right_rl;
755 760
756 761 type = get_type(expr);
757 762 if (type_unsigned(type))
758 763 user_rl = strip_negatives(user_rl);
759 764 capped_state = alloc_estate_rl(user_rl);
760 765 estate_set_capped(capped_state);
761 766
762 767 switch (expr->op) {
763 768 case '<':
764 769 case SPECIAL_UNSIGNED_LT:
765 770 case SPECIAL_LTE:
766 771 case SPECIAL_UNSIGNED_LTE:
767 772 if (left_rl)
768 773 left_true = capped_state;
769 774 else
770 775 right_false = capped_state;
771 776 break;
772 777 case '>':
773 778 case SPECIAL_UNSIGNED_GT:
774 779 case SPECIAL_GTE:
775 780 case SPECIAL_UNSIGNED_GTE:
776 781 if (left_rl)
777 782 left_false = capped_state;
778 783 else
779 784 right_true = capped_state;
780 785 break;
781 786 }
782 787
783 788 set_true_false_states_expr(my_id, left, left_true, left_false);
784 789 set_true_false_states_expr(my_id, right, right_true, right_false);
785 790 }
786 791
787 792 static void match_condition(struct expression *expr)
788 793 {
789 794 if (expr->type != EXPR_COMPARE)
790 795 return;
791 796
792 797 if (expr->op == SPECIAL_EQUAL ||
793 798 expr->op == SPECIAL_NOTEQUAL) {
794 799 handle_eq_noteq(expr);
795 800 return;
796 801 }
797 802
798 803 handle_compare(expr);
799 804 }
800 805
801 806 static void match_user_assign_function(const char *fn, struct expression *expr, void *unused)
802 807 {
803 808 tag_as_user_data(expr->left);
804 809 set_points_to_user_data(expr->left);
805 810 }
806 811
807 812 static void match_returns_user_rl(const char *fn, struct expression *expr, void *unused)
808 813 {
809 814 func_gets_user_data = true;
810 815 }
811 816
812 817 static int get_user_macro_rl(struct expression *expr, struct range_list **rl)
813 818 {
814 819 struct expression *parent;
815 820 char *macro;
816 821
817 822 if (!expr)
818 823 return 0;
819 824
820 825 macro = get_macro_name(expr->pos);
821 826 if (!macro)
822 827 return 0;
823 828
824 829 /* handle ntohl(foo[i]) where "i" is trusted */
825 830 parent = expr_get_parent_expr(expr);
826 831 while (parent && parent->type != EXPR_BINOP)
827 832 parent = expr_get_parent_expr(parent);
828 833 if (parent && parent->type == EXPR_BINOP) {
829 834 char *parent_macro = get_macro_name(parent->pos);
830 835
831 836 if (parent_macro && strcmp(macro, parent_macro) == 0)
832 837 return 0;
833 838 }
834 839
835 840 if (strcmp(macro, "ntohl") == 0) {
836 841 *rl = alloc_whole_rl(&uint_ctype);
837 842 return 1;
838 843 }
839 844 if (strcmp(macro, "ntohs") == 0) {
840 845 *rl = alloc_whole_rl(&ushort_ctype);
841 846 return 1;
842 847 }
843 848 return 0;
844 849 }
845 850
846 851 static int has_user_data(struct symbol *sym)
847 852 {
848 853 struct sm_state *tmp;
849 854
850 855 FOR_EACH_MY_SM(my_id, __get_cur_stree(), tmp) {
851 856 if (tmp->sym == sym)
852 857 return 1;
853 858 } END_FOR_EACH_SM(tmp);
854 859 return 0;
855 860 }
856 861
857 862 static int we_pass_user_data(struct expression *call)
858 863 {
859 864 struct expression *arg;
860 865 struct symbol *sym;
861 866
862 867 FOR_EACH_PTR(call->args, arg) {
863 868 sym = expr_to_sym(arg);
864 869 if (!sym)
865 870 continue;
866 871 if (has_user_data(sym))
867 872 return 1;
868 873 } END_FOR_EACH_PTR(arg);
869 874
870 875 return 0;
871 876 }
872 877
873 878 static int db_returned_user_rl(struct expression *call, struct range_list **rl)
874 879 {
875 880 struct smatch_state *state;
876 881 char buf[48];
877 882
878 883 if (is_fake_call(call))
879 884 return 0;
880 885 snprintf(buf, sizeof(buf), "return %p", call);
881 886 state = get_state(my_id, buf, NULL);
882 887 if (!state || !estate_rl(state))
883 888 return 0;
884 889 *rl = estate_rl(state);
885 890 return 1;
886 891 }
887 892
888 893 struct stree *get_user_stree(void)
889 894 {
890 895 return get_all_states_stree(my_id);
891 896 }
892 897
893 898 static int user_data_flag;
894 899 static int no_user_data_flag;
895 900 struct range_list *var_user_rl(struct expression *expr)
896 901 {
897 902 struct smatch_state *state;
898 903 struct range_list *rl;
899 904 struct range_list *absolute_rl;
900 905
901 906 if (expr->type == EXPR_PREOP && expr->op == '&') {
902 907 no_user_data_flag = 1;
903 908 return NULL;
904 909 }
905 910
906 911 if (expr->type == EXPR_BINOP && expr->op == '%') {
907 912 struct range_list *left, *right;
908 913
909 914 if (!get_user_rl(expr->right, &right))
910 915 return NULL;
911 916 get_absolute_rl(expr->left, &left);
912 917 rl = rl_binop(left, '%', right);
913 918 goto found;
914 919 }
915 920
916 921 if (expr->type == EXPR_BINOP && expr->op == '/') {
917 922 struct range_list *left = NULL;
918 923 struct range_list *right = NULL;
919 924 struct range_list *abs_right;
920 925
921 926 /*
922 927 * The specific bug I'm dealing with is:
923 928 *
924 929 * foo = capped_user / unknown;
925 930 *
926 931 * Instead of just saying foo is now entirely user_rl we should
927 932 * probably say instead that it is not at all user data.
928 933 *
929 934 */
930 935
931 936 get_user_rl(expr->left, &left);
932 937 get_user_rl(expr->right, &right);
933 938 get_absolute_rl(expr->right, &abs_right);
934 939
935 940 if (left && !right) {
936 941 rl = rl_binop(left, '/', abs_right);
937 942 if (sval_cmp(rl_max(left), rl_max(rl)) < 0)
938 943 no_user_data_flag = 1;
939 944 }
940 945
941 946 return NULL;
942 947 }
943 948
944 949 if (get_rl_from_function(expr, &rl))
945 950 goto found;
946 951
947 952 if (get_user_macro_rl(expr, &rl))
948 953 goto found;
949 954
950 955 if (comes_from_skb_data(expr)) {
951 956 rl = alloc_whole_rl(get_type(expr));
952 957 goto found;
953 958 }
954 959
955 960 state = get_state_expr(my_id, expr);
956 961 if (state && estate_rl(state)) {
957 962 rl = estate_rl(state);
958 963 goto found;
959 964 }
960 965
961 966 if (expr->type == EXPR_CALL && db_returned_user_rl(expr, &rl))
962 967 goto found;
963 968
964 969 if (is_array(expr)) {
965 970 struct expression *array = get_array_base(expr);
966 971
967 972 if (!get_state_expr(my_id, array)) {
968 973 no_user_data_flag = 1;
969 974 return NULL;
970 975 }
971 976 }
972 977
973 978 if (expr->type == EXPR_PREOP && expr->op == '*' &&
974 979 is_user_rl(expr->unop)) {
975 980 rl = var_to_absolute_rl(expr);
976 981 goto found;
977 982 }
978 983
979 984 return NULL;
980 985 found:
981 986 user_data_flag = 1;
982 987 absolute_rl = var_to_absolute_rl(expr);
983 988 return clone_rl(rl_intersection(rl, absolute_rl));
984 989 }
985 990
986 991 static bool is_ptr_subtract(struct expression *expr)
987 992 {
988 993 expr = strip_expr(expr);
989 994 if (!expr)
990 995 return false;
991 996 if (expr->type == EXPR_BINOP && expr->op == '-' &&
992 997 type_is_ptr(get_type(expr->left))) {
993 998 return true;
994 999 }
995 1000 return false;
996 1001 }
997 1002
998 1003 int get_user_rl(struct expression *expr, struct range_list **rl)
999 1004 {
1000 1005 if (is_ptr_subtract(expr))
1001 1006 return 0;
1002 1007
1003 1008 user_data_flag = 0;
1004 1009 no_user_data_flag = 0;
1005 1010 custom_get_absolute_rl(expr, &var_user_rl, rl);
1006 1011 if (!user_data_flag || no_user_data_flag)
1007 1012 *rl = NULL;
1008 1013
1009 1014 return !!*rl;
1010 1015 }
1011 1016
1012 1017 int is_user_rl(struct expression *expr)
1013 1018 {
1014 1019 struct range_list *tmp;
1015 1020
1016 1021 return !!get_user_rl(expr, &tmp);
1017 1022 }
1018 1023
1019 1024 int get_user_rl_var_sym(const char *name, struct symbol *sym, struct range_list **rl)
1020 1025 {
1021 1026 struct smatch_state *state;
1022 1027
1023 1028 state = get_state(my_id, name, sym);
1024 1029 if (state && estate_rl(state)) {
1025 1030 *rl = estate_rl(state);
1026 1031 return 1;
1027 1032 }
1028 1033 return 0;
1029 1034 }
1030 1035
1031 1036 static char *get_user_rl_str(struct expression *expr, struct symbol *type)
1032 1037 {
1033 1038 struct range_list *rl;
1034 1039 static char buf[64];
1035 1040
1036 1041 if (!get_user_rl(expr, &rl))
1037 1042 return NULL;
1038 1043 rl = cast_rl(type, rl);
1039 1044 snprintf(buf, sizeof(buf), "%s%s%s",
1040 1045 show_rl(rl),
1041 1046 user_rl_capped(expr) ? "[c]" : "",
1042 1047 user_rl_treat_untagged(expr) ? "[u]" : "");
1043 1048 return buf;
1044 1049 }
1045 1050
1046 1051 static void match_call_info(struct expression *expr)
1047 1052 {
1048 1053 struct expression *arg;
1049 1054 struct symbol *type;
1050 1055 char *str;
1051 1056 int i;
1052 1057
1053 1058 i = -1;
1054 1059 FOR_EACH_PTR(expr->args, arg) {
1055 1060 i++;
1056 1061 type = get_arg_type(expr->fn, i);
1057 1062 str = get_user_rl_str(arg, type);
1058 1063 if (!str)
1059 1064 continue;
1060 1065
1061 1066 sql_insert_caller_info(expr, USER_DATA, i, "$", str);
1062 1067 } END_FOR_EACH_PTR(arg);
1063 1068 }
1064 1069
1065 1070 static int is_struct_ptr(struct symbol *sym)
1066 1071 {
1067 1072 struct symbol *type;
1068 1073
1069 1074 if (!sym)
1070 1075 return 0;
1071 1076 type = get_real_base_type(sym);
1072 1077 if (!type || type->type != SYM_PTR)
1073 1078 return 0;
1074 1079 type = get_real_base_type(type);
1075 1080 if (!type || type->type != SYM_STRUCT)
1076 1081 return 0;
1077 1082 return 1;
1078 1083 }
1079 1084
1080 1085 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
1081 1086 {
1082 1087 struct smatch_state *state;
1083 1088 struct range_list *rl;
1084 1089 struct symbol *type;
1085 1090 char buf[64];
1086 1091
1087 1092 /*
1088 1093 * Smatch uses a hack where if we get an unsigned long we say it's
1089 1094 * both user data and it points to user data. But if we pass it to a
1090 1095 * function which takes an int, then it's just user data. There's not
1091 1096 * enough bytes for it to be a pointer.
1092 1097 *
1093 1098 */
1094 1099 type = get_arg_type(call->fn, param);
1095 1100 if (type && type_bits(type) < type_bits(&ptr_ctype))
1096 1101 return;
1097 1102
1098 1103 if (strcmp(sm->state->name, "") == 0)
1099 1104 return;
1100 1105
1101 1106 if (strcmp(printed_name, "*$") == 0 &&
1102 1107 is_struct_ptr(sm->sym))
1103 1108 return;
1104 1109
1105 1110 state = __get_state(SMATCH_EXTRA, sm->name, sm->sym);
1106 1111 if (!state || !estate_rl(state))
1107 1112 rl = estate_rl(sm->state);
1108 1113 else
1109 1114 rl = rl_intersection(estate_rl(sm->state), estate_rl(state));
1110 1115
1111 1116 if (!rl)
1112 1117 return;
1113 1118
1114 1119 snprintf(buf, sizeof(buf), "%s%s%s", show_rl(rl),
1115 1120 estate_capped(sm->state) ? "[c]" : "",
1116 1121 estate_treat_untagged(sm->state) ? "[u]" : "");
1117 1122 sql_insert_caller_info(call, USER_DATA, param, printed_name, buf);
1118 1123 }
1119 1124
1120 1125 static void db_param_set(struct expression *expr, int param, char *key, char *value)
1121 1126 {
1122 1127 struct expression *arg;
1123 1128 char *name;
1124 1129 struct symbol *sym;
1125 1130 struct smatch_state *state;
1126 1131
1127 1132 while (expr->type == EXPR_ASSIGNMENT)
1128 1133 expr = strip_expr(expr->right);
1129 1134 if (expr->type != EXPR_CALL)
1130 1135 return;
1131 1136
1132 1137 arg = get_argument_from_call_expr(expr->args, param);
1133 1138 if (!arg)
1134 1139 return;
1135 1140 name = get_variable_from_key(arg, key, &sym);
1136 1141 if (!name || !sym)
1137 1142 goto free;
1138 1143
1139 1144 state = get_state(my_id, name, sym);
1140 1145 if (!state)
1141 1146 goto free;
1142 1147
1143 1148 set_state(my_id, name, sym, alloc_estate_empty());
1144 1149 free:
1145 1150 free_string(name);
1146 1151 }
1147 1152
1148 1153 static bool param_data_capped(const char *value)
1149 1154 {
1150 1155 if (strstr(value, ",c") || strstr(value, "[c"))
1151 1156 return true;
1152 1157 return false;
1153 1158 }
1154 1159
1155 1160 static bool param_data_treat_untagged(const char *value)
1156 1161 {
1157 1162 if (strstr(value, ",u") || strstr(value, "[u"))
1158 1163 return true;
1159 1164 return false;
1160 1165 }
1161 1166
1162 1167 static void set_param_user_data(const char *name, struct symbol *sym, char *key, char *value)
1163 1168 {
1164 1169 struct range_list *rl = NULL;
1165 1170 struct smatch_state *state;
1166 1171 struct expression *expr;
1167 1172 struct symbol *type;
1168 1173 char fullname[256];
1169 1174 char *key_orig = key;
1170 1175 bool add_star = false;
1171 1176
1172 1177 if (strcmp(key, "**$") == 0) {
1173 1178 snprintf(fullname, sizeof(fullname), "**%s", name);
1174 1179 } else {
1175 1180 if (key[0] == '*') {
1176 1181 add_star = true;
1177 1182 key++;
1178 1183 }
1179 1184
1180 1185 snprintf(fullname, 256, "%s%s%s", add_star ? "*" : "", name, key + 1);
1181 1186 }
1182 1187
1183 1188 expr = symbol_expression(sym);
1184 1189 type = get_member_type_from_key(expr, key_orig);
1185 1190
1186 1191 /*
1187 1192 * Say this function takes a struct ponter but the caller passes
1188 1193 * this_function(skb->data). We have two options, we could pass *$
1189 1194 * as user data or we could pass foo->bar, foo->baz as user data.
1190 1195 * The second option is easier to implement so we do that.
1191 1196 *
1192 1197 */
1193 1198 if (strcmp(key_orig, "*$") == 0) {
1194 1199 struct symbol *tmp = type;
1195 1200
1196 1201 while (tmp && tmp->type == SYM_PTR)
1197 1202 tmp = get_real_base_type(tmp);
1198 1203
1199 1204 if (tmp && (tmp->type == SYM_STRUCT || tmp->type == SYM_UNION)) {
1200 1205 tag_as_user_data(symbol_expression(sym));
1201 1206 return;
1202 1207 }
1203 1208 }
1204 1209
1205 1210 str_to_rl(type, value, &rl);
1206 1211 state = alloc_estate_rl(rl);
1207 1212 if (param_data_capped(value) || is_capped(expr))
1208 1213 estate_set_capped(state);
1209 1214 if (param_data_treat_untagged(value) || sym->ctype.as == 5)
1210 1215 estate_set_treat_untagged(state);
1211 1216 set_state(my_id, fullname, sym, state);
1212 1217 }
1213 1218
1214 1219 static void set_called(const char *name, struct symbol *sym, char *key, char *value)
1215 1220 {
1216 1221 set_state(my_call_id, "this_function", NULL, &called);
1217 1222 }
1218 1223
1219 1224 static void match_syscall_definition(struct symbol *sym)
1220 1225 {
1221 1226 struct symbol *arg;
1222 1227 char *macro;
1223 1228 char *name;
1224 1229 int is_syscall = 0;
1225 1230
1226 1231 macro = get_macro_name(sym->pos);
1227 1232 if (macro &&
1228 1233 (strncmp("SYSCALL_DEFINE", macro, strlen("SYSCALL_DEFINE")) == 0 ||
1229 1234 strncmp("COMPAT_SYSCALL_DEFINE", macro, strlen("COMPAT_SYSCALL_DEFINE")) == 0))
1230 1235 is_syscall = 1;
1231 1236
1232 1237 name = get_function();
1233 1238 if (!option_no_db && get_state(my_call_id, "this_function", NULL) != &called) {
1234 1239 if (name && strncmp(name, "sys_", 4) == 0)
1235 1240 is_syscall = 1;
1236 1241 }
1237 1242
1238 1243 if (name && strncmp(name, "compat_sys_", 11) == 0)
1239 1244 is_syscall = 1;
1240 1245
1241 1246 if (!is_syscall)
1242 1247 return;
1243 1248
1244 1249 FOR_EACH_PTR(sym->ctype.base_type->arguments, arg) {
1245 1250 set_state(my_id, arg->ident->name, arg, alloc_estate_whole(get_real_base_type(arg)));
1246 1251 } END_FOR_EACH_PTR(arg);
1247 1252 }
1248 1253
1249 1254 static void store_user_data_return(struct expression *expr, char *key, char *value)
1250 1255 {
1251 1256 struct range_list *rl;
1252 1257 struct symbol *type;
1253 1258 char buf[48];
1254 1259
1255 1260 if (strcmp(key, "$") != 0)
1256 1261 return;
1257 1262
1258 1263 type = get_type(expr);
1259 1264 snprintf(buf, sizeof(buf), "return %p", expr);
1260 1265 call_results_to_rl(expr, type, value, &rl);
1261 1266
1262 1267 set_state(my_id, buf, NULL, alloc_estate_rl(rl));
1263 1268 }
1264 1269
1265 1270 static void set_to_user_data(struct expression *expr, char *key, char *value)
1266 1271 {
1267 1272 struct smatch_state *state;
1268 1273 char *name;
1269 1274 struct symbol *sym;
1270 1275 struct symbol *type;
1271 1276 struct range_list *rl = NULL;
1272 1277
1273 1278 type = get_member_type_from_key(expr, key);
1274 1279 name = get_variable_from_key(expr, key, &sym);
1275 1280 if (!name || !sym)
1276 1281 goto free;
1277 1282
1278 1283 call_results_to_rl(expr, type, value, &rl);
1279 1284
1280 1285 state = alloc_estate_rl(rl);
1281 1286 if (param_data_capped(value))
1282 1287 estate_set_capped(state);
1283 1288 if (param_data_treat_untagged(value))
1284 1289 estate_set_treat_untagged(state);
1285 1290 set_state(my_id, name, sym, state);
1286 1291 free:
1287 1292 free_string(name);
1288 1293 }
1289 1294
1290 1295 static void returns_param_user_data(struct expression *expr, int param, char *key, char *value)
1291 1296 {
1292 1297 struct expression *arg;
1293 1298 struct expression *call;
1294 1299
1295 1300 call = expr;
1296 1301 while (call->type == EXPR_ASSIGNMENT)
1297 1302 call = strip_expr(call->right);
1298 1303 if (call->type != EXPR_CALL)
1299 1304 return;
1300 1305
1301 1306 if (!we_pass_user_data(call))
1302 1307 return;
1303 1308
1304 1309 if (param == -1) {
1305 1310 if (expr->type != EXPR_ASSIGNMENT) {
1306 1311 store_user_data_return(expr, key, value);
1307 1312 return;
1308 1313 }
1309 1314 set_to_user_data(expr->left, key, value);
1310 1315 return;
1311 1316 }
1312 1317
1313 1318 arg = get_argument_from_call_expr(call->args, param);
1314 1319 if (!arg)
1315 1320 return;
1316 1321 set_to_user_data(arg, key, value);
1317 1322 }
1318 1323
1319 1324 static void returns_param_user_data_set(struct expression *expr, int param, char *key, char *value)
1320 1325 {
1321 1326 struct expression *arg;
1322 1327
1323 1328 func_gets_user_data = true;
1324 1329
1325 1330 if (param == -1) {
1326 1331 if (expr->type != EXPR_ASSIGNMENT) {
1327 1332 store_user_data_return(expr, key, value);
1328 1333 return;
1329 1334 }
1330 1335 if (strcmp(key, "*$") == 0) {
1331 1336 set_points_to_user_data(expr->left);
1332 1337 tag_as_user_data(expr->left);
1333 1338 } else {
1334 1339 set_to_user_data(expr->left, key, value);
1335 1340 }
1336 1341 return;
1337 1342 }
1338 1343
1339 1344 while (expr->type == EXPR_ASSIGNMENT)
1340 1345 expr = strip_expr(expr->right);
1341 1346 if (expr->type != EXPR_CALL)
1342 1347 return;
1343 1348
1344 1349 arg = get_argument_from_call_expr(expr->args, param);
1345 1350 if (!arg)
1346 1351 return;
1347 1352 set_to_user_data(arg, key, value);
1348 1353 }
1349 1354
1350 1355 static void param_set_to_user_data(int return_id, char *return_ranges, struct expression *expr)
1351 1356 {
1352 1357 struct sm_state *sm;
1353 1358 struct smatch_state *start_state;
1354 1359 struct range_list *rl;
1355 1360 int param;
1356 1361 char *return_str;
1357 1362 const char *param_name;
1358 1363 struct symbol *ret_sym;
1359 1364 bool return_found = false;
1360 1365 bool pointed_at_found = false;
1361 1366 char buf[64];
1362 1367
1363 1368 expr = strip_expr(expr);
1364 1369 return_str = expr_to_str(expr);
1365 1370 ret_sym = expr_to_sym(expr);
1366 1371
1367 1372 FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
1368 1373 param = get_param_num_from_sym(sm->sym);
1369 1374 if (param < 0)
1370 1375 continue;
1371 1376
1372 1377 if (!param_was_set_var_sym(sm->name, sm->sym))
1373 1378 continue;
1374 1379
1375 1380 /* The logic here was that if we were passed in a user data then
1376 1381 * we don't record that. It's like the difference between
1377 1382 * param_filter and param_set. When I think about it, I'm not
1378 1383 * sure it actually works. It's probably harmless because we
1379 1384 * checked earlier that we're not returning a parameter...
1380 1385 * Let's mark this as a TODO.
1381 1386 */
1382 1387 start_state = get_state_stree(start_states, my_id, sm->name, sm->sym);
1383 1388 if (start_state && rl_equiv(estate_rl(sm->state), estate_rl(start_state)))
1384 1389 continue;
1385 1390
1386 1391 param_name = get_param_name(sm);
1387 1392 if (!param_name)
1388 1393 continue;
1389 1394 if (strcmp(param_name, "$") == 0) /* The -1 param is handled after the loop */
1390 1395 continue;
1391 1396
1392 1397 snprintf(buf, sizeof(buf), "%s%s%s",
1393 1398 show_rl(estate_rl(sm->state)),
1394 1399 estate_capped(sm->state) ? "[c]" : "",
1395 1400 estate_treat_untagged(sm->state) ? "[u]" : "");
1396 1401 sql_insert_return_states(return_id, return_ranges,
1397 1402 func_gets_user_data ? USER_DATA_SET : USER_DATA,
1398 1403 param, param_name, buf);
1399 1404 } END_FOR_EACH_SM(sm);
1400 1405
1401 1406 /* This if for "return foo;" where "foo->bar" is user data. */
1402 1407 FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
1403 1408 if (!ret_sym)
1404 1409 break;
1405 1410 if (ret_sym != sm->sym)
1406 1411 continue;
1407 1412
1408 1413 param_name = state_name_to_param_name(sm->name, return_str);
1409 1414 if (!param_name)
1410 1415 continue;
1411 1416 if (strcmp(param_name, "$") == 0)
1412 1417 return_found = true;
1413 1418 if (strcmp(param_name, "*$") == 0)
1414 1419 pointed_at_found = true;
1415 1420 snprintf(buf, sizeof(buf), "%s%s%s",
1416 1421 show_rl(estate_rl(sm->state)),
1417 1422 estate_capped(sm->state) ? "[c]" : "",
1418 1423 estate_treat_untagged(sm->state) ? "[u]" : "");
1419 1424 sql_insert_return_states(return_id, return_ranges,
1420 1425 func_gets_user_data ? USER_DATA_SET : USER_DATA,
1421 1426 -1, param_name, buf);
1422 1427 } END_FOR_EACH_SM(sm);
1423 1428
1424 1429 /* This if for "return ntohl(foo);" */
1425 1430 if (!return_found && get_user_rl(expr, &rl)) {
1426 1431 snprintf(buf, sizeof(buf), "%s%s%s",
1427 1432 show_rl(rl),
1428 1433 user_rl_capped(expr) ? "[c]" : "",
1429 1434 user_rl_treat_untagged(expr) ? "[u]" : "");
1430 1435 sql_insert_return_states(return_id, return_ranges,
1431 1436 func_gets_user_data ? USER_DATA_SET : USER_DATA,
1432 1437 -1, "$", buf);
1433 1438 }
1434 1439
1435 1440 /*
1436 1441 * This is to handle things like return skb->data where we don't set a
1437 1442 * state for that.
1438 1443 */
1439 1444 if (!pointed_at_found && points_to_user_data(expr)) {
1440 1445 sql_insert_return_states(return_id, return_ranges,
1441 1446 (is_skb_data(expr) || func_gets_user_data) ?
1442 1447 USER_DATA_SET : USER_DATA,
1443 1448 -1, "*$", "s64min-s64max");
1444 1449 }
1445 1450
1446 1451 free_string(return_str);
1447 1452 }
1448 1453
1449 1454 static void returns_param_capped(struct expression *expr, int param, char *key, char *value)
1450 1455 {
1451 1456 struct smatch_state *state, *new;
1452 1457 struct symbol *sym;
1453 1458 char *name;
1454 1459
1455 1460 name = return_state_to_var_sym(expr, param, key, &sym);
1456 1461 if (!name || !sym)
1457 1462 goto free;
1458 1463
1459 1464 state = get_state(my_id, name, sym);
1460 1465 if (!state || estate_capped(state))
1461 1466 goto free;
1462 1467
1463 1468 new = clone_estate(state);
1464 1469 estate_set_capped(new);
1465 1470
1466 1471 set_state(my_id, name, sym, new);
1467 1472 free:
1468 1473 free_string(name);
1469 1474 }
1470 1475
1471 1476 static struct int_stack *gets_data_stack;
1472 1477 static void match_function_def(struct symbol *sym)
1473 1478 {
1474 1479 func_gets_user_data = false;
1475 1480 }
1476 1481
1477 1482 static void match_inline_start(struct expression *expr)
1478 1483 {
1479 1484 push_int(&gets_data_stack, func_gets_user_data);
1480 1485 }
1481 1486
1482 1487 static void match_inline_end(struct expression *expr)
1483 1488 {
1484 1489 func_gets_user_data = pop_int(&gets_data_stack);
1485 1490 }
1486 1491
1487 1492 void register_kernel_user_data(int id)
1488 1493 {
1489 1494 int i;
1490 1495
1491 1496 my_id = id;
1492 1497
1493 1498 if (option_project != PROJ_KERNEL)
1494 1499 return;
1495 1500
1496 1501 set_dynamic_states(my_id);
1497 1502
1498 1503 add_hook(&match_function_def, FUNC_DEF_HOOK);
1499 1504 add_hook(&match_inline_start, INLINE_FN_START);
1500 1505 add_hook(&match_inline_end, INLINE_FN_END);
1501 1506
1502 1507 add_hook(&save_start_states, AFTER_DEF_HOOK);
1503 1508 add_hook(&free_start_states, AFTER_FUNC_HOOK);
1504 1509 add_hook(&match_save_states, INLINE_FN_START);
1505 1510 add_hook(&match_restore_states, INLINE_FN_END);
1506 1511
1507 1512 add_unmatched_state_hook(my_id, &empty_state);
1508 1513 add_extra_nomod_hook(&extra_nomod_hook);
1509 1514 add_pre_merge_hook(my_id, &pre_merge_hook);
1510 1515 add_merge_hook(my_id, &merge_estates);
1511 1516
1512 1517 add_function_hook("copy_from_user", &match_user_copy, INT_PTR(0));
1513 1518 add_function_hook("__copy_from_user", &match_user_copy, INT_PTR(0));
1514 1519 add_function_hook("memcpy_fromiovec", &match_user_copy, INT_PTR(0));
1515 1520 for (i = 0; i < ARRAY_SIZE(kstr_funcs); i++)
1516 1521 add_function_hook(kstr_funcs[i], &match_user_copy, INT_PTR(2));
1517 1522 add_function_hook("usb_control_msg", &match_user_copy, INT_PTR(6));
1518 1523
1519 1524 for (i = 0; i < ARRAY_SIZE(returns_user_data); i++) {
1520 1525 add_function_assign_hook(returns_user_data[i], &match_user_assign_function, NULL);
1521 1526 add_function_hook(returns_user_data[i], &match_returns_user_rl, NULL);
1522 1527 }
1523 1528
1524 1529 add_function_hook("sscanf", &match_sscanf, NULL);
1525 1530
1526 1531 add_hook(&match_syscall_definition, AFTER_DEF_HOOK);
1527 1532
1528 1533 add_hook(&match_assign, ASSIGNMENT_HOOK);
1529 1534 select_return_states_hook(PARAM_SET, &db_param_set);
1530 1535 add_hook(&match_condition, CONDITION_HOOK);
1531 1536
1532 1537 add_hook(&match_call_info, FUNCTION_CALL_HOOK);
1533 1538 add_member_info_callback(my_id, struct_member_callback);
1534 1539 select_caller_info_hook(set_param_user_data, USER_DATA);
1535 1540 select_return_states_hook(USER_DATA, &returns_param_user_data);
1536 1541 select_return_states_hook(USER_DATA_SET, &returns_param_user_data_set);
1537 1542 select_return_states_hook(CAPPED_DATA, &returns_param_capped);
1538 1543 add_split_return_callback(¶m_set_to_user_data);
1539 1544 }
1540 1545
1541 1546 void register_kernel_user_data2(int id)
1542 1547 {
1543 1548 my_call_id = id;
1544 1549
1545 1550 if (option_project != PROJ_KERNEL)
1546 1551 return;
1547 1552 select_caller_info_hook(set_called, INTERNAL);
1548 1553 }
1549 1554
↓ open down ↓ |
852 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX