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
test_zeroed()19 void test_zeroed() {
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
test_nonzero()34 void test_nonzero() {
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
test_indeterminate(int flags)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
test_3arg_malloc(struct malloc_type * mtp)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
test_3arg_malloc_nonzero(struct malloc_type * mtp)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
test_3arg_malloc_indeterminate(struct malloc_type * mtp,int flags)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
test_3arg_malloc_leak(struct malloc_type * mtp,int flags)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
test_kfree_ZERO_SIZE_PTR()129 void test_kfree_ZERO_SIZE_PTR() {
130 void *ptr = ZERO_SIZE_PTR;
131 kfree(ptr); // no warning about freeing this value
132 }
133
test_kfree_other_constant_value()134 void test_kfree_other_constant_value() {
135 void *ptr = (void *)1;
136 kfree(ptr); // expected-warning{{Argument to kfree() is a constant address (1)}}
137 }
138