xref: /llvm-project/clang/test/Analysis/malloc.cpp (revision f82fb06cd1276bd358315e45cd3f4312b1319314)
1 // RUN: %clang_analyze_cc1 -w -verify %s \
2 // RUN:   -analyzer-checker=core \
3 // RUN:   -analyzer-checker=alpha.deadcode.UnreachableCode \
4 // RUN:   -analyzer-checker=alpha.core.CastSize \
5 // RUN:   -analyzer-checker=unix.Malloc \
6 // RUN:   -analyzer-checker=cplusplus.NewDelete \
7 // RUN:   -analyzer-checker=optin.taint.TaintPropagation \
8 // RUN:   -analyzer-checker=optin.taint.TaintedAlloc
9 
10 // RUN: %clang_analyze_cc1 -w -verify %s \
11 // RUN:   -triple i386-unknown-linux-gnu \
12 // RUN:   -analyzer-checker=core \
13 // RUN:   -analyzer-checker=alpha.deadcode.UnreachableCode \
14 // RUN:   -analyzer-checker=alpha.core.CastSize \
15 // RUN:   -analyzer-checker=unix.Malloc \
16 // RUN:   -analyzer-checker=cplusplus.NewDelete \
17 // RUN:   -analyzer-checker=optin.taint.TaintPropagation \
18 // RUN:   -analyzer-checker=optin.taint.TaintedAlloc
19 
20 // RUN: %clang_analyze_cc1 -w -verify %s -DTEST_INLINABLE_ALLOCATORS \
21 // RUN:   -analyzer-checker=core \
22 // RUN:   -analyzer-checker=alpha.deadcode.UnreachableCode \
23 // RUN:   -analyzer-checker=alpha.core.CastSize \
24 // RUN:   -analyzer-checker=unix.Malloc \
25 // RUN:   -analyzer-checker=cplusplus.NewDelete \
26 // RUN:   -analyzer-checker=optin.taint.TaintPropagation \
27 // RUN:   -analyzer-checker=optin.taint.TaintedAlloc
28 
29 // RUN: %clang_analyze_cc1 -w -verify %s -DTEST_INLINABLE_ALLOCATORS \
30 // RUN:   -triple i386-unknown-linux-gnu \
31 // RUN:   -analyzer-checker=core \
32 // RUN:   -analyzer-checker=alpha.deadcode.UnreachableCode \
33 // RUN:   -analyzer-checker=alpha.core.CastSize \
34 // RUN:   -analyzer-checker=unix.Malloc \
35 // RUN:   -analyzer-checker=cplusplus.NewDelete \
36 // RUN:   -analyzer-checker=optin.taint.TaintPropagation \
37 // RUN:   -analyzer-checker=optin.taint.TaintedAlloc
38 
39 #include "Inputs/system-header-simulator-cxx.h"
40 
41 typedef __typeof(sizeof(int)) size_t;
42 void *malloc(size_t);
43 void free(void *);
44 void *realloc(void *ptr, size_t size);
45 void *calloc(size_t nmemb, size_t size);
46 char *strdup(const char *s);
47 int scanf( const char* format, ... );
48 
49 void taintAlloc() {
50   size_t size = 0;
51   scanf("%zu", &size);
52   int *ptr = new int[size];// expected-warning{{Memory allocation function is called with a tainted (potentially attacker controlled) value}}
53   delete[] ptr;
54 }
55 
56 void checkThatMallocCheckerIsRunning() {
57   malloc(4);
58 } // expected-warning{{leak}}
59 
60 struct Foo {
61     mutable void* m_data;
62     Foo(void* data) : m_data(data) {}
63 };
64 Foo aFunction() {
65     return malloc(10);
66 }
67 
68 // Assume that functions which take a function pointer can free memory even if
69 // they are defined in system headers and take the const pointer to the
70 // allocated memory.
71 // Test default parameter.
72 int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = free);
73 void r11160612_3() {
74   char *x = (char*)malloc(12);
75   const_ptr_and_callback_def_param(0, x, 12);
76 }
77 
78 int const_ptr_and_callback_def_param_null(int, const char*, int n, void(*)(void*) = 0);
79 void r11160612_no_callback() {
80   char *x = (char*)malloc(12);
81   const_ptr_and_callback_def_param_null(0, x, 12);
82 } // expected-warning{{leak}}
83 
84 // Test member function pointer.
85 struct CanFreeMemory {
86   static void myFree(void*);
87 };
88 //This is handled because we look at the type of the parameter(not argument).
89 void r11160612_3(CanFreeMemory* p) {
90   char *x = (char*)malloc(12);
91   const_ptr_and_callback_def_param(0, x, 12, p->myFree);
92 }
93 
94 
95 namespace PR13751 {
96   class OwningVector {
97     void **storage;
98     size_t length;
99   public:
100     OwningVector();
101     ~OwningVector();
102     void push_back(void *Item) {
103       storage[length++] = Item;
104     }
105   };
106 
107   void testDestructors() {
108     OwningVector v;
109     v.push_back(malloc(4));
110     // no leak warning; freed in destructor
111   }
112 }
113 
114 struct X { void *a; };
115 
116 struct X get() {
117   struct X result;
118   result.a = malloc(4);
119   return result; // no-warning
120 }
121 
122 // Ensure that regions accessible through a LazyCompoundVal trigger region escape.
123 // Malloc checker used to report leaks for the following two test cases.
124 struct Property {
125   char* getterName;
126   Property(char* n)
127   : getterName(n) {}
128 
129 };
130 void append(Property x);
131 
132 void appendWrapper(char *getterName) {
133   append(Property(getterName));
134 }
135 void foo(const char* name) {
136   char* getterName = strdup(name);
137   appendWrapper(getterName); // no-warning
138 }
139 
140 struct NestedProperty {
141   Property prop;
142   NestedProperty(Property p)
143   : prop(p) {}
144 };
145 void appendNested(NestedProperty x);
146 
147 void appendWrapperNested(char *getterName) {
148   appendNested(NestedProperty(Property(getterName)));
149 }
150 void fooNested(const char* name) {
151   char* getterName = strdup(name);
152   appendWrapperNested(getterName); // no-warning
153 }
154 
155 namespace PR31226 {
156   struct b2 {
157     int f;
158   };
159 
160   struct b1 : virtual b2 {
161     void m();
162   };
163 
164   struct d : b1, b2 {
165   };
166 
167   void f() {
168     d *p = new d();
169     p->m(); // no-crash // no-warning
170   }
171 }
172 
173 // Allow __cxa_demangle to escape.
174 char* test_cxa_demangle(const char* sym) {
175   size_t funcnamesize = 256;
176   char* funcname = (char*)malloc(funcnamesize);
177   int status;
178   char* ret = abi::__cxa_demangle(sym, funcname, &funcnamesize, &status);
179   if (status == 0) {
180     funcname = ret;
181   }
182   return funcname; // no-warning
183 }
184 
185 namespace argument_leak {
186 class A {
187   char *name;
188 
189 public:
190   char *getName() {
191     if (!name) {
192       name = static_cast<char *>(malloc(10));
193     }
194     return name;
195   }
196   ~A() {
197     if (name) {
198       delete[] name;
199     }
200   }
201 };
202 
203 void test(A a) {
204   (void)a.getName();
205 }
206 } // namespace argument_leak
207 
208 #define ZERO_SIZE_PTR ((void *)16)
209 
210 void test_delete_ZERO_SIZE_PTR() {
211   int *Ptr = (int *)ZERO_SIZE_PTR;
212   // ZERO_SIZE_PTR is specially handled but only for malloc family
213   delete Ptr; // expected-warning{{Argument to 'delete' is a constant address (16)}}
214 }
215 
216 namespace pr46253_class {
217 class a {
218   void *realloc(int, bool = false) { realloc(1); } // no-crash
219 };
220 } // namespace pr46253_class
221 
222 namespace pr46253_retty{
223 void realloc(void *ptr, size_t size) { realloc(ptr, size); } // no-crash
224 } // namespace pr46253_retty
225 
226 namespace pr46253_paramty{
227 void *realloc(void **ptr, size_t size) { realloc(ptr, size); } // no-crash
228 } // namespace pr46253_paramty
229 
230 namespace pr46253_paramty2{
231 void *realloc(void *ptr, int size) { realloc(ptr, size); } // no-crash
232 } // namespace pr46253_paramty2
233 
234 namespace pr81597 {
235 struct S {};
236 struct T {
237   void free(const S& s);
238 };
239 void f(T& t) {
240   S s;
241   t.free(s); // no-warning: This is not the free you are looking for...
242 }
243 } // namespace pr81597
244