1 /* 2 * Copyright (C) 2010 Dan Carpenter. 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 #include <stdlib.h> 19 #include <errno.h> 20 #include "parse.h" 21 #include "smatch.h" 22 #include "smatch_slist.h" 23 #include "smatch_extra.h" 24 #include "smatch_function_hashtable.h" 25 26 #define UNKNOWN_SIZE -1 27 28 static int my_size_id; 29 30 static DEFINE_HASHTABLE_INSERT(insert_func, char, int); 31 static DEFINE_HASHTABLE_SEARCH(search_func, char, int); 32 static struct hashtable *allocation_funcs; 33 34 static char *get_fn_name(struct expression *expr) 35 { 36 if (expr->type != EXPR_CALL) 37 return NULL; 38 if (expr->fn->type != EXPR_SYMBOL) 39 return NULL; 40 return expr_to_var(expr->fn); 41 } 42 43 static int is_allocation_function(struct expression *expr) 44 { 45 char *func; 46 int ret = 0; 47 48 func = get_fn_name(expr); 49 if (!func) 50 return 0; 51 if (search_func(allocation_funcs, func)) 52 ret = 1; 53 free_string(func); 54 return ret; 55 } 56 57 static void add_allocation_function(const char *func, void *call_back, int param) 58 { 59 insert_func(allocation_funcs, (char *)func, (int *)1); 60 add_function_assign_hook(func, call_back, INT_PTR(param)); 61 } 62 63 static int estate_to_size(struct smatch_state *state) 64 { 65 sval_t sval; 66 67 if (!state || !estate_rl(state)) 68 return 0; 69 sval = estate_max(state); 70 return sval.value; 71 } 72 73 static struct smatch_state *size_to_estate(int size) 74 { 75 sval_t sval; 76 77 sval.type = &int_ctype; 78 sval.value = size; 79 80 return alloc_estate_sval(sval); 81 } 82 83 static struct range_list *size_to_rl(int size) 84 { 85 sval_t sval; 86 87 sval.type = &int_ctype; 88 sval.value = size; 89 90 return alloc_rl(sval, sval); 91 } 92 93 static struct smatch_state *unmatched_size_state(struct sm_state *sm) 94 { 95 return size_to_estate(UNKNOWN_SIZE); 96 } 97 98 static void set_size_undefined(struct sm_state *sm, struct expression *mod_expr) 99 { 100 set_state(sm->owner, sm->name, sm->sym, size_to_estate(UNKNOWN_SIZE)); 101 } 102 103 static struct smatch_state *merge_size_func(struct smatch_state *s1, struct smatch_state *s2) 104 { 105 return merge_estates(s1, s2); 106 } 107 108 void set_param_buf_size(const char *name, struct symbol *sym, char *key, char *value) 109 { 110 struct range_list *rl = NULL; 111 struct smatch_state *state; 112 char fullname[256]; 113 114 if (strncmp(key, "$", 1) != 0) 115 return; 116 117 snprintf(fullname, 256, "%s%s", name, key + 1); 118 119 str_to_rl(&int_ctype, value, &rl); 120 if (!rl || is_whole_rl(rl)) 121 return; 122 state = alloc_estate_rl(rl); 123 set_state(my_size_id, fullname, sym, state); 124 } 125 126 static int bytes_per_element(struct expression *expr) 127 { 128 struct symbol *type; 129 130 if (!expr) 131 return 0; 132 if (expr->type == EXPR_STRING) 133 return 1; 134 if (expr->type == EXPR_PREOP && expr->op == '&') { 135 type = get_type(expr->unop); 136 if (type && type->type == SYM_ARRAY) 137 expr = expr->unop; 138 } 139 type = get_type(expr); 140 if (!type) 141 return 0; 142 143 if (type->type != SYM_PTR && type->type != SYM_ARRAY) 144 return 0; 145 146 type = get_base_type(type); 147 return type_bytes(type); 148 } 149 150 static int bytes_to_elements(struct expression *expr, int bytes) 151 { 152 int bpe; 153 154 bpe = bytes_per_element(expr); 155 if (bpe == 0) 156 return 0; 157 return bytes / bpe; 158 } 159 160 static int elements_to_bytes(struct expression *expr, int elements) 161 { 162 int bpe; 163 164 bpe = bytes_per_element(expr); 165 return elements * bpe; 166 } 167 168 static int get_initializer_size(struct expression *expr) 169 { 170 switch (expr->type) { 171 case EXPR_STRING: 172 return expr->string->length; 173 case EXPR_INITIALIZER: { 174 struct expression *tmp; 175 int i = 0; 176 177 FOR_EACH_PTR(expr->expr_list, tmp) { 178 if (tmp->type == EXPR_INDEX) { 179 if (tmp->idx_to >= i) 180 i = tmp->idx_to; 181 else 182 continue; 183 } 184 185 i++; 186 } END_FOR_EACH_PTR(tmp); 187 return i; 188 } 189 case EXPR_SYMBOL: 190 return get_array_size(expr); 191 } 192 return 0; 193 } 194 195 static struct range_list *db_size_rl; 196 static int db_size_callback(void *unused, int argc, char **argv, char **azColName) 197 { 198 struct range_list *tmp = NULL; 199 200 if (!db_size_rl) { 201 str_to_rl(&int_ctype, argv[0], &db_size_rl); 202 } else { 203 str_to_rl(&int_ctype, argv[0], &tmp); 204 db_size_rl = rl_union(db_size_rl, tmp); 205 } 206 return 0; 207 } 208 209 static struct range_list *size_from_db_type(struct expression *expr) 210 { 211 int this_file_only = 0; 212 char *name; 213 214 name = get_member_name(expr); 215 if (!name && is_static(expr)) { 216 name = expr_to_var(expr); 217 this_file_only = 1; 218 } 219 if (!name) 220 return NULL; 221 222 if (this_file_only) { 223 db_size_rl = NULL; 224 run_sql(db_size_callback, NULL, 225 "select size from function_type_size where type = '%s' and file = '%s';", 226 name, get_filename()); 227 if (db_size_rl) 228 return db_size_rl; 229 return NULL; 230 } 231 232 db_size_rl = NULL; 233 run_sql(db_size_callback, NULL, 234 "select size from type_size where type = '%s';", 235 name); 236 return db_size_rl; 237 } 238 239 static struct range_list *size_from_db_symbol(struct expression *expr) 240 { 241 struct symbol *sym; 242 243 if (expr->type != EXPR_SYMBOL) 244 return NULL; 245 sym = expr->symbol; 246 if (!sym || !sym->ident || 247 !(sym->ctype.modifiers & MOD_TOPLEVEL) || 248 sym->ctype.modifiers & MOD_STATIC) 249 return NULL; 250 251 db_size_rl = NULL; 252 run_sql(db_size_callback, NULL, 253 "select value from data_info where file = 'extern' and data = '%s' and type = %d;", 254 sym->ident->name, BUF_SIZE); 255 return db_size_rl; 256 } 257 258 static struct range_list *size_from_db(struct expression *expr) 259 { 260 struct range_list *rl; 261 262 rl = size_from_db_symbol(expr); 263 if (rl) 264 return rl; 265 return size_from_db_type(expr); 266 } 267 268 static void db_returns_buf_size(struct expression *expr, int param, char *unused, char *math) 269 { 270 struct expression *call; 271 struct range_list *rl; 272 sval_t sval; 273 274 if (expr->type != EXPR_ASSIGNMENT) 275 return; 276 call = strip_expr(expr->right); 277 278 call_results_to_rl(call, &int_ctype, math, &rl); 279 rl = cast_rl(&int_ctype, rl); 280 if (rl_to_sval(rl, &sval) && sval.value == 0) 281 return; 282 set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl)); 283 } 284 285 static int get_real_array_size_from_type(struct symbol *type) 286 { 287 sval_t sval; 288 289 if (!type) 290 return 0; 291 if (!type || type->type != SYM_ARRAY) 292 return 0; 293 294 if (!get_implied_value(type->array_size, &sval)) 295 return 0; 296 297 return sval.value; 298 } 299 300 int get_real_array_size(struct expression *expr) 301 { 302 if (!expr) 303 return 0; 304 if (expr->type == EXPR_PREOP && expr->op == '&') 305 expr = expr->unop; 306 if (expr->type == EXPR_BINOP) /* array elements foo[5] */ 307 return 0; 308 return get_real_array_size_from_type(get_type(expr)); 309 } 310 311 static int get_size_from_initializer(struct expression *expr) 312 { 313 if (expr->type != EXPR_SYMBOL || !expr->symbol || !expr->symbol->initializer) 314 return 0; 315 if (expr->symbol->initializer == expr) /* int a = a; */ 316 return 0; 317 return get_initializer_size(expr->symbol->initializer); 318 } 319 320 static struct range_list *get_stored_size_bytes(struct expression *expr) 321 { 322 struct smatch_state *state; 323 324 state = get_state_expr(my_size_id, expr); 325 if (!state) 326 return NULL; 327 return estate_rl(state); 328 } 329 330 static int get_bytes_from_address(struct expression *expr) 331 { 332 struct symbol *type; 333 int ret; 334 335 if (expr->type != EXPR_PREOP || expr->op != '&') 336 return 0; 337 type = get_type(expr); 338 if (!type) 339 return 0; 340 341 if (type->type == SYM_PTR) 342 type = get_base_type(type); 343 344 ret = type_bytes(type); 345 if (ret == 1) 346 return 0; /* ignore char pointers */ 347 348 return ret; 349 } 350 351 static struct expression *remove_addr_fluff(struct expression *expr) 352 { 353 struct expression *tmp; 354 sval_t sval; 355 356 expr = strip_expr(expr); 357 358 /* remove '&' and '*' operations that cancel */ 359 while (expr && expr->type == EXPR_PREOP && expr->op == '&') { 360 tmp = strip_expr(expr->unop); 361 if (tmp->type != EXPR_PREOP) 362 break; 363 if (tmp->op != '*') 364 break; 365 expr = strip_expr(tmp->unop); 366 } 367 368 if (!expr) 369 return NULL; 370 371 /* "foo + 0" is just "foo" */ 372 if (expr->type == EXPR_BINOP && expr->op == '+' && 373 get_value(expr->right, &sval) && sval.value == 0) 374 return expr->left; 375 376 return expr; 377 } 378 379 static int is_last_member_of_struct(struct symbol *sym, struct ident *member) 380 { 381 struct symbol *tmp; 382 int i; 383 384 i = 0; 385 FOR_EACH_PTR_REVERSE(sym->symbol_list, tmp) { 386 if (i++ || !tmp->ident) 387 return 0; 388 if (tmp->ident == member) 389 return 1; 390 return 0; 391 } END_FOR_EACH_PTR_REVERSE(tmp); 392 393 return 0; 394 } 395 396 int last_member_is_resizable(struct symbol *sym) 397 { 398 struct symbol *last_member; 399 struct symbol *type; 400 sval_t sval; 401 402 if (!sym || sym->type != SYM_STRUCT) 403 return 0; 404 405 last_member = last_ptr_list((struct ptr_list *)sym->symbol_list); 406 if (!last_member || !last_member->ident) 407 return 0; 408 409 type = get_real_base_type(last_member); 410 if (type->type == SYM_STRUCT) 411 return last_member_is_resizable(type); 412 if (type->type != SYM_ARRAY) 413 return 0; 414 415 if (!get_implied_value(type->array_size, &sval)) 416 return 0; 417 418 if (sval.value != 0 && sval.value != 1) 419 return 0; 420 421 return 1; 422 } 423 424 static int get_stored_size_end_struct_bytes(struct expression *expr) 425 { 426 struct symbol *sym; 427 struct symbol *base_sym; 428 struct smatch_state *state; 429 430 if (expr->type == EXPR_BINOP) /* array elements foo[5] */ 431 return 0; 432 433 if (expr->type == EXPR_PREOP && expr->op == '&') 434 expr = strip_parens(expr->unop); 435 436 sym = expr_to_sym(expr); 437 if (!sym || !sym->ident) 438 return 0; 439 if (!type_bytes(sym)) 440 return 0; 441 if (sym->type != SYM_NODE) 442 return 0; 443 444 base_sym = get_real_base_type(sym); 445 if (!base_sym || base_sym->type != SYM_PTR) 446 return 0; 447 base_sym = get_real_base_type(base_sym); 448 if (!base_sym || base_sym->type != SYM_STRUCT) 449 return 0; 450 451 if (!is_last_member_of_struct(base_sym, expr->member)) 452 return 0; 453 if (!last_member_is_resizable(base_sym)) 454 return 0; 455 456 state = get_state(my_size_id, sym->ident->name, sym); 457 if (!estate_to_size(state) || estate_to_size(state) == -1) 458 return 0; 459 460 return estate_to_size(state) - type_bytes(base_sym) + type_bytes(get_type(expr)); 461 } 462 463 static struct range_list *alloc_int_rl(int value) 464 { 465 sval_t sval = { 466 .type = &int_ctype, 467 {.value = value}, 468 }; 469 470 return alloc_rl(sval, sval); 471 } 472 473 struct range_list *get_array_size_bytes_rl(struct expression *expr) 474 { 475 struct range_list *ret = NULL; 476 sval_t sval; 477 int size; 478 479 expr = remove_addr_fluff(expr); 480 if (!expr) 481 return NULL; 482 483 /* "BAR" */ 484 if (expr->type == EXPR_STRING) 485 return alloc_int_rl(expr->string->length); 486 487 if (expr->type == EXPR_BINOP && expr->op == '+') { 488 sval_t offset; 489 struct symbol *type; 490 int bytes; 491 492 if (!get_implied_value(expr->right, &offset)) 493 return NULL; 494 type = get_type(expr->left); 495 if (!type) 496 return NULL; 497 if (type->type != SYM_ARRAY && type->type != SYM_PTR) 498 return NULL; 499 type = get_real_base_type(type); 500 bytes = type_bytes(type); 501 if (bytes == 0) 502 return NULL; 503 offset.value *= bytes; 504 size = get_array_size_bytes(expr->left); 505 if (size <= 0) 506 return NULL; 507 return alloc_int_rl(size - offset.value); 508 } 509 510 /* buf = malloc(1024); */ 511 ret = get_stored_size_bytes(expr); 512 if (ret) 513 return ret; 514 515 size = get_stored_size_end_struct_bytes(expr); 516 if (size) 517 return alloc_int_rl(size); 518 519 /* buf[4] */ 520 size = get_real_array_size(expr); 521 if (size) 522 return alloc_int_rl(elements_to_bytes(expr, size)); 523 524 /* char *foo = "BAR" */ 525 size = get_size_from_initializer(expr); 526 if (size) 527 return alloc_int_rl(elements_to_bytes(expr, size)); 528 529 size = get_bytes_from_address(expr); 530 if (size) 531 return alloc_int_rl(size); 532 533 ret = size_from_db(expr); 534 if (rl_to_sval(ret, &sval) && sval.value == -1) 535 return NULL; 536 if (ret) 537 return ret; 538 539 return NULL; 540 } 541 542 int get_array_size_bytes(struct expression *expr) 543 { 544 struct range_list *rl; 545 sval_t sval; 546 547 rl = get_array_size_bytes_rl(expr); 548 if (!rl_to_sval(rl, &sval)) 549 return 0; 550 if (sval.uvalue >= INT_MAX) 551 return 0; 552 return sval.value; 553 } 554 555 int get_array_size_bytes_max(struct expression *expr) 556 { 557 struct range_list *rl; 558 sval_t bytes; 559 560 rl = get_array_size_bytes_rl(expr); 561 if (!rl) 562 return 0; 563 bytes = rl_min(rl); 564 if (bytes.value < 0) 565 return 0; 566 bytes = rl_max(rl); 567 if (bytes.uvalue >= INT_MAX) 568 return 0; 569 return bytes.value; 570 } 571 572 int get_array_size_bytes_min(struct expression *expr) 573 { 574 struct range_list *rl; 575 struct data_range *range; 576 577 rl = get_array_size_bytes_rl(expr); 578 if (!rl) 579 return 0; 580 581 FOR_EACH_PTR(rl, range) { 582 if (range->min.value <= 0) 583 return 0; 584 if (range->max.value <= 0) 585 return 0; 586 if (range->min.uvalue >= INT_MAX) 587 return 0; 588 return range->min.value; 589 } END_FOR_EACH_PTR(range); 590 591 return 0; 592 } 593 594 int get_array_size(struct expression *expr) 595 { 596 if (!expr) 597 return 0; 598 return bytes_to_elements(expr, get_array_size_bytes_max(expr)); 599 } 600 601 static struct expression *strip_ampersands(struct expression *expr) 602 { 603 struct symbol *type; 604 605 if (expr->type != EXPR_PREOP) 606 return expr; 607 if (expr->op != '&') 608 return expr; 609 type = get_type(expr->unop); 610 if (!type || type->type != SYM_ARRAY) 611 return expr; 612 return expr->unop; 613 } 614 615 static void info_record_alloction(struct expression *buffer, struct range_list *rl) 616 { 617 char *name; 618 619 if (!option_info) 620 return; 621 622 name = get_member_name(buffer); 623 if (!name && is_static(buffer)) 624 name = expr_to_var(buffer); 625 if (!name) 626 return; 627 if (rl && !is_whole_rl(rl)) 628 sql_insert_function_type_size(name, show_rl(rl)); 629 else 630 sql_insert_function_type_size(name, "(-1)"); 631 632 free_string(name); 633 } 634 635 static void store_alloc(struct expression *expr, struct range_list *rl) 636 { 637 struct symbol *type; 638 639 rl = clone_rl(rl); // FIXME!!! 640 if (!rl) 641 rl = size_to_rl(UNKNOWN_SIZE); 642 643 if (rl_min(rl).value != UNKNOWN_SIZE || 644 rl_max(rl).value != UNKNOWN_SIZE || 645 get_state_expr(my_size_id, expr)) 646 set_state_expr(my_size_id, expr, alloc_estate_rl(rl)); 647 648 type = get_type(expr); 649 if (!type) 650 return; 651 if (type->type != SYM_PTR) 652 return; 653 type = get_real_base_type(type); 654 if (!type) 655 return; 656 if (type == &void_ctype) 657 return; 658 if (type->type != SYM_BASETYPE && type->type != SYM_PTR) 659 return; 660 661 info_record_alloction(expr, rl); 662 } 663 664 static bool is_array_base(struct expression *expr) 665 { 666 struct symbol *type; 667 668 type = get_type(expr); 669 if (type && type->type == SYM_ARRAY) 670 return true; 671 return false; 672 } 673 674 static void match_array_assignment(struct expression *expr) 675 { 676 struct expression *left; 677 struct expression *right; 678 char *left_member, *right_member; 679 struct range_list *rl; 680 sval_t sval; 681 682 if (expr->op != '=') 683 return; 684 685 left = strip_expr(expr->left); 686 right = strip_expr(expr->right); 687 right = strip_ampersands(right); 688 689 if (!is_pointer(left)) 690 return; 691 /* char buf[24] = "str"; */ 692 if (is_array_base(left)) 693 return; 694 if (is_allocation_function(right)) 695 return; 696 697 left_member = get_member_name(left); 698 right_member = get_member_name(right); 699 if (left_member && right_member && strcmp(left_member, right_member) == 0) { 700 free_string(left_member); 701 free_string(right_member); 702 return; 703 } 704 free_string(left_member); 705 free_string(right_member); 706 707 if (get_implied_value(right, &sval) && sval.value == 0) { 708 rl = alloc_int_rl(0); 709 goto store; 710 } 711 712 rl = get_array_size_bytes_rl(right); 713 if (!rl && __in_fake_assign) 714 return; 715 716 store: 717 store_alloc(left, rl); 718 } 719 720 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg) 721 { 722 int size_arg = PTR_INT(_size_arg); 723 struct expression *right; 724 struct expression *arg; 725 struct range_list *rl; 726 727 right = strip_expr(expr->right); 728 arg = get_argument_from_call_expr(right->args, size_arg); 729 get_absolute_rl(arg, &rl); 730 rl = cast_rl(&int_ctype, rl); 731 store_alloc(expr->left, rl); 732 } 733 734 static void match_calloc(const char *fn, struct expression *expr, void *_param) 735 { 736 struct expression *right; 737 struct expression *size, *nr, *mult; 738 struct range_list *rl; 739 int param = PTR_INT(_param); 740 741 right = strip_expr(expr->right); 742 nr = get_argument_from_call_expr(right->args, param); 743 size = get_argument_from_call_expr(right->args, param + 1); 744 mult = binop_expression(nr, '*', size); 745 if (get_implied_rl(mult, &rl)) 746 store_alloc(expr->left, rl); 747 else 748 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE)); 749 } 750 751 static void match_page(const char *fn, struct expression *expr, void *_unused) 752 { 753 sval_t page_size = { 754 .type = &int_ctype, 755 {.value = 4096}, 756 }; 757 758 store_alloc(expr->left, alloc_rl(page_size, page_size)); 759 } 760 761 static void match_strndup(const char *fn, struct expression *expr, void *unused) 762 { 763 struct expression *fn_expr; 764 struct expression *size_expr; 765 sval_t size; 766 767 fn_expr = strip_expr(expr->right); 768 size_expr = get_argument_from_call_expr(fn_expr->args, 1); 769 if (get_implied_max(size_expr, &size)) { 770 size.value++; 771 store_alloc(expr->left, size_to_rl(size.value)); 772 } else { 773 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE)); 774 } 775 776 } 777 778 static void match_alloc_pages(const char *fn, struct expression *expr, void *_order_arg) 779 { 780 int order_arg = PTR_INT(_order_arg); 781 struct expression *right; 782 struct expression *arg; 783 sval_t sval; 784 785 right = strip_expr(expr->right); 786 arg = get_argument_from_call_expr(right->args, order_arg); 787 if (!get_implied_value(arg, &sval)) 788 return; 789 if (sval.value < 0 || sval.value > 10) 790 return; 791 792 sval.type = &int_ctype; 793 sval.value = 1 << sval.value; 794 sval.value *= 4096; 795 796 store_alloc(expr->left, alloc_rl(sval, sval)); 797 } 798 799 static int is_type_bytes(struct range_list *rl, struct expression *arg) 800 { 801 struct symbol *type; 802 sval_t sval; 803 804 if (!rl_to_sval(rl, &sval)) 805 return 0; 806 807 type = get_type(arg); 808 if (!type) 809 return 0; 810 if (type->type != SYM_PTR) 811 return 0; 812 type = get_real_base_type(type); 813 if (type->type != SYM_STRUCT && 814 type->type != SYM_UNION) 815 return 0; 816 if (sval.value != type_bytes(type)) 817 return 0; 818 return 1; 819 } 820 821 static void match_call(struct expression *expr) 822 { 823 struct expression *arg; 824 struct symbol *type; 825 struct range_list *rl; 826 int i; 827 828 i = -1; 829 FOR_EACH_PTR(expr->args, arg) { 830 i++; 831 type = get_type(arg); 832 if (!type || (type->type != SYM_PTR && type->type != SYM_ARRAY)) 833 continue; 834 rl = get_array_size_bytes_rl(arg); 835 if (!rl) 836 continue; 837 if (rl_min(rl).value == UNKNOWN_SIZE && 838 rl_max(rl).value == UNKNOWN_SIZE) 839 continue; 840 if (is_whole_rl(rl)) 841 continue; 842 if (is_type_bytes(rl, arg)) 843 continue; 844 sql_insert_caller_info(expr, BUF_SIZE, i, "$", show_rl(rl)); 845 } END_FOR_EACH_PTR(arg); 846 } 847 848 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm) 849 { 850 sval_t sval; 851 852 if (!estate_rl(sm->state) || 853 (estate_get_single_value(sm->state, &sval) && 854 (sval.value == -1 || sval.value == 0))) 855 return; 856 857 sql_insert_caller_info(call, BUF_SIZE, param, printed_name, sm->state->name); 858 } 859 860 /* 861 * This is slightly (very) weird because half of this stuff is handled in 862 * smatch_parse_call_math.c which is poorly named. But anyway, add some buf 863 * sizes here. 864 * 865 */ 866 static void print_returned_allocations(int return_id, char *return_ranges, struct expression *expr) 867 { 868 const char *param_math; 869 struct range_list *rl; 870 char buf[64]; 871 sval_t sval; 872 873 rl = get_array_size_bytes_rl(expr); 874 param_math = get_allocation_math(expr); 875 if (!rl && !param_math) 876 return; 877 878 if (!param_math && 879 rl_to_sval(rl, &sval) && 880 (sval.value == -1 || sval.value == 0)) 881 return; 882 883 if (param_math) 884 snprintf(buf, sizeof(buf), "%s[%s]", show_rl(rl), param_math); 885 else 886 snprintf(buf, sizeof(buf), "%s", show_rl(rl)); 887 888 // FIXME: don't store if you can guess the size from the type 889 // FIXME: return if we allocate a parameter $0->bar 890 sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "", buf); 891 } 892 893 static void record_global_size(struct symbol *sym) 894 { 895 int bytes; 896 char buf[16]; 897 898 if (!sym->ident) 899 return; 900 901 if (!(sym->ctype.modifiers & MOD_TOPLEVEL) || 902 sym->ctype.modifiers & MOD_STATIC) 903 return; 904 905 bytes = get_array_size_bytes(symbol_expression(sym)); 906 if (bytes <= 1) 907 return; 908 909 snprintf(buf, sizeof(buf), "%d", bytes); 910 sql_insert_data_info_var_sym(sym->ident->name, sym, BUF_SIZE, buf); 911 } 912 913 void register_buf_size(int id) 914 { 915 my_size_id = id; 916 917 set_dynamic_states(my_size_id); 918 919 add_unmatched_state_hook(my_size_id, &unmatched_size_state); 920 add_merge_hook(my_size_id, &merge_estates); 921 922 select_caller_info_hook(set_param_buf_size, BUF_SIZE); 923 select_return_states_hook(BUF_SIZE, &db_returns_buf_size); 924 add_split_return_callback(print_returned_allocations); 925 926 allocation_funcs = create_function_hashtable(100); 927 add_allocation_function("malloc", &match_alloc, 0); 928 add_allocation_function("calloc", &match_calloc, 0); 929 add_allocation_function("memdup", &match_alloc, 1); 930 add_allocation_function("realloc", &match_alloc, 1); 931 if (option_project == PROJ_KERNEL) { 932 add_allocation_function("kmalloc", &match_alloc, 0); 933 add_allocation_function("kmalloc_node", &match_alloc, 0); 934 add_allocation_function("kzalloc", &match_alloc, 0); 935 add_allocation_function("kzalloc_node", &match_alloc, 0); 936 add_allocation_function("vmalloc", &match_alloc, 0); 937 add_allocation_function("vzalloc", &match_alloc, 0); 938 add_allocation_function("__vmalloc", &match_alloc, 0); 939 add_allocation_function("kvmalloc", &match_alloc, 0); 940 add_allocation_function("kcalloc", &match_calloc, 0); 941 add_allocation_function("kmalloc_array", &match_calloc, 0); 942 add_allocation_function("devm_kmalloc_array", &match_calloc, 1); 943 add_allocation_function("sock_kmalloc", &match_alloc, 1); 944 add_allocation_function("kmemdup", &match_alloc, 1); 945 add_allocation_function("kmemdup_user", &match_alloc, 1); 946 add_allocation_function("dma_alloc_attrs", &match_alloc, 1); 947 add_allocation_function("pci_alloc_consistent", &match_alloc, 1); 948 add_allocation_function("pci_alloc_coherent", &match_alloc, 1); 949 add_allocation_function("devm_kmalloc", &match_alloc, 1); 950 add_allocation_function("devm_kzalloc", &match_alloc, 1); 951 add_allocation_function("krealloc", &match_alloc, 1); 952 add_allocation_function("__alloc_bootmem", &match_alloc, 0); 953 add_allocation_function("alloc_bootmem", &match_alloc, 0); 954 add_allocation_function("kmap", &match_page, 0); 955 add_allocation_function("kmap_atomic", &match_page, 0); 956 add_allocation_function("get_zeroed_page", &match_page, 0); 957 add_allocation_function("alloc_page", &match_page, 0); 958 add_allocation_function("alloc_pages", &match_alloc_pages, 1); 959 add_allocation_function("alloc_pages_current", &match_alloc_pages, 1); 960 add_allocation_function("__get_free_pages", &match_alloc_pages, 1); 961 add_allocation_function("dma_alloc_contiguous", &match_alloc, 1); 962 add_allocation_function("dma_alloc_coherent", &match_alloc, 1); 963 } 964 965 add_allocation_function("strndup", match_strndup, 0); 966 if (option_project == PROJ_KERNEL) 967 add_allocation_function("kstrndup", match_strndup, 0); 968 969 add_modification_hook(my_size_id, &set_size_undefined); 970 971 add_merge_hook(my_size_id, &merge_size_func); 972 973 if (option_info) 974 add_hook(record_global_size, BASE_HOOK); 975 } 976 977 void register_buf_size_late(int id) 978 { 979 /* has to happen after match_alloc() */ 980 add_hook(&match_array_assignment, ASSIGNMENT_HOOK); 981 982 add_hook(&match_call, FUNCTION_CALL_HOOK); 983 add_member_info_callback(my_size_id, struct_member_callback); 984 }