3 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>
6 * Faculty of Computer Science, Mathematics and Natural Sciences,
7 * Leipzig University of Applied Sciences (HTWK Leipzig)
11 * Copyright (C) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland,
13 * Copyright (C) 2010 Daniel Borkmann <daniel@netyack.org>,
14 * Ported from SSH and added several other functions and
15 * heap consistency checks
17 * Versions of malloc and friends that check their results, and never return
18 * failure (they call fatal if they encounter an error).
20 * As far as I am concerned, the code I have written for this software
21 * can be used freely for any purpose. Any derived versions of this
22 * software must be clearly marked as such, and if the derived work is
23 * incompatible with the protocol description in the RFC file, it must be
24 * called by a name other than "ssh" or "Secure Shell".
36 #include <sys/ioctl.h>
39 # define SIZE_T_MAX ((size_t) ~0)
43 #include "cache_x86.h"
47 #include "stacktrace.h"
49 static void mcheck_abort(enum mcheck_status stat
)
51 if (stat
!= MCHECK_OK
)
52 panic("mcheck: mem inconsistency detected: %d\n", stat
);
55 static void xmalloc_mcheck_init(void)
58 * If we would use mcheck_pedantic() here, then libloudmouth
59 * is not able to perform SSL/TLS authentication. Weird.
61 int ret
= mcheck(mcheck_abort
);
63 panic("xmalloc: cannot init mcheck! bug\n");
68 static void xmalloc_init_hook(void)
70 xmalloc_mcheck_init();
73 void (*__malloc_initialize_hook
)(void) = xmalloc_init_hook
;
75 __hidden
void muntrace_handler(int signal
)
77 if (signal
!= SIGSEGV
) {
82 info("Oops, SIGSEGV received!\n");
83 info("Stacktrace:\n");
85 info("@('_')@ __.-<^*Panic!*^>\n");
91 __hidden
int xmem_used(void)
93 struct mallinfo mi
= mallinfo();
97 __hidden
int xmem_free(void)
99 struct mallinfo mi
= mallinfo();
103 __hidden
int xmem_totalarena(void)
105 struct mallinfo mi
= mallinfo();
109 __hidden
void *xmalloc(size_t size
)
112 enum mcheck_status stat
;
115 panic("xmalloc: zero size\n");
119 panic("xmalloc: out of memory (allocating %lu bytes)\n",
122 if (stat
!= MCHECK_OK
)
123 panic("xmalloc: mem inconsistency detected: %d\n", stat
);
125 debug("%p: %zu", ptr
, size
);
129 __hidden
void *xvalloc(size_t size
)
132 enum mcheck_status stat
;
135 panic("xmalloc: zero size\n");
139 panic("xvalloc: out of memory (allocating %lu bytes)\n",
142 if (stat
!= MCHECK_OK
)
143 panic("xvalloc: mem inconsistency detected: %d\n", stat
);
145 debug("%p: %zu", ptr
, size
);
149 __hidden
void *xzmalloc(size_t size
)
152 enum mcheck_status stat
;
155 panic("xzmalloc: zero size\n");
159 panic("xzmalloc: out of memory (allocating %lu bytes)\n",
162 if (stat
!= MCHECK_OK
)
163 panic("xzmalloc: mem inconsistency detected: %d\n", stat
);
164 memset(ptr
, 0, size
);
166 debug("%p: %zu", ptr
, size
);
170 __hidden
void *xmalloc_aligned(size_t size
, size_t alignment
)
174 enum mcheck_status stat
;
177 panic("xmalloc_aligned: zero size\n");
179 ret
= posix_memalign(&ptr
, alignment
, size
);
181 panic("xmalloc_aligned: out of memory (allocating %lu bytes)\n",
184 if (stat
!= MCHECK_OK
)
185 panic("xmalloc_aligned: mem inconsistency detected: %d\n", stat
);
187 debug("%p: %zu", ptr
, size
);
191 __hidden
void *xmalloc_geode_l1_cl_aligned(size_t size
)
193 return xmalloc_aligned(size
, GEODE_CACHE_LINE_SIZE
);
196 __hidden
void *xmalloc_geode_l2_cl_aligned(size_t size
)
198 return xmalloc_aligned(size
, GEODE_CACHE_LINE_SIZE
);
201 __hidden
void *xmallocz(size_t size
)
206 panic("xmallocz: data too large to fit into virtual "
209 ptr
= xmalloc(size
+ 1);
210 ((char*) ptr
)[size
] = 0;
215 __hidden
void *xmemdupz(const void *data
, size_t len
)
217 return memcpy(xmallocz(len
), data
, len
);
220 __hidden
void *xcalloc(size_t nmemb
, size_t size
)
223 enum mcheck_status stat
;
225 if (size
== 0 || nmemb
== 0)
226 panic("xcalloc: zero size\n");
227 if (SIZE_T_MAX
/ nmemb
< size
)
228 panic("xcalloc: nmemb * size > SIZE_T_MAX\n");
230 ptr
= calloc(nmemb
, size
);
232 panic("xcalloc: out of memory (allocating %lu bytes)\n",
233 (u_long
) (size
* nmemb
));
235 if (stat
!= MCHECK_OK
)
236 panic("xcalloc: mem inconsistency detected: %d\n", stat
);
238 debug("%p: %zu", ptr
, size
);
242 __hidden
void *xrealloc(void *ptr
, size_t nmemb
, size_t size
)
245 size_t new_size
= nmemb
* size
;
246 enum mcheck_status stat
;
249 panic("xrealloc: zero size\n");
250 if (SIZE_T_MAX
/ nmemb
< size
)
251 panic("xrealloc: nmemb * size > SIZE_T_MAX\n");
254 new_ptr
= malloc(new_size
);
256 new_ptr
= realloc(ptr
, new_size
);
259 panic("xrealloc: out of memory (new_size %lu bytes)\n",
262 if (stat
!= MCHECK_OK
)
263 panic("xrealloc: mem inconsistency detected: %d\n", stat
);
265 debug("%p: %zu => %p: %zu", ptr
, size
, new_ptr
, new_size
);
269 __hidden
void xfree(void *ptr
)
271 enum mcheck_status stat
;
274 panic("xfree: NULL pointer given as argument\n");
277 if (stat
!= MCHECK_OK
)
278 panic("xfree: mem inconsistency detected: %d\n", stat
);
280 debug("%p => 0", ptr
);
284 __hidden
char *xstrdup(const char *str
)
289 len
= strlen(str
) + 1;
291 strlcpy(cp
, str
, len
);
296 __hidden
char *xstrndup(const char *str
, size_t size
)
301 len
= strlen(str
) + 1;
306 strlcpy(cp
, str
, len
);
311 __hidden
int xdup(int fd
)
315 panic("xdup: dup failed\n");
320 int __xioctl(int fd
, int req
, void *arg
)
324 do ret
= ioctl(fd
, req
, arg
);
325 while (ret
< 0 && EINTR
== errno
);