GNUnet 0.26.2-106-g126384b46
 
Loading...
Searching...
No Matches
common_allocation.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001, 2002, 2003, 2005, 2006, 2024 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#if HAVE_MALLOC_H
30#include <malloc.h>
31#endif
32#if HAVE_MALLOC_MALLOC_H
33#include <malloc/malloc.h>
34#endif
35
36#define LOG(kind, ...) \
37 GNUNET_log_from (kind, "util-common-allocation", __VA_ARGS__)
38
39#define LOG_STRERROR(kind, syscall) \
40 GNUNET_log_from_strerror (kind, "util-common-allocation", syscall)
41
42#ifndef INT_MAX
43#define INT_MAX 0x7FFFFFFF
44#endif
45
46
47void *
49 const char *filename,
50 int linenumber)
51{
52 void *ret;
53
54 /* As a security precaution, we generally do not allow very large
55 * allocations using the default 'GNUNET_malloc()' macro */
58 linenumber);
61 linenumber);
62 if (NULL == ret)
63 {
65 "malloc");
66 GNUNET_assert (0);
67 }
68 return ret;
69}
70
71
72void *
73GNUNET_xmemdup_ (const void *buf,
74 size_t size,
75 const char *filename,
76 int linenumber)
77{
78 void *ret;
79
80 /* As a security precaution, we generally do not allow very large
81 * allocations here */
84 linenumber);
87 linenumber);
88 ret = malloc (size);
89 if (NULL == ret)
90 {
92 "malloc");
93 GNUNET_assert (0);
94 }
96 buf,
97 size);
98 return ret;
99}
100
101
102void *
104 const char *filename,
105 int linenumber)
106{
107 void *result;
108
109 (void) filename;
110 (void) linenumber;
111 result = malloc (size);
112 if (NULL == result)
113 return NULL;
114 memset (result,
115 0,
116 size);
117 return result;
118}
119
120
121void *
123 size_t n,
124 const char *filename,
125 int linenumber)
126{
127 (void) filename;
128 (void) linenumber;
129
130#if defined(M_SIZE)
131#if ENABLE_POISONING
132 {
133 uint64_t *base = ptr;
134 size_t s = M_SIZE (ptr);
135
136 if (s > n)
137 {
138 const uint64_t baadfood = GNUNET_ntohll (0xBAADF00DBAADF00DLL);
139 char *cbase = ptr;
140
141 GNUNET_memcpy (&cbase[n],
142 &baadfood,
143 GNUNET_MIN (8 - (n % 8),
144 s - n));
145 for (size_t i = 1 + (n + 7) / 8; i < s / 8; i++)
146 base[i] = baadfood;
147 GNUNET_memcpy (&base[s / 8],
148 &baadfood,
149 s % 8);
150 }
151 }
152#endif
153#endif
154 ptr = realloc (ptr, n);
155 if ((NULL == ptr) && (n > 0))
156 {
158 "realloc");
159 GNUNET_assert (0);
160 }
161 return ptr;
162}
163
164
165#if __BYTE_ORDER == __LITTLE_ENDIAN
166#define BAADFOOD_STR "\x0D\xF0\xAD\xBA"
167#endif
168#if __BYTE_ORDER == __BIG_ENDIAN
169#define BAADFOOD_STR "\xBA\xAD\xF0\x0D"
170#endif
171
172#if HAVE_MALLOC_NP_H
173#include <malloc_np.h>
174#endif
175#if HAVE_MALLOC_USABLE_SIZE
176#define M_SIZE(p) malloc_usable_size (p)
177#elif HAVE_MALLOC_SIZE
178#define M_SIZE(p) malloc_size (p)
179#endif
180
181void
182GNUNET_xfree_ (void *ptr,
183 const char *filename,
184 int linenumber)
185{
186 if (NULL == ptr)
187 return;
188#if defined(M_SIZE)
189#if ENABLE_POISONING
190 {
191 const uint64_t baadfood = GNUNET_ntohll (0xBAADF00DBAADF00DLL);
192 uint64_t *base = ptr;
193 size_t s = M_SIZE (ptr);
194
195 for (size_t i = 0; i < s / 8; i++)
196 base[i] = baadfood;
197 GNUNET_memcpy (&base[s / 8], &baadfood, s % 8);
198 }
199#endif
200#endif
201 free (ptr);
202}
203
204
205char *
206GNUNET_xstrdup_ (const char *str,
207 const char *filename,
208 int linenumber)
209{
210 size_t slen;
211 char *res;
212
213 GNUNET_assert_at (str != NULL,
214 filename,
215 linenumber);
216 slen = strlen (str) + 1;
217 res = GNUNET_xmalloc_ (slen,
218 filename,
219 linenumber);
221 str,
222 slen);
223 return res;
224}
225
226
227#if ! HAVE_STRNLEN
228static size_t
229strnlen (const char *s,
230 size_t n)
231{
232 const char *e;
233
234 e = memchr (s,
235 '\0',
236 n);
237 if (NULL == e)
238 return n;
239 return e - s;
240}
241
242
243#endif
244
245
246char *
248 size_t len,
249 const char *filename,
250 int linenumber)
251{
252 char *res;
253
254 if (0 == len)
255 return GNUNET_strdup ("");
256 GNUNET_assert_at (NULL != str,
257 filename,
258 linenumber);
259 len = strnlen (str, len);
260 res = GNUNET_xmalloc_ (len + 1,
261 filename,
262 linenumber);
263 GNUNET_memcpy (res, str, len);
264 /* res[len] = '\0'; 'malloc' zeros out anyway */
265 return res;
266}
267
268
269void
270GNUNET_xgrow_ (void **old,
271 size_t elementSize,
272 unsigned int *oldCount,
273 unsigned int newCount,
274 const char *filename,
275 int linenumber)
276{
277 void *tmp;
278 size_t size;
279
280 GNUNET_assert_at (elementSize > 0, filename, linenumber);
281 GNUNET_assert_at (INT_MAX / elementSize > newCount, filename, linenumber);
282 size = newCount * elementSize;
283 if (0 == size)
284 {
285 tmp = NULL;
286 }
287 else
288 {
289 tmp = GNUNET_xmalloc_ (size,
290 filename,
291 linenumber);
292 if (NULL != *old)
293 {
294 GNUNET_memcpy (tmp,
295 *old,
296 elementSize * GNUNET_MIN (*oldCount,
297 newCount));
298 }
299 }
300
301 if (NULL != *old)
302 {
303 GNUNET_xfree_ (*old,
304 filename,
305 linenumber);
306 }
307 *old = tmp;
308 *oldCount = newCount;
309}
310
311
312int
313GNUNET_asprintf (char **buf,
314 const char *format,
315 ...)
316{
317 int ret;
318 va_list args;
319
320 va_start (args,
321 format);
322 ret = vsnprintf (NULL,
323 0,
324 format,
325 args);
326 va_end (args);
327 GNUNET_assert (ret >= 0);
328 *buf = GNUNET_malloc (ret + 1);
329 va_start (args, format);
330 ret = vsnprintf (*buf,
331 ret + 1,
332 format,
333 args);
334 va_end (args);
335 return ret;
336}
337
338
339int
341 size_t size,
342 const char *format,
343 ...)
344{
345 int ret;
346 va_list args;
347
348 va_start (args,
349 format);
350 ret = vsnprintf (buf,
351 size,
352 format,
353 args);
354 va_end (args);
355 GNUNET_assert ((ret >= 0) && (((size_t) ret) < size));
356 return ret;
357}
358
359
362{
364 uint16_t msize;
365
366 msize = ntohs (msg->size);
367 GNUNET_assert (msize >= sizeof(struct GNUNET_MessageHeader));
368 ret = GNUNET_malloc (msize);
369 GNUNET_memcpy (ret, msg, msize);
370 return ret;
371}
372
373
374bool
375GNUNET_is_zero_ (const void *a,
376 size_t n)
377{
378 const char *b = a;
379
380 for (size_t i = 0; i < n; i++)
381 if (b[i])
382 return false;
383 return true;
384}
385
386
387/* end of common_allocation.c */
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static size_t strnlen(const char *s, size_t n)
#define INT_MAX
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
int GNUNET_asprintf(char **buf, const char *format,...)
#define LOG_STRERROR(kind, syscall)
static int ret
Final status code.
Definition gnunet-arm.c:93
static char * filename
static char * res
Currently read line or NULL on EOF.
static int result
Global testing status.
char * GNUNET_xstrndup_(const char *str, size_t len, const char *filename, int linenumber)
Dup partially a string.
void GNUNET_xgrow_(void **old, size_t elementSize, unsigned int *oldCount, unsigned int newCount, const char *filename, int linenumber)
Grow an array, the new elements are zeroed out.
char * GNUNET_xstrdup_(const char *str, const char *filename, int linenumber)
Dup a string.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
void * GNUNET_xmalloc_unchecked_(size_t size, const char *filename, int linenumber)
Allocate memory.
void GNUNET_xfree_(void *ptr, const char *filename, int linenumber)
Free memory.
void * GNUNET_xrealloc_(void *ptr, size_t n, const char *filename, int linenumber)
Reallocate memory.
void * GNUNET_xmalloc_(size_t size, const char *filename, int linenumber)
Allocate memory.
bool GNUNET_is_zero_(const void *a, size_t n)
Check that memory in a is all zeros.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void * GNUNET_xmemdup_(const void *buf, size_t size, const char *filename, int linenumber)
Allocate and initialize memory.
#define GNUNET_MIN(a, b)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_assert_at(cond, f, l)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_MAX_MALLOC_CHECKED
Maximum allocation with GNUNET_malloc macro.
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.
#define GNUNET_malloc(size)
Wrapper around malloc.
static unsigned int size
Size of the "table".
Definition peer.c:68
Header for all communications.
const char * str
Definition time.c:1252