2 * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/types.h>
39 struct safe_mem_hdr
*prev
;
40 struct safe_mem_hdr
*next
;
41 struct safe_mem_tail
*tail
;
45 char sig
[8]; /* SAFEMEM */
48 struct safe_mem_tail
{
49 char sig
[8]; /* SAFEMEM */
52 static struct safe_mem_hdr
*safe_mem_hdr_first
= NULL
;
55 _alloc_safe_mem(size_t req_sz
, const char *file
, int line
)
57 struct safe_mem_hdr
*hdr
, *hdrp
;
58 struct safe_mem_tail
*tail
;
62 alloc_sz
= req_sz
+ sizeof(*hdr
) + sizeof(*tail
);
63 if ((mem
= malloc(alloc_sz
)) == NULL
)
66 if (mlock(mem
, alloc_sz
) < 0) {
71 memset(mem
, 0, alloc_sz
);
73 hdr
= (struct safe_mem_hdr
*)mem
;
74 tail
= (struct safe_mem_tail
*)(mem
+ alloc_sz
- sizeof(*tail
));
75 user_mem
= mem
+ sizeof(*hdr
);
77 strcpy(hdr
->sig
, "SAFEMEM");
78 strcpy(tail
->sig
, "SAFEMEM");
80 hdr
->alloc_sz
= alloc_sz
;
85 if (safe_mem_hdr_first
== NULL
) {
86 safe_mem_hdr_first
= hdr
;
88 hdrp
= safe_mem_hdr_first
;
89 while (hdrp
->next
!= NULL
)
99 _free_safe_mem(void *mem_ptr
, const char *file
, int line
)
101 struct safe_mem_hdr
*hdr
;
102 struct safe_mem_tail
*tail
;
107 hdr
= (struct safe_mem_hdr
*)mem
;
108 tail
= (struct safe_mem_tail
*)(mem
+ hdr
->alloc_sz
- sizeof(*tail
));
111 fprintf(stderr
, "freeing safe_mem (hdr): %#lx (%s:%d)\n",
112 (unsigned long)(void *)hdr
, hdr
->file
, hdr
->line
);
115 if (hdr
->alloc_sz
== 0) {
116 fprintf(stderr
, "BUG: double-free at %s:%d !!!\n", file
, line
);
120 /* Integrity checks */
121 if ((memcmp(hdr
->sig
, "SAFEMEM\0", 8) != 0) ||
122 (memcmp(tail
->sig
, "SAFEMEM\0", 8) != 0)) {
123 fprintf(stderr
, "BUG: safe_mem buffer under- or overflow at "
124 "%s:%d !!!\n", file
, line
);
128 if (safe_mem_hdr_first
== NULL
) {
129 fprintf(stderr
, "BUG: safe_mem list should not be empty at "
130 "%s:%d !!!\n", file
, line
);
134 if (hdr
->prev
!= NULL
)
135 hdr
->prev
->next
= hdr
->next
;
136 if (hdr
->next
!= NULL
)
137 hdr
->next
->prev
= hdr
->prev
;
138 if (safe_mem_hdr_first
== hdr
)
139 safe_mem_hdr_first
= hdr
->next
;
141 alloc_sz
= hdr
->alloc_sz
;
142 memset(mem
, 0xFF, alloc_sz
);
143 memset(mem
, 0, alloc_sz
);
149 _strdup_safe_mem(const char *in
, const char *file
, int line
)
156 if ((out
= _alloc_safe_mem(sz
, file
, line
)) == NULL
) {
167 check_and_purge_safe_mem(void)
169 struct safe_mem_hdr
*hdr
;
175 if (safe_mem_hdr_first
== NULL
)
178 hdr
= safe_mem_hdr_first
;
179 while ((hdr
= safe_mem_hdr_first
) != NULL
) {
181 if ((hdr
->alloc_sz
> 0) &&
182 (memcmp(hdr
->sig
, "SAFEMEM\0", 8) == 0) &&
183 (memcmp(hdr
->tail
->sig
, "SAFEMEM\0", 8) == 0))
188 fprintf(stderr
, "un-freed safe_mem: %#lx (%s:%d) [integrity=%s]\n",
189 (unsigned long)(void *)hdr
, hdr
->file
, hdr
->line
,
190 ok
? "ok" : "failed");
194 _free_safe_mem(mem
, "check_and_purge_safe_mem", 0);