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 "smatch.h"
19 #include "smatch_extra.h"
20
21 static int my_id;
22
23 struct allocator {
24 const char *func;
25 int param;
26 int param2;
27 };
28
29 static struct allocator generic_allocator_table[] = {
30 {"malloc", 0},
31 {"memdup", 1},
32 {"realloc", 1},
33 };
34
35 static struct allocator kernel_allocator_table[] = {
36 {"kmalloc", 0},
37 {"kzalloc", 0},
38 {"vmalloc", 0},
39 {"__vmalloc", 0},
40 {"vzalloc", 0},
41 {"sock_kmalloc", 1},
42 {"kmemdup", 1},
43 {"kmemdup_user", 1},
44 {"dma_alloc_attrs", 1},
45 {"pci_alloc_consistent", 1},
46 {"pci_alloc_coherent", 1},
47 {"devm_kmalloc", 1},
48 {"devm_kzalloc", 1},
49 {"krealloc", 1},
50 };
51
52 static struct allocator calloc_table[] = {
53 {"calloc", 0, 1},
54 {"kcalloc", 0, 1},
55 {"kmalloc_array", 0, 1},
56 {"devm_kcalloc", 1, 2},
57 };
58
59 static int bytes_per_element(struct expression *expr)
60 {
61 struct symbol *type;
62
63 type = get_type(expr);
64 if (!type)
65 return 0;
66
67 if (type->type != SYM_PTR && type->type != SYM_ARRAY)
68 return 0;
69
70 type = get_base_type(type);
71 return type_bytes(type);
72 }
73
74 static void save_constraint_required(struct expression *pointer, int op, struct expression *constraint)
75 {
76 char *data, *limit;
77
78 data = get_constraint_str(pointer);
307 if (!tmp)
308 return;
309
310 right = strip_expr(tmp);
311 if (right->type != EXPR_CALL)
312 return;
313
314 if (right->fn->type != EXPR_SYMBOL ||
315 !right->fn->symbol ||
316 !right->fn->symbol->ident)
317 return;
318
319 for (i = 0; i < ARRAY_SIZE(generic_allocator_table); i++) {
320 if (strcmp(right->fn->symbol->ident->name,
321 generic_allocator_table[i].func) == 0) {
322 size_arg = generic_allocator_table[i].param;
323 goto found;
324 }
325 }
326
327 if (option_project != PROJ_KERNEL)
328 return;
329
330 for (i = 0; i < ARRAY_SIZE(kernel_allocator_table); i++) {
331 if (strcmp(right->fn->symbol->ident->name,
332 kernel_allocator_table[i].func) == 0) {
333 size_arg = kernel_allocator_table[i].param;
334 goto found;
335 }
336 }
337
338 for (i = 0; i < ARRAY_SIZE(calloc_table); i++) {
339 if (strcmp(right->fn->symbol->ident->name,
340 calloc_table[i].func) == 0) {
341 size_arg = calloc_table[i].param;
342 size_arg2 = calloc_table[i].param2;
343 goto found;
344 }
345 }
346
347 return;
348
349 found:
350 arg = get_argument_from_call_expr(right->args, size_arg);
351 match_alloc_helper(expr->left, arg, 1);
352 if (size_arg2 == -1)
353 return;
354 arg = get_argument_from_call_expr(right->args, size_arg2);
355 match_alloc_helper(expr->left, arg, 1);
356 }
357
358 static void match_assign_ARRAY_SIZE(struct expression *expr)
359 {
360 struct expression *array;
361 char *data, *limit;
362 const char *macro;
450 free_string(right);
451 free_string(left);
452 }
453
454 void register_constraints_required(int id)
455 {
456 my_id = id;
457
458 add_hook(&match_assign_size, ASSIGNMENT_HOOK);
459 add_hook(&match_assign_data, ASSIGNMENT_HOOK);
460 add_hook(&match_assign_has_buf_comparison, ASSIGNMENT_HOOK);
461
462 add_hook(&match_assign_ARRAY_SIZE, ASSIGNMENT_HOOK);
463 add_hook(&match_assign_ARRAY_SIZE, GLOBAL_ASSIGNMENT_HOOK);
464 add_hook(&match_assign_buf_comparison, ASSIGNMENT_HOOK);
465 add_hook(&match_assign_constraint, ASSIGNMENT_HOOK);
466
467 add_allocation_function("malloc", &match_alloc, 0);
468 add_allocation_function("memdup", &match_alloc, 1);
469 add_allocation_function("realloc", &match_alloc, 1);
470 add_allocation_function("realloc", &match_calloc, 0);
471 if (option_project == PROJ_KERNEL) {
472 add_allocation_function("kmalloc", &match_alloc, 0);
473 add_allocation_function("kzalloc", &match_alloc, 0);
474 add_allocation_function("vmalloc", &match_alloc, 0);
475 add_allocation_function("__vmalloc", &match_alloc, 0);
476 add_allocation_function("vzalloc", &match_alloc, 0);
477 add_allocation_function("sock_kmalloc", &match_alloc, 1);
478 add_allocation_function("kmemdup", &match_alloc, 1);
479 add_allocation_function("kmemdup_user", &match_alloc, 1);
480 add_allocation_function("dma_alloc_attrs", &match_alloc, 1);
481 add_allocation_function("pci_alloc_consistent", &match_alloc, 1);
482 add_allocation_function("pci_alloc_coherent", &match_alloc, 1);
483 add_allocation_function("devm_kmalloc", &match_alloc, 1);
484 add_allocation_function("devm_kzalloc", &match_alloc, 1);
485 add_allocation_function("kcalloc", &match_calloc, 0);
486 add_allocation_function("kmalloc_array", &match_calloc, 0);
487 add_allocation_function("devm_kcalloc", &match_calloc, 1);
488 add_allocation_function("krealloc", &match_alloc, 1);
489 }
490 }
|
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 "smatch.h"
19 #include "smatch_extra.h"
20
21 static int my_id;
22
23 struct allocator {
24 const char *func;
25 int param;
26 int param2;
27 };
28
29 static struct allocator illumos_user_allocator_table[] = {
30 {"libld_malloc", 0},
31 {"libld_realloc", 1},
32 };
33
34 static struct allocator generic_allocator_table[] = {
35 {"malloc", 0},
36 {"memdup", 1},
37 {"realloc", 1},
38 };
39
40 static struct allocator kernel_allocator_table[] = {
41 {"kmalloc", 0},
42 {"kzalloc", 0},
43 {"vmalloc", 0},
44 {"__vmalloc", 0},
45 {"vzalloc", 0},
46 {"sock_kmalloc", 1},
47 {"kmemdup", 1},
48 {"kmemdup_user", 1},
49 {"dma_alloc_attrs", 1},
50 {"pci_alloc_consistent", 1},
51 {"pci_alloc_coherent", 1},
52 {"devm_kmalloc", 1},
53 {"devm_kzalloc", 1},
54 {"krealloc", 1},
55 };
56
57 static struct allocator illumos_user_calloc_table[] = {
58 {"libld_calloc", 0, 1},
59 {"calloc", 0, 1},
60 {"kcalloc", 0, 1},
61 {"kmalloc_array", 0, 1},
62 {"devm_kcalloc", 1, 2},
63 };
64
65 static struct allocator generic_calloc_table[] = {
66 {"calloc", 0, 1},
67 };
68
69 static struct allocator kernel_calloc_table[] = {
70 {"kcalloc", 0, 1},
71 {"kmalloc_array", 0, 1},
72 {"devm_kcalloc", 1, 2},
73 };
74
75 static int bytes_per_element(struct expression *expr)
76 {
77 struct symbol *type;
78
79 type = get_type(expr);
80 if (!type)
81 return 0;
82
83 if (type->type != SYM_PTR && type->type != SYM_ARRAY)
84 return 0;
85
86 type = get_base_type(type);
87 return type_bytes(type);
88 }
89
90 static void save_constraint_required(struct expression *pointer, int op, struct expression *constraint)
91 {
92 char *data, *limit;
93
94 data = get_constraint_str(pointer);
323 if (!tmp)
324 return;
325
326 right = strip_expr(tmp);
327 if (right->type != EXPR_CALL)
328 return;
329
330 if (right->fn->type != EXPR_SYMBOL ||
331 !right->fn->symbol ||
332 !right->fn->symbol->ident)
333 return;
334
335 for (i = 0; i < ARRAY_SIZE(generic_allocator_table); i++) {
336 if (strcmp(right->fn->symbol->ident->name,
337 generic_allocator_table[i].func) == 0) {
338 size_arg = generic_allocator_table[i].param;
339 goto found;
340 }
341 }
342
343 for (i = 0; i < ARRAY_SIZE(generic_calloc_table); i++) {
344 if (strcmp(right->fn->symbol->ident->name,
345 generic_calloc_table[i].func) == 0) {
346 size_arg = generic_calloc_table[i].param;
347 size_arg2 = generic_calloc_table[i].param2;
348 goto found;
349 }
350 }
351
352 if (option_project == PROJ_ILLUMOS_USER) {
353 if (strcmp(right->fn->symbol->ident->name,
354 illumos_user_allocator_table[i].func) == 0) {
355 size_arg = illumos_user_allocator_table[i].param;
356 goto found;
357 }
358
359 for (i = 0; i < ARRAY_SIZE(illumos_user_calloc_table); i++) {
360 if (strcmp(right->fn->symbol->ident->name,
361 illumos_user_calloc_table[i].func) == 0) {
362 size_arg = illumos_user_calloc_table[i].param;
363 size_arg2 = illumos_user_calloc_table[i].param2;
364 goto found;
365 }
366 }
367 }
368
369 if (option_project != PROJ_KERNEL)
370 return;
371
372 for (i = 0; i < ARRAY_SIZE(kernel_allocator_table); i++) {
373 if (strcmp(right->fn->symbol->ident->name,
374 kernel_allocator_table[i].func) == 0) {
375 size_arg = kernel_allocator_table[i].param;
376 goto found;
377 }
378 }
379
380 for (i = 0; i < ARRAY_SIZE(kernel_calloc_table); i++) {
381 if (strcmp(right->fn->symbol->ident->name,
382 kernel_calloc_table[i].func) == 0) {
383 size_arg = kernel_calloc_table[i].param;
384 size_arg2 = kernel_calloc_table[i].param2;
385 goto found;
386 }
387 }
388
389 return;
390
391 found:
392 arg = get_argument_from_call_expr(right->args, size_arg);
393 match_alloc_helper(expr->left, arg, 1);
394 if (size_arg2 == -1)
395 return;
396 arg = get_argument_from_call_expr(right->args, size_arg2);
397 match_alloc_helper(expr->left, arg, 1);
398 }
399
400 static void match_assign_ARRAY_SIZE(struct expression *expr)
401 {
402 struct expression *array;
403 char *data, *limit;
404 const char *macro;
492 free_string(right);
493 free_string(left);
494 }
495
496 void register_constraints_required(int id)
497 {
498 my_id = id;
499
500 add_hook(&match_assign_size, ASSIGNMENT_HOOK);
501 add_hook(&match_assign_data, ASSIGNMENT_HOOK);
502 add_hook(&match_assign_has_buf_comparison, ASSIGNMENT_HOOK);
503
504 add_hook(&match_assign_ARRAY_SIZE, ASSIGNMENT_HOOK);
505 add_hook(&match_assign_ARRAY_SIZE, GLOBAL_ASSIGNMENT_HOOK);
506 add_hook(&match_assign_buf_comparison, ASSIGNMENT_HOOK);
507 add_hook(&match_assign_constraint, ASSIGNMENT_HOOK);
508
509 add_allocation_function("malloc", &match_alloc, 0);
510 add_allocation_function("memdup", &match_alloc, 1);
511 add_allocation_function("realloc", &match_alloc, 1);
512 add_allocation_function("calloc", &match_calloc, 0);
513 if (option_project == PROJ_ILLUMOS_USER) {
514 add_allocation_function("libld_malloc", &match_alloc, 0);
515 add_allocation_function("libld_realloc", &match_alloc, 1);
516 add_allocation_function("libld_calloc", &match_calloc, 0);
517 }
518 if (option_project == PROJ_KERNEL) {
519 add_allocation_function("kmalloc", &match_alloc, 0);
520 add_allocation_function("kzalloc", &match_alloc, 0);
521 add_allocation_function("vmalloc", &match_alloc, 0);
522 add_allocation_function("__vmalloc", &match_alloc, 0);
523 add_allocation_function("vzalloc", &match_alloc, 0);
524 add_allocation_function("sock_kmalloc", &match_alloc, 1);
525 add_allocation_function("kmemdup", &match_alloc, 1);
526 add_allocation_function("kmemdup_user", &match_alloc, 1);
527 add_allocation_function("dma_alloc_attrs", &match_alloc, 1);
528 add_allocation_function("pci_alloc_consistent", &match_alloc, 1);
529 add_allocation_function("pci_alloc_coherent", &match_alloc, 1);
530 add_allocation_function("devm_kmalloc", &match_alloc, 1);
531 add_allocation_function("devm_kzalloc", &match_alloc, 1);
532 add_allocation_function("kcalloc", &match_calloc, 0);
533 add_allocation_function("kmalloc_array", &match_calloc, 0);
534 add_allocation_function("devm_kcalloc", &match_calloc, 1);
535 add_allocation_function("krealloc", &match_alloc, 1);
536 }
537 }
|