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
29 #include <sys/types.h>
38 struct safe_mem_hdr
*prev
;
39 struct safe_mem_hdr
*next
;
40 struct safe_mem_tail
*tail
;
44 char sig
[8]; /* SAFEMEM */
47 struct safe_mem_tail
{
48 char sig
[8]; /* SAFEMEM */
51 static struct safe_mem_hdr
*safe_mem_hdr_first
= NULL
;
53 #pragma weak _alloc_safe_mem
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
)
98 #pragma weak _free_safe_mem
100 _free_safe_mem(void *mem_ptr
, const char *file
, int line
)
102 struct safe_mem_hdr
*hdr
;
103 struct safe_mem_tail
*tail
;
108 hdr
= (struct safe_mem_hdr
*)mem
;
109 tail
= (struct safe_mem_tail
*)(mem
+ hdr
->alloc_sz
- sizeof(*tail
));
112 fprintf(stderr
, "freeing safe_mem (hdr): %#lx (%s:%d)\n",
113 (unsigned long)(void *)hdr
, hdr
->file
, hdr
->line
);
116 if (hdr
->alloc_sz
== 0) {
117 fprintf(stderr
, "BUG: double-free at %s:%d !!!\n", file
, line
);
121 /* Integrity checks */
122 if ((memcmp(hdr
->sig
, "SAFEMEM\0", 8) != 0) ||
123 (memcmp(tail
->sig
, "SAFEMEM\0", 8) != 0)) {
124 fprintf(stderr
, "BUG: safe_mem buffer under- or overflow at "
125 "%s:%d !!!\n", file
, line
);
129 if (safe_mem_hdr_first
== NULL
) {
130 fprintf(stderr
, "BUG: safe_mem list should not be empty at "
131 "%s:%d !!!\n", file
, line
);
135 if (hdr
->prev
!= NULL
)
136 hdr
->prev
->next
= hdr
->next
;
137 if (hdr
->next
!= NULL
)
138 hdr
->next
->prev
= hdr
->prev
;
139 if (safe_mem_hdr_first
== hdr
)
140 safe_mem_hdr_first
= hdr
->next
;
142 alloc_sz
= hdr
->alloc_sz
;
143 memset(mem
, 0xFF, alloc_sz
);
144 memset(mem
, 0, alloc_sz
);
149 #pragma weak check_and_purge_safe_mem
151 check_and_purge_safe_mem(void)
153 struct safe_mem_hdr
*hdr
;
159 if (safe_mem_hdr_first
== NULL
)
162 hdr
= safe_mem_hdr_first
;
163 while ((hdr
= safe_mem_hdr_first
) != NULL
) {
165 if ((hdr
->alloc_sz
> 0) &&
166 (memcmp(hdr
->sig
, "SAFEMEM\0", 8) == 0) &&
167 (memcmp(hdr
->tail
->sig
, "SAFEMEM\0", 8) == 0))
172 fprintf(stderr
, "un-freed safe_mem: %#lx (%s:%d) [integrity=%s]\n",
173 (unsigned long)(void *)hdr
, hdr
->file
, hdr
->line
,
174 ok
? "ok" : "failed");
178 _free_safe_mem(mem
, "check_and_purge_safe_mem", 0);