11506 smatch resync
1 /* 2 * Copyright (C) 2012 Oracle. 3 * 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. 8 * 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. 13 * 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 16 */ 17 18 /* 19 * The point here is to store that a buffer has x bytes even if we don't know 20 * the value of x. 21 * 22 */ 23 24 #include "smatch.h" 25 #include "smatch_extra.h" 26 #include "smatch_slist.h" 27 28 static int size_id; 29 static int link_id; 30 31 /* 32 * There is a bunch of code which does this: 33 * 34 * if (size) 35 * foo = malloc(size); 36 * 37 * So if "size" is non-zero then the size of "foo" is size. But really it's 38 * also true if size is zero. It's just better to assume to not trample over 39 * the data that we have by merging &undefined states. 40 * 41 */ 42 static struct smatch_state *unmatched_state(struct sm_state *sm) 43 { 44 return sm->state; 45 } 46 47 static struct smatch_state *merge_links(struct smatch_state *s1, struct smatch_state *s2) 48 { 49 struct expression *expr1, *expr2; 50 51 expr1 = s1->data; 52 expr2 = s2->data; 53 54 if (expr1 && expr2 && expr_equiv(expr1, expr2)) 55 return s1; 56 return &merged; 57 } 58 59 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr) 60 { 61 struct expression *expr; 62 struct sm_state *tmp; 63 64 expr = sm->state->data; 65 if (expr) { 66 set_state_expr(size_id, expr, &undefined); 67 set_state(link_id, sm->name, sm->sym, &undefined); 68 return; 69 } 70 71 FOR_EACH_PTR(sm->possible, tmp) { 72 expr = tmp->state->data; 73 if (expr) 74 set_state_expr(size_id, expr, &undefined); 75 } END_FOR_EACH_PTR(tmp); 76 set_state(link_id, sm->name, sm->sym, &undefined); 77 } 78 79 static const char *limit_map[] = { 80 "byte_count", 81 "elem_count", 82 "elem_last", 83 "used_count", 84 "used_last", 85 }; 86 87 int state_to_limit(struct smatch_state *state) 88 { 89 int i; 90 91 if (!state || !state->data) 92 return -1; 93 94 for (i = 0; i < ARRAY_SIZE(limit_map); i++) { 95 if (strncmp(state->name, limit_map[i], strlen(limit_map[i])) == 0) 96 return i + BYTE_COUNT; 97 } 98 99 return -1; 100 } 101 102 const char *limit_type_str(unsigned int limit_type) 103 { 104 if (limit_type - BYTE_COUNT >= ARRAY_SIZE(limit_map)) { 105 sm_msg("internal: wrong size type %u", limit_type); 106 return "unknown"; 107 } 108 109 return limit_map[limit_type - BYTE_COUNT]; 110 } 111 112 static struct smatch_state *alloc_compare_size(int limit_type, struct expression *expr) 113 { 114 struct smatch_state *state; 115 char *name; 116 char buf[256]; 117 118 state = __alloc_smatch_state(0); 119 expr = strip_expr(expr); 120 name = expr_to_str(expr); 121 snprintf(buf, sizeof(buf), "%s %s", limit_type_str(limit_type), name); 122 state->name = alloc_sname(buf); 123 free_string(name); 124 state->data = expr; 125 return state; 126 } 127 128 static int bytes_per_element(struct expression *expr) 129 { 130 struct symbol *type; 131 132 type = get_type(expr); 133 if (!type) 134 return 0; 135 136 if (type->type != SYM_PTR && type->type != SYM_ARRAY) 137 return 0; 138 139 type = get_base_type(type); 140 return type_bytes(type); 141 } 142 143 static void db_save_type_links(struct expression *array, int type_limit, struct expression *size) 144 { 145 const char *array_name; 146 147 array_name = get_data_info_name(array); 148 if (!array_name) 149 array_name = ""; 150 sql_insert_data_info(size, type_limit, array_name); 151 } 152 153 static void match_alloc_helper(struct expression *pointer, struct expression *size) 154 { 155 struct expression *tmp; 156 struct sm_state *sm; 157 int limit_type = ELEM_COUNT; 158 sval_t sval; 159 int cnt = 0; 160 161 pointer = strip_expr(pointer); 162 size = strip_expr(size); 163 if (!size || !pointer) 164 return; 165 166 while ((tmp = get_assigned_expr(size))) { 167 size = strip_expr(tmp); 168 if (cnt++ > 5) 169 break; 170 } 171 172 if (size->type == EXPR_BINOP && size->op == '*') { 173 struct expression *mult_left, *mult_right; 174 175 mult_left = strip_expr(size->left); 176 mult_right = strip_expr(size->right); 177 178 if (get_implied_value(mult_left, &sval) && 179 sval.value == bytes_per_element(pointer)) 180 size = mult_right; 181 else if (get_implied_value(mult_right, &sval) && 182 sval.value == bytes_per_element(pointer)) 183 size = mult_left; 184 else 185 return; 186 } 187 188 /* Only save links to variables, not fixed sizes */ 189 if (get_value(size, &sval)) 190 return; 191 192 if (size->type == EXPR_BINOP && size->op == '+' && 193 get_value(size->right, &sval) && sval.value == 1) { 194 size = size->left; 195 limit_type = ELEM_LAST; 196 } 197 198 db_save_type_links(pointer, limit_type, size); 199 sm = set_state_expr(size_id, pointer, alloc_compare_size(limit_type, size)); 200 if (!sm) 201 return; 202 set_state_expr(link_id, size, alloc_state_expr(pointer)); 203 } 204 205 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg) 206 { 207 int size_arg = PTR_INT(_size_arg); 208 struct expression *pointer, *call, *arg; 209 210 pointer = strip_expr(expr->left); 211 call = strip_expr(expr->right); 212 arg = get_argument_from_call_expr(call->args, size_arg); 213 match_alloc_helper(pointer, arg); 214 } 215 216 static void match_calloc(const char *fn, struct expression *expr, void *_start_arg) 217 { 218 int start_arg = PTR_INT(_start_arg); 219 struct expression *pointer, *call, *arg; 220 struct sm_state *tmp; 221 int limit_type = ELEM_COUNT; 222 sval_t sval; 223 224 pointer = strip_expr(expr->left); 225 call = strip_expr(expr->right); 226 arg = get_argument_from_call_expr(call->args, start_arg); 227 if (get_implied_value(arg, &sval) && 228 sval.value == bytes_per_element(pointer)) 229 arg = get_argument_from_call_expr(call->args, start_arg + 1); 230 231 if (arg->type == EXPR_BINOP && arg->op == '+' && 232 get_value(arg->right, &sval) && sval.value == 1) { 233 arg = arg->left; 234 limit_type = ELEM_LAST; 235 } 236 237 db_save_type_links(pointer, limit_type, arg); 238 tmp = set_state_expr(size_id, pointer, alloc_compare_size(limit_type, arg)); 239 if (!tmp) 240 return; 241 set_state_expr(link_id, arg, alloc_state_expr(pointer)); 242 } 243 244 struct expression *get_size_variable(struct expression *buf, int *limit_type) 245 { 246 struct smatch_state *state; 247 248 state = get_state_expr(size_id, buf); 249 if (!state) 250 return NULL; 251 *limit_type = state_to_limit(state); 252 return state->data; 253 } 254 255 struct expression *get_array_variable(struct expression *size) 256 { 257 struct smatch_state *state; 258 259 state = get_state_expr(link_id, size); 260 if (state) 261 return state->data; 262 return NULL; 263 } 264 265 static void array_check(struct expression *expr) 266 { 267 struct expression *array; 268 struct expression *size; 269 struct expression *offset; 270 char *array_str, *offset_str; 271 int limit_type; 272 273 expr = strip_expr(expr); 274 if (!is_array(expr)) 275 return; 276 277 array = get_array_base(expr); 278 size = get_size_variable(array, &limit_type); 279 if (!size) 280 return; 281 if (limit_type != ELEM_COUNT) 282 return; 283 offset = get_array_offset(expr); 284 if (!possible_comparison(size, SPECIAL_EQUAL, offset)) 285 return; 286 287 array_str = expr_to_str(array); 288 offset_str = expr_to_str(offset); 289 sm_warning("potentially one past the end of array '%s[%s]'", array_str, offset_str); 290 free_string(array_str); 291 free_string(offset_str); 292 } 293 294 struct db_info { 295 char *name; 296 int ret; 297 }; 298 299 static int db_limitter_callback(void *_info, int argc, char **argv, char **azColName) 300 { 301 struct db_info *info = _info; 302 303 /* 304 * If possible the limitters are tied to the struct they limit. If we 305 * aren't sure which struct they limit then we use them as limitters for 306 * everything. 307 */ 308 if (!info->name || argv[0][0] == '\0' || strcmp(info->name, argv[0]) == 0) 309 info->ret = 1; 310 return 0; 311 } 312 313 static char *vsl_to_data_info_name(const char *name, struct var_sym_list *vsl) 314 { 315 struct var_sym *vs; 316 struct symbol *type; 317 static char buf[80]; 318 const char *p; 319 320 if (ptr_list_size((struct ptr_list *)vsl) != 1) 321 return NULL; 322 vs = first_ptr_list((struct ptr_list *)vsl); 323 324 type = get_real_base_type(vs->sym); 325 if (!type || type->type != SYM_PTR) 326 goto top_level_name; 327 type = get_real_base_type(type); 328 if (!type || type->type != SYM_STRUCT) 329 goto top_level_name; 330 if (!type->ident) 331 goto top_level_name; 332 333 p = name; 334 while ((name = strstr(p, "->"))) 335 p = name + 2; 336 337 snprintf(buf, sizeof(buf),"(struct %s)->%s", type->ident->name, p); 338 return alloc_sname(buf); 339 340 top_level_name: 341 if (!(vs->sym->ctype.modifiers & MOD_TOPLEVEL)) 342 return NULL; 343 if (vs->sym->ctype.modifiers & MOD_STATIC) 344 snprintf(buf, sizeof(buf),"static %s", name); 345 else 346 snprintf(buf, sizeof(buf),"global %s", name); 347 return alloc_sname(buf); 348 } 349 350 int db_var_is_array_limit(struct expression *array, const char *name, struct var_sym_list *vsl) 351 { 352 char *size_name; 353 char *array_name = get_data_info_name(array); 354 struct db_info db_info = {.name = array_name,}; 355 356 size_name = vsl_to_data_info_name(name, vsl); 357 if (!size_name) 358 return 0; 359 360 run_sql(db_limitter_callback, &db_info, 361 "select value from data_info where type = %d and data = '%s';", 362 ARRAY_LEN, size_name); 363 364 return db_info.ret; 365 } 366 367 int buf_comparison_index_ok(struct expression *expr) 368 { 369 struct expression *array; 370 struct expression *size; 371 struct expression *offset; 372 int limit_type; 373 int comparison; 374 375 array = get_array_base(expr); 376 size = get_size_variable(array, &limit_type); 377 if (!size) 378 return 0; 379 offset = get_array_offset(expr); 380 comparison = get_comparison(offset, size); 381 if (!comparison) 382 return 0; 383 384 if ((limit_type == ELEM_COUNT || limit_type == ELEM_LAST) && 385 (comparison == '<' || comparison == SPECIAL_UNSIGNED_LT)) 386 return 1; 387 if (limit_type == ELEM_LAST && 388 (comparison == SPECIAL_LTE || 389 comparison == SPECIAL_UNSIGNED_LTE || 390 comparison == SPECIAL_EQUAL)) 391 return 1; 392 393 return 0; 394 } 395 396 static int known_access_ok_numbers(struct expression *expr) 397 { 398 struct expression *array; 399 struct expression *offset; 400 sval_t max; 401 int size; 402 403 array = get_array_base(expr); 404 offset = get_array_offset(expr); 405 406 size = get_array_size(array); 407 if (size <= 0) 408 return 0; 409 410 get_absolute_max(offset, &max); 411 if (max.uvalue < size) 412 return 1; 413 return 0; 414 } 415 416 static void array_check_data_info(struct expression *expr) 417 { 418 struct expression *array; 419 struct expression *offset; 420 struct state_list *slist; 421 struct sm_state *sm; 422 struct compare_data *comp; 423 char *offset_name; 424 const char *equal_name = NULL; 425 426 expr = strip_expr(expr); 427 if (!is_array(expr)) 428 return; 429 430 if (known_access_ok_numbers(expr)) 431 return; 432 if (buf_comparison_index_ok(expr)) 433 return; 434 435 array = get_array_base(expr); 436 offset = get_array_offset(expr); 437 offset_name = expr_to_var(offset); 438 if (!offset_name) 439 return; 440 slist = get_all_possible_equal_comparisons(offset); 441 if (!slist) 442 goto free; 443 444 FOR_EACH_PTR(slist, sm) { 445 comp = sm->state->data; 446 if (strcmp(comp->left_var, offset_name) == 0) { 447 if (db_var_is_array_limit(array, comp->right_var, comp->right_vsl)) { 448 equal_name = comp->right_var; 449 break; 450 } 451 } else if (strcmp(comp->right_var, offset_name) == 0) { 452 if (db_var_is_array_limit(array, comp->left_var, comp->left_vsl)) { 453 equal_name = comp->left_var; 454 break; 455 } 456 } 457 } END_FOR_EACH_PTR(sm); 458 459 if (equal_name) { 460 char *array_name = expr_to_str(array); 461 462 sm_warning("potential off by one '%s[]' limit '%s'", array_name, equal_name); 463 free_string(array_name); 464 } 465 466 free: 467 free_slist(&slist); 468 free_string(offset_name); 469 } 470 471 static void add_allocation_function(const char *func, void *call_back, int param) 472 { 473 add_function_assign_hook(func, call_back, INT_PTR(param)); 474 } 475 476 static int is_sizeof(struct expression *expr) 477 { 478 const char *name; 479 480 if (expr->type == EXPR_SIZEOF) 481 return 1; 482 name = pos_ident(expr->pos); 483 if (name && strcmp(name, "sizeof") == 0) 484 return 1; 485 return 0; 486 } 487 488 static int match_size_binop(struct expression *size, struct expression *expr, int *limit_type) 489 { 490 int orig_type = *limit_type; 491 struct expression *left; 492 sval_t sval; 493 494 left = expr->left; 495 if (!expr_equiv(size, left)) 496 return 0; 497 498 if (expr->op == '-' && 499 get_value(expr->right, &sval) && 500 sval.value == 1 && 501 orig_type == ELEM_COUNT) { 502 *limit_type = ELEM_LAST; 503 return 1; 504 } 505 506 if (expr->op == '+' && 507 get_value(expr->right, &sval) && 508 sval.value == 1 && 509 orig_type == ELEM_LAST) { 510 *limit_type = ELEM_COUNT; 511 return 1; 512 } 513 514 if (expr->op == '*' && 515 is_sizeof(expr->right) && 516 orig_type == ELEM_COUNT) { 517 *limit_type = BYTE_COUNT; 518 return 1; 519 } 520 521 if (expr->op == '/' && 522 is_sizeof(expr->right) && 523 orig_type == BYTE_COUNT) { 524 *limit_type = ELEM_COUNT; 525 return 1; 526 } 527 528 return 0; 529 } 530 531 static char *buf_size_param_comparison(struct expression *array, struct expression_list *args, int *limit_type) 532 { 533 struct expression *tmp, *arg; 534 struct expression *size; 535 static char buf[32]; 536 int i; 537 538 size = get_size_variable(array, limit_type); 539 if (!size) 540 return NULL; 541 542 if (*limit_type == USED_LAST) 543 *limit_type = ELEM_LAST; 544 if (*limit_type == USED_COUNT) 545 *limit_type = ELEM_COUNT; 546 547 i = -1; 548 FOR_EACH_PTR(args, tmp) { 549 i++; 550 arg = tmp; 551 if (arg == array) 552 continue; 553 if (expr_equiv(arg, size) || 554 (arg->type == EXPR_BINOP && 555 match_size_binop(size, arg, limit_type))) { 556 snprintf(buf, sizeof(buf), "==$%d", i); 557 return buf; 558 } 559 } END_FOR_EACH_PTR(tmp); 560 561 return NULL; 562 } 563 564 static void match_call(struct expression *call) 565 { 566 struct expression *arg; 567 char *compare; 568 int param; 569 char buf[5]; 570 int limit_type; 571 572 param = -1; 573 FOR_EACH_PTR(call->args, arg) { 574 param++; 575 if (!is_pointer(arg)) 576 continue; 577 compare = buf_size_param_comparison(arg, call->args, &limit_type); 578 if (!compare) 579 continue; 580 snprintf(buf, sizeof(buf), "%d", limit_type); 581 sql_insert_caller_info(call, limit_type, param, compare, buf); 582 } END_FOR_EACH_PTR(arg); 583 } 584 585 static int get_param(int param, char **name, struct symbol **sym) 586 { 587 struct symbol *arg; 588 int i; 589 590 i = 0; 591 FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) { 592 /* 593 * this is a temporary hack to work around a bug (I think in sparse?) 594 * 2.6.37-rc1:fs/reiserfs/journal.o 595 * If there is a function definition without parameter name found 596 * after a function implementation then it causes a crash. 597 * int foo() {} 598 * int bar(char *); 599 */ 600 if (arg->ident->name < (char *)100) 601 continue; 602 if (i == param) { 603 *name = arg->ident->name; 604 *sym = arg; 605 return TRUE; 606 } 607 i++; 608 } END_FOR_EACH_PTR(arg); 609 610 return FALSE; 611 } 612 613 static void set_param_compare(const char *array_name, struct symbol *array_sym, char *key, char *value) 614 { 615 struct expression *array_expr; 616 struct expression *size_expr; 617 struct symbol *size_sym; 618 char *size_name; 619 long param; 620 struct sm_state *tmp; 621 int limit_type; 622 623 if (strncmp(key, "==$", 3) != 0) 624 return; 625 param = strtol(key + 3, NULL, 10); 626 if (!get_param(param, &size_name, &size_sym)) 627 return; 628 array_expr = symbol_expression(array_sym); 629 size_expr = symbol_expression(size_sym); 630 limit_type = strtol(value, NULL, 10); 631 632 tmp = set_state_expr(size_id, array_expr, alloc_compare_size(limit_type, size_expr)); 633 if (!tmp) 634 return; 635 set_state_expr(link_id, size_expr, alloc_state_expr(array_expr)); 636 } 637 638 static void set_implied(struct expression *call, struct expression *array_expr, char *key, char *value) 639 { 640 struct expression *size_expr; 641 struct symbol *size_sym; 642 char *size_name; 643 long param; 644 struct sm_state *tmp; 645 int limit_type; 646 647 if (strncmp(key, "==$", 3) != 0) 648 return; 649 param = strtol(key + 3, NULL, 10); 650 if (!get_param(param, &size_name, &size_sym)) 651 return; 652 size_expr = symbol_expression(size_sym); 653 654 limit_type = strtol(value, NULL, 10); 655 tmp = set_state_expr(size_id, array_expr, alloc_compare_size(limit_type, size_expr)); 656 if (!tmp) 657 return; 658 set_state_expr(link_id, size_expr, alloc_state_expr(array_expr)); 659 } 660 661 static void munge_start_states(struct statement *stmt) 662 { 663 struct state_list *slist = NULL; 664 struct sm_state *sm; 665 struct sm_state *poss; 666 667 FOR_EACH_MY_SM(size_id, __get_cur_stree(), sm) { 668 if (sm->state != &merged) 669 continue; 670 /* 671 * screw it. let's just assume that if one caller passes the 672 * size then they all do. 673 */ 674 FOR_EACH_PTR(sm->possible, poss) { 675 if (poss->state != &merged && 676 poss->state != &undefined) { 677 add_ptr_list(&slist, poss); 678 break; 679 } 680 } END_FOR_EACH_PTR(poss); 681 } END_FOR_EACH_SM(sm); 682 683 FOR_EACH_PTR(slist, sm) { 684 set_state(size_id, sm->name, sm->sym, sm->state); 685 } END_FOR_EACH_PTR(sm); 686 687 free_slist(&slist); 688 } 689 690 static void set_used(struct expression *expr) 691 { 692 struct expression *parent; 693 struct expression *array; 694 struct expression *offset; 695 struct sm_state *tmp; 696 int limit_type; 697 698 if (expr->op != SPECIAL_INCREMENT) 699 return; 700 701 limit_type = USED_LAST; 702 if (expr->type == EXPR_POSTOP) 703 limit_type = USED_COUNT; 704 705 parent = expr_get_parent_expr(expr); 706 if (!parent || parent->type != EXPR_BINOP) 707 return; 708 parent = expr_get_parent_expr(parent); 709 if (!parent || !is_array(parent)) 710 return; 711 712 array = get_array_base(parent); 713 offset = get_array_offset(parent); 714 if (offset != expr) 715 return; 716 717 tmp = set_state_expr(size_id, array, alloc_compare_size(limit_type, offset->unop)); 718 if (!tmp) 719 return; 720 set_state_expr(link_id, offset->unop, alloc_state_expr(array)); 721 } 722 723 static int match_assign_array(struct expression *expr) 724 { 725 // FIXME: implement 726 return 0; 727 } 728 729 static int match_assign_size(struct expression *expr) 730 { 731 struct expression *right, *size, *array; 732 struct smatch_state *state; 733 struct sm_state *tmp; 734 int limit_type; 735 736 right = expr->right; 737 size = right; 738 if (size->type == EXPR_BINOP) 739 size = size->left; 740 741 array = get_array_variable(size); 742 if (!array) 743 return 0; 744 state = get_state_expr(size_id, array); 745 if (!state || !state->data) 746 return 0; 747 748 limit_type = state_to_limit(state); 749 if (limit_type < 0) 750 return 0; 751 752 if (right->type == EXPR_BINOP && !match_size_binop(size, right, &limit_type)) 753 return 0; 754 755 tmp = set_state_expr(size_id, array, alloc_compare_size(limit_type, expr->left)); 756 if (!tmp) 757 return 0; 758 set_state_expr(link_id, expr->left, alloc_state_expr(array)); 759 return 1; 760 } 761 762 static void match_assign(struct expression *expr) 763 { 764 if (expr->op != '=') 765 return; 766 767 if (match_assign_array(expr)) 768 return; 769 match_assign_size(expr); 770 } 771 772 static void match_copy(const char *fn, struct expression *expr, void *unused) 773 { 774 struct expression *src, *size; 775 int src_param, size_param; 776 777 src = get_argument_from_call_expr(expr->args, 1); 778 size = get_argument_from_call_expr(expr->args, 2); 779 src = strip_expr(src); 780 size = strip_expr(size); 781 if (!src || !size) 782 return; 783 if (src->type != EXPR_SYMBOL || size->type != EXPR_SYMBOL) 784 return; 785 786 src_param = get_param_num_from_sym(src->symbol); 787 size_param = get_param_num_from_sym(size->symbol); 788 if (src_param < 0 || size_param < 0) 789 return; 790 791 sql_insert_cache(call_implies, "'%s', '%s', 0, %d, %d, %d, '==$%d', '%d'", 792 get_base_file(), get_function(), fn_static(), 793 BYTE_COUNT, src_param, size_param, BYTE_COUNT); 794 } 795 796 void register_buf_comparison(int id) 797 { 798 int i; 799 800 size_id = id; 801 802 set_dynamic_states(size_id); 803 804 add_unmatched_state_hook(size_id, &unmatched_state); 805 806 add_allocation_function("malloc", &match_alloc, 0); 807 add_allocation_function("memdup", &match_alloc, 1); 808 add_allocation_function("realloc", &match_alloc, 1); 809 if (option_project == PROJ_KERNEL) { 810 add_allocation_function("kmalloc", &match_alloc, 0); 811 add_allocation_function("kzalloc", &match_alloc, 0); 812 add_allocation_function("vmalloc", &match_alloc, 0); 813 add_allocation_function("__vmalloc", &match_alloc, 0); 814 add_allocation_function("sock_kmalloc", &match_alloc, 1); 815 add_allocation_function("kmemdup", &match_alloc, 1); 816 add_allocation_function("kmemdup_user", &match_alloc, 1); 817 add_allocation_function("dma_alloc_attrs", &match_alloc, 1); 818 add_allocation_function("pci_alloc_consistent", &match_alloc, 1); 819 add_allocation_function("pci_alloc_coherent", &match_alloc, 1); 820 add_allocation_function("devm_kmalloc", &match_alloc, 1); 821 add_allocation_function("devm_kzalloc", &match_alloc, 1); 822 add_allocation_function("kcalloc", &match_calloc, 0); 823 add_allocation_function("devm_kcalloc", &match_calloc, 1); 824 add_allocation_function("kmalloc_array", &match_calloc, 0); 825 add_allocation_function("krealloc", &match_alloc, 1); 826 827 add_function_hook("copy_from_user", &match_copy, NULL); 828 add_function_hook("__copy_from_user", &match_copy, NULL); 829 } 830 831 add_hook(&array_check, OP_HOOK); 832 add_hook(&array_check_data_info, OP_HOOK); 833 add_hook(&set_used, OP_HOOK); 834 835 add_hook(&match_call, FUNCTION_CALL_HOOK); 836 add_hook(&munge_start_states, AFTER_DEF_HOOK); 837 838 add_hook(&match_assign, ASSIGNMENT_HOOK); 839 840 for (i = BYTE_COUNT; i <= USED_COUNT; i++) { 841 select_call_implies_hook(i, &set_implied); 842 select_caller_info_hook(set_param_compare, i); 843 select_return_implies_hook(i, &set_implied); 844 } 845 } 846 847 void register_buf_comparison_links(int id) 848 { 849 link_id = id; 850 set_dynamic_states(link_id); 851 add_merge_hook(link_id, &merge_links); 852 add_modification_hook(link_id, &match_link_modify); 853 } --- EOF ---