1 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux %s -verify \ 2 // RUN: -Wno-incompatible-library-redeclaration \ 3 // RUN: -analyzer-checker=core \ 4 // RUN: -analyzer-checker=unix.Malloc 5 6 #define __GFP_ZERO 0x8000 7 #define NULL ((void *)0) 8 9 typedef __typeof(sizeof(int)) size_t; 10 11 void *kmalloc(size_t, int); 12 void kfree(void *); 13 14 struct test { 15 }; 16 17 void foo(struct test *); 18 19 void test_zeroed(void) { 20 struct test **list, *t; 21 int i; 22 23 list = kmalloc(sizeof(*list) * 10, __GFP_ZERO); 24 if (list == NULL) 25 return; 26 27 for (i = 0; i < 10; i++) { 28 t = list[i]; 29 foo(t); 30 } 31 kfree(list); // no-warning 32 } 33 34 void test_nonzero(void) { 35 struct test **list, *t; 36 int i; 37 38 list = kmalloc(sizeof(*list) * 10, 0); 39 if (list == NULL) 40 return; 41 42 for (i = 0; i < 10; i++) { 43 t = list[i]; // expected-warning{{undefined}} 44 foo(t); 45 } 46 kfree(list); 47 } 48 49 void test_indeterminate(int flags) { 50 struct test **list, *t; 51 int i; 52 53 list = kmalloc(sizeof(*list) * 10, flags); 54 if (list == NULL) 55 return; 56 57 for (i = 0; i < 10; i++) { 58 t = list[i]; // expected-warning{{undefined}} 59 foo(t); 60 } 61 kfree(list); 62 } 63 64 typedef unsigned long long uint64_t; 65 66 struct malloc_type; 67 68 // 3 parameter malloc: 69 // https://www.freebsd.org/cgi/man.cgi?query=malloc&sektion=9 70 void *malloc(unsigned long size, struct malloc_type *mtp, int flags); 71 72 void test_3arg_malloc(struct malloc_type *mtp) { 73 struct test **list, *t; 74 int i; 75 76 list = malloc(sizeof(*list) * 10, mtp, __GFP_ZERO); 77 if (list == NULL) 78 return; 79 80 for (i = 0; i < 10; i++) { 81 t = list[i]; 82 foo(t); 83 } 84 kfree(list); // no-warning 85 } 86 87 void test_3arg_malloc_nonzero(struct malloc_type *mtp) { 88 struct test **list, *t; 89 int i; 90 91 list = malloc(sizeof(*list) * 10, mtp, 0); 92 if (list == NULL) 93 return; 94 95 for (i = 0; i < 10; i++) { 96 t = list[i]; // expected-warning{{undefined}} 97 foo(t); 98 } 99 kfree(list); 100 } 101 102 void test_3arg_malloc_indeterminate(struct malloc_type *mtp, int flags) { 103 struct test **list, *t; 104 int i; 105 106 list = malloc(sizeof(*list) * 10, mtp, flags); 107 if (list == NULL) 108 return; 109 110 for (i = 0; i < 10; i++) { 111 t = list[i]; // expected-warning{{undefined}} 112 foo(t); 113 } 114 kfree(list); 115 } 116 117 void test_3arg_malloc_leak(struct malloc_type *mtp, int flags) { 118 struct test **list; 119 120 list = malloc(sizeof(*list) * 10, mtp, flags); 121 if (list == NULL) 122 return; 123 } // expected-warning{{Potential leak of memory pointed to by 'list'}} 124 125 // kmalloc can return a constant value defined in ZERO_SIZE_PTR 126 // if a block of size 0 is requested 127 #define ZERO_SIZE_PTR ((void *)16) 128 129 void test_kfree_ZERO_SIZE_PTR(void) { 130 void *ptr = ZERO_SIZE_PTR; 131 kfree(ptr); // no warning about freeing this value 132 } 133 134 void test_kfree_other_constant_value(void) { 135 void *ptr = (void *)1; 136 kfree(ptr); // expected-warning{{Argument to 'kfree()' is a constant address (1)}} 137 } 138