1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18
19#include <limits.h>
20#include <stdint.h>
21#include <stdlib.h>
22#include <malloc.h>
23#include <unistd.h>
24
25#include "private/bionic_config.h"
26
27TEST(malloc, malloc_std) {
28  // Simple malloc test.
29  void *ptr = malloc(100);
30  ASSERT_TRUE(ptr != NULL);
31  ASSERT_LE(100U, malloc_usable_size(ptr));
32  free(ptr);
33}
34
35TEST(malloc, malloc_overflow) {
36  errno = 0;
37  ASSERT_EQ(NULL, malloc(SIZE_MAX));
38  ASSERT_EQ(ENOMEM, errno);
39}
40
41TEST(malloc, calloc_std) {
42  // Simple calloc test.
43  size_t alloc_len = 100;
44  char *ptr = (char *)calloc(1, alloc_len);
45  ASSERT_TRUE(ptr != NULL);
46  ASSERT_LE(alloc_len, malloc_usable_size(ptr));
47  for (size_t i = 0; i < alloc_len; i++) {
48    ASSERT_EQ(0, ptr[i]);
49  }
50  free(ptr);
51}
52
53TEST(malloc, calloc_illegal) {
54  errno = 0;
55  ASSERT_EQ(NULL, calloc(-1, 100));
56  ASSERT_EQ(ENOMEM, errno);
57}
58
59TEST(malloc, calloc_overflow) {
60  errno = 0;
61  ASSERT_EQ(NULL, calloc(1, SIZE_MAX));
62  ASSERT_EQ(ENOMEM, errno);
63  errno = 0;
64  ASSERT_EQ(NULL, calloc(SIZE_MAX, SIZE_MAX));
65  ASSERT_EQ(ENOMEM, errno);
66  errno = 0;
67  ASSERT_EQ(NULL, calloc(2, SIZE_MAX));
68  ASSERT_EQ(ENOMEM, errno);
69  errno = 0;
70  ASSERT_EQ(NULL, calloc(SIZE_MAX, 2));
71  ASSERT_EQ(ENOMEM, errno);
72}
73
74TEST(malloc, memalign_multiple) {
75  // Memalign test where the alignment is any value.
76  for (size_t i = 0; i <= 12; i++) {
77    for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
78      char *ptr = reinterpret_cast<char*>(memalign(alignment, 100));
79      ASSERT_TRUE(ptr != NULL) << "Failed at alignment " << alignment;
80      ASSERT_LE(100U, malloc_usable_size(ptr)) << "Failed at alignment " << alignment;
81      ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % ((1U << i)))
82          << "Failed at alignment " << alignment;
83      free(ptr);
84    }
85  }
86}
87
88TEST(malloc, memalign_overflow) {
89  ASSERT_EQ(NULL, memalign(4096, SIZE_MAX));
90}
91
92TEST(malloc, memalign_non_power2) {
93  void* ptr;
94  for (size_t align = 0; align <= 256; align++) {
95    ptr = memalign(align, 1024);
96    ASSERT_TRUE(ptr != NULL) << "Failed at align " << align;
97    free(ptr);
98  }
99}
100
101TEST(malloc, posix_memalign_non_power2) {
102  void* ptr;
103  ASSERT_EQ(EINVAL, posix_memalign(&ptr, 17, 1024));
104}
105
106TEST(malloc, posix_memalign_overflow) {
107  void* ptr;
108  ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
109}
110
111TEST(malloc, memalign_realloc) {
112  // Memalign and then realloc the pointer a couple of times.
113  for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
114    char *ptr = (char*)memalign(alignment, 100);
115    ASSERT_TRUE(ptr != NULL);
116    ASSERT_LE(100U, malloc_usable_size(ptr));
117    ASSERT_EQ(0U, (intptr_t)ptr % alignment);
118    memset(ptr, 0x23, 100);
119
120    ptr = (char*)realloc(ptr, 200);
121    ASSERT_TRUE(ptr != NULL);
122    ASSERT_LE(200U, malloc_usable_size(ptr));
123    ASSERT_TRUE(ptr != NULL);
124    for (size_t i = 0; i < 100; i++) {
125      ASSERT_EQ(0x23, ptr[i]);
126    }
127    memset(ptr, 0x45, 200);
128
129    ptr = (char*)realloc(ptr, 300);
130    ASSERT_TRUE(ptr != NULL);
131    ASSERT_LE(300U, malloc_usable_size(ptr));
132    for (size_t i = 0; i < 200; i++) {
133      ASSERT_EQ(0x45, ptr[i]);
134    }
135    memset(ptr, 0x67, 300);
136
137    ptr = (char*)realloc(ptr, 250);
138    ASSERT_TRUE(ptr != NULL);
139    ASSERT_LE(250U, malloc_usable_size(ptr));
140    for (size_t i = 0; i < 250; i++) {
141      ASSERT_EQ(0x67, ptr[i]);
142    }
143    free(ptr);
144  }
145}
146
147TEST(malloc, malloc_realloc_larger) {
148  // Realloc to a larger size, malloc is used for the original allocation.
149  char *ptr = (char *)malloc(100);
150  ASSERT_TRUE(ptr != NULL);
151  ASSERT_LE(100U, malloc_usable_size(ptr));
152  memset(ptr, 67, 100);
153
154  ptr = (char *)realloc(ptr, 200);
155  ASSERT_TRUE(ptr != NULL);
156  ASSERT_LE(200U, malloc_usable_size(ptr));
157  for (size_t i = 0; i < 100; i++) {
158    ASSERT_EQ(67, ptr[i]);
159  }
160  free(ptr);
161}
162
163TEST(malloc, malloc_realloc_smaller) {
164  // Realloc to a smaller size, malloc is used for the original allocation.
165  char *ptr = (char *)malloc(200);
166  ASSERT_TRUE(ptr != NULL);
167  ASSERT_LE(200U, malloc_usable_size(ptr));
168  memset(ptr, 67, 200);
169
170  ptr = (char *)realloc(ptr, 100);
171  ASSERT_TRUE(ptr != NULL);
172  ASSERT_LE(100U, malloc_usable_size(ptr));
173  for (size_t i = 0; i < 100; i++) {
174    ASSERT_EQ(67, ptr[i]);
175  }
176  free(ptr);
177}
178
179TEST(malloc, malloc_multiple_realloc) {
180  // Multiple reallocs, malloc is used for the original allocation.
181  char *ptr = (char *)malloc(200);
182  ASSERT_TRUE(ptr != NULL);
183  ASSERT_LE(200U, malloc_usable_size(ptr));
184  memset(ptr, 0x23, 200);
185
186  ptr = (char *)realloc(ptr, 100);
187  ASSERT_TRUE(ptr != NULL);
188  ASSERT_LE(100U, malloc_usable_size(ptr));
189  for (size_t i = 0; i < 100; i++) {
190    ASSERT_EQ(0x23, ptr[i]);
191  }
192
193  ptr = (char*)realloc(ptr, 50);
194  ASSERT_TRUE(ptr != NULL);
195  ASSERT_LE(50U, malloc_usable_size(ptr));
196  for (size_t i = 0; i < 50; i++) {
197    ASSERT_EQ(0x23, ptr[i]);
198  }
199
200  ptr = (char*)realloc(ptr, 150);
201  ASSERT_TRUE(ptr != NULL);
202  ASSERT_LE(150U, malloc_usable_size(ptr));
203  for (size_t i = 0; i < 50; i++) {
204    ASSERT_EQ(0x23, ptr[i]);
205  }
206  memset(ptr, 0x23, 150);
207
208  ptr = (char*)realloc(ptr, 425);
209  ASSERT_TRUE(ptr != NULL);
210  ASSERT_LE(425U, malloc_usable_size(ptr));
211  for (size_t i = 0; i < 150; i++) {
212    ASSERT_EQ(0x23, ptr[i]);
213  }
214  free(ptr);
215}
216
217TEST(malloc, calloc_realloc_larger) {
218  // Realloc to a larger size, calloc is used for the original allocation.
219  char *ptr = (char *)calloc(1, 100);
220  ASSERT_TRUE(ptr != NULL);
221  ASSERT_LE(100U, malloc_usable_size(ptr));
222
223  ptr = (char *)realloc(ptr, 200);
224  ASSERT_TRUE(ptr != NULL);
225  ASSERT_LE(200U, malloc_usable_size(ptr));
226  for (size_t i = 0; i < 100; i++) {
227    ASSERT_EQ(0, ptr[i]);
228  }
229  free(ptr);
230}
231
232TEST(malloc, calloc_realloc_smaller) {
233  // Realloc to a smaller size, calloc is used for the original allocation.
234  char *ptr = (char *)calloc(1, 200);
235  ASSERT_TRUE(ptr != NULL);
236  ASSERT_LE(200U, malloc_usable_size(ptr));
237
238  ptr = (char *)realloc(ptr, 100);
239  ASSERT_TRUE(ptr != NULL);
240  ASSERT_LE(100U, malloc_usable_size(ptr));
241  for (size_t i = 0; i < 100; i++) {
242    ASSERT_EQ(0, ptr[i]);
243  }
244  free(ptr);
245}
246
247TEST(malloc, calloc_multiple_realloc) {
248  // Multiple reallocs, calloc is used for the original allocation.
249  char *ptr = (char *)calloc(1, 200);
250  ASSERT_TRUE(ptr != NULL);
251  ASSERT_LE(200U, malloc_usable_size(ptr));
252
253  ptr = (char *)realloc(ptr, 100);
254  ASSERT_TRUE(ptr != NULL);
255  ASSERT_LE(100U, malloc_usable_size(ptr));
256  for (size_t i = 0; i < 100; i++) {
257    ASSERT_EQ(0, ptr[i]);
258  }
259
260  ptr = (char*)realloc(ptr, 50);
261  ASSERT_TRUE(ptr != NULL);
262  ASSERT_LE(50U, malloc_usable_size(ptr));
263  for (size_t i = 0; i < 50; i++) {
264    ASSERT_EQ(0, ptr[i]);
265  }
266
267  ptr = (char*)realloc(ptr, 150);
268  ASSERT_TRUE(ptr != NULL);
269  ASSERT_LE(150U, malloc_usable_size(ptr));
270  for (size_t i = 0; i < 50; i++) {
271    ASSERT_EQ(0, ptr[i]);
272  }
273  memset(ptr, 0, 150);
274
275  ptr = (char*)realloc(ptr, 425);
276  ASSERT_TRUE(ptr != NULL);
277  ASSERT_LE(425U, malloc_usable_size(ptr));
278  for (size_t i = 0; i < 150; i++) {
279    ASSERT_EQ(0, ptr[i]);
280  }
281  free(ptr);
282}
283
284TEST(malloc, realloc_overflow) {
285  errno = 0;
286  ASSERT_EQ(NULL, realloc(NULL, SIZE_MAX));
287  ASSERT_EQ(ENOMEM, errno);
288  void* ptr = malloc(100);
289  ASSERT_TRUE(ptr != NULL);
290  errno = 0;
291  ASSERT_EQ(NULL, realloc(ptr, SIZE_MAX));
292  ASSERT_EQ(ENOMEM, errno);
293  free(ptr);
294}
295
296#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
297extern "C" void* pvalloc(size_t);
298extern "C" void* valloc(size_t);
299
300TEST(malloc, pvalloc_std) {
301  size_t pagesize = sysconf(_SC_PAGESIZE);
302  void* ptr = pvalloc(100);
303  ASSERT_TRUE(ptr != NULL);
304  ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
305  ASSERT_LE(pagesize, malloc_usable_size(ptr));
306  free(ptr);
307}
308
309TEST(malloc, pvalloc_overflow) {
310  ASSERT_EQ(NULL, pvalloc(SIZE_MAX));
311}
312
313TEST(malloc, valloc_std) {
314  size_t pagesize = sysconf(_SC_PAGESIZE);
315  void* ptr = pvalloc(100);
316  ASSERT_TRUE(ptr != NULL);
317  ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0);
318  free(ptr);
319}
320
321TEST(malloc, valloc_overflow) {
322  ASSERT_EQ(NULL, valloc(SIZE_MAX));
323}
324#endif
325