3 * By Daniel Borkmann <daniel@netyack.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
9 * Copyright (C) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland,
11 * Copyright (C) 2010 Daniel Borkmann <daniel@netyack.org>,
12 * Ported from SSH and added several other functions and
13 * heap consistency checks
15 * Versions of malloc and friends that check their results, and never return
16 * failure (they call fatal if they encounter an error).
18 * As far as I am concerned, the code I have written for this software
19 * can be used freely for any purpose. Any derived versions of this
20 * software must be clearly marked as such, and if the derived work is
21 * incompatible with the protocol description in the RFC file, it must be
22 * called by a name other than "ssh" or "Secure Shell".
36 # define SIZE_T_MAX ((size_t) ~0)
43 #include "error_and_die.h"
45 __hidden
void mcheck_abort(enum mcheck_status stat
)
47 if (stat
!= MCHECK_OK
)
48 error_and_die(EXIT_FAILURE
, "mcheck: mem inconsistency "
49 "detected: %d\n", stat
);
52 static void xmalloc_mcheck_init(void)
55 * If we would use mcheck_pedantic() here, then libloudmouth
56 * is not able to perform SSL/TLS authentication. Weird.
58 int ret
= mcheck(mcheck_abort
);
60 error_and_die(EXIT_FAILURE
, "xmalloc: cannot init "
65 static void xmalloc_init_hook(void)
67 xmalloc_mcheck_init();
70 void (*__malloc_initialize_hook
)(void) = xmalloc_init_hook
;
72 __hidden
void muntrace_handler(int signal
)
78 __hidden
int xmem_used(void)
80 struct mallinfo mi
= mallinfo();
84 __hidden
int xmem_free(void)
86 struct mallinfo mi
= mallinfo();
90 __hidden
int xmem_totalarena(void)
92 struct mallinfo mi
= mallinfo();
96 __hidden
void *xmalloc(size_t size
)
99 enum mcheck_status stat
;
102 error_and_die(EXIT_FAILURE
, "xmalloc: zero size\n");
106 error_and_die(EXIT_FAILURE
, "xmalloc: out of memory "
107 "(allocating %lu bytes)\n", (u_long
) size
);
109 if (stat
!= MCHECK_OK
)
110 error_and_die(EXIT_FAILURE
, "xmalloc: mem inconsistency "
111 "detected: %d\n", stat
);
113 debug_blue("%p: %zu", ptr
, size
);
117 __hidden
void *xalloca(size_t size
)
122 error_and_die(EXIT_FAILURE
, "xalloca: zero size\n");
126 error_and_die(EXIT_FAILURE
, "xalloca: out of memory "
127 "(allocating %lu bytes on stack)\n",
130 debug_blue("%p: %zu (stack)", ptr
, size
);
134 __hidden
void *xvalloc(size_t size
)
137 enum mcheck_status stat
;
140 error_and_die(EXIT_FAILURE
, "xmalloc: zero size\n");
144 error_and_die(EXIT_FAILURE
, "xvalloc: out of memory "
145 "(allocating %lu bytes)\n", (u_long
) size
);
147 if (stat
!= MCHECK_OK
)
148 error_and_die(EXIT_FAILURE
, "xvalloc: mem inconsistency "
149 "detected: %d\n", stat
);
151 debug_blue("%p: %zu", ptr
, size
);
155 __hidden
void *xzmalloc(size_t size
)
158 enum mcheck_status stat
;
161 error_and_die(EXIT_FAILURE
, "xzmalloc: zero size\n");
165 error_and_die(EXIT_FAILURE
, "xzmalloc: out of memory "
166 "(allocating %lu bytes)\n", (u_long
) size
);
168 if (stat
!= MCHECK_OK
)
169 error_and_die(EXIT_FAILURE
, "xzmalloc: mem inconsistency "
170 "detected: %d\n", stat
);
172 memset(ptr
, 0, size
);
174 debug_blue("%p: %zu", ptr
, size
);
178 __hidden
void *xmalloc_aligned(size_t size
, size_t alignment
)
182 enum mcheck_status stat
;
185 error_and_die(EXIT_FAILURE
, "xmalloc_aligned: zero size\n");
187 ret
= posix_memalign(&ptr
, alignment
, size
);
189 error_and_die(EXIT_FAILURE
, "xmalloc_aligned: out of memory "
190 "(allocating %lu bytes)\n", (u_long
) size
);
192 if (stat
!= MCHECK_OK
)
193 error_and_die(EXIT_FAILURE
, "xmalloc_aligned: mem "
194 "inconsistency detected: %d\n", stat
);
196 debug_blue("%p: %zu", ptr
, size
);
200 __hidden
void *xmallocz(size_t size
)
205 error_and_die(EXIT_FAILURE
, "xmallocz: data too large to fit "
206 "into virtual memory space\n");
208 ptr
= xmalloc(size
+ 1);
209 ((char*) ptr
)[size
] = 0;
214 __hidden
void *xmemdupz(const void *data
, size_t len
)
216 return memcpy(xmallocz(len
), data
, len
);
219 __hidden
void *xcalloc(size_t nmemb
, size_t size
)
222 enum mcheck_status stat
;
224 if (size
== 0 || nmemb
== 0)
225 error_and_die(EXIT_FAILURE
, "xcalloc: zero size\n");
226 if (SIZE_T_MAX
/ nmemb
< size
)
227 error_and_die(EXIT_FAILURE
, "xcalloc: nmemb * size > "
230 ptr
= calloc(nmemb
, size
);
232 error_and_die(EXIT_FAILURE
, "xcalloc: out of memory "
233 "(allocating %lu bytes)\n",
234 (u_long
) (size
* nmemb
));
236 if (stat
!= MCHECK_OK
)
237 error_and_die(EXIT_FAILURE
, "xcalloc: mem inconsistency "
238 "detected: %d\n", stat
);
240 debug_blue("%p: %zu", ptr
, size
);
244 __hidden
void *xrealloc(void *ptr
, size_t nmemb
, size_t size
)
247 size_t new_size
= nmemb
* size
;
248 enum mcheck_status stat
;
251 error_and_die(EXIT_FAILURE
, "xrealloc: zero size\n");
252 if (SIZE_T_MAX
/ nmemb
< size
)
253 error_and_die(EXIT_FAILURE
, "xrealloc: nmemb * size > "
257 new_ptr
= malloc(new_size
);
259 new_ptr
= realloc(ptr
, new_size
);
262 error_and_die(EXIT_FAILURE
, "xrealloc: out of memory "
263 "(new_size %lu bytes)\n", (u_long
) new_size
);
265 if (stat
!= MCHECK_OK
)
266 error_and_die(EXIT_FAILURE
, "xrealloc: mem inconsistency "
267 "detected: %d\n", stat
);
269 debug_blue("%p: %zu => %p: %zu", ptr
, size
, new_ptr
, new_size
);
273 __hidden
void xfree(void *ptr
)
275 enum mcheck_status stat
;
278 error_and_die(EXIT_FAILURE
, "xfree: NULL pointer given as "
282 if (stat
!= MCHECK_OK
)
283 error_and_die(EXIT_FAILURE
, "xfree: mem inconsistency "
284 "detected: %d\n", stat
);
286 debug_blue("%p => 0", ptr
);
291 __hidden
char *xstrdup(const char *str
)
296 len
= strlen(str
) + 1;
298 strlcpy(cp
, str
, len
);
303 __hidden
char *xstrndup(const char *str
, size_t size
)
308 len
= strlen(str
) + 1;
313 strlcpy(cp
, str
, len
);
318 __hidden
int xdup(int fd
)
322 error_and_die(EXIT_FAILURE
, "xdup: dup failed\n");