/[imapfilter]/imapfilter/memory.c
ViewVC logotype

Contents of /imapfilter/memory.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (show annotations)
Sat Mar 29 14:04:10 2003 UTC (21 years ago) by lefcha
Branch: MAIN
Changes since 1.13: +8 -4 lines
File MIME type: text/plain
Correct bug concerning secmem clearing/freeing.

1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <sys/types.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <sys/mman.h>
7 #include <sys/time.h>
8 #include <sys/resource.h>
9
10
11 #include "config.h"
12 #include "imapfilter.h"
13
14
15 extern unsigned int options;
16
17 #ifdef MEMORY_LOCK
18 extern uid_t ruid, euid;
19
20 #endif
21
22 static secmem_t *smem = NULL; /* First node of secure memory linked list. */
23
24
25 /*
26 * A malloc() that checks the results and dies in case of error.
27 */
28 void *
29 xmalloc(size_t size)
30 {
31 void *ptr;
32
33 ptr = (void *)malloc(size);
34
35 if (ptr == NULL)
36 fatal(ERROR_MEMORY_ALLOCATION,
37 "allocating memory; %s\n", strerror(errno));
38
39 return ptr;
40 }
41
42
43 /*
44 * A realloc() that checks the results and dies in case of error.
45 */
46 void *
47 xrealloc(void *ptr, size_t size)
48 {
49 ptr = (void *)realloc(ptr, size);
50
51 if (ptr == NULL)
52 fatal(ERROR_MEMORY_ALLOCATION,
53 "allocating memory; %s\n", strerror(errno));
54
55 return ptr;
56 }
57
58
59 /*
60 * A free() that dies if fed with NULL pointer.
61 */
62 void
63 xfree(void *ptr)
64 {
65 if (ptr == NULL)
66 fatal(ERROR_MEMORY_ALLOCATION,
67 "NULL pointer given as argument");
68 free(ptr);
69 }
70
71
72 /*
73 * A strdup() that checks the results and dies in case of error.
74 */
75 char *
76 xstrdup(const char *s)
77 {
78 char *cp;
79
80 cp = strdup(s);
81
82 if (cp == NULL)
83 fatal(ERROR_MEMORY_ALLOCATION,
84 "allocating memory; %s\n", strerror(errno));
85
86 return cp;
87 }
88
89
90 /*
91 * Secure memory malloc(). Locks memory and keeps information about the
92 * chunk that was allocated.
93 */
94 void *
95 smalloc(size_t size)
96 {
97 #ifdef MEMORY_LOCK
98 int r;
99 static int w = 0;
100
101 #endif
102 void *ptr;
103 secmem_t *node;
104
105 ptr = xmalloc(size);
106
107 #ifdef MEMORY_LOCK
108 seteuid(euid); /* Gain root privileges. */
109 r = mlock(ptr, size);
110 seteuid(ruid); /* Drop root privileges. */
111
112 if (getuid() != geteuid())
113 fatal(ERROR_SETUID, "failed to drop privileges\n");
114
115
116 if (options & OPTION_WARNING && r == -1 && !w) {
117 error("warning: using insecure memory\n");
118 w = 1;
119 }
120 #endif
121 node = (secmem_t *) xmalloc(sizeof(secmem_t));
122
123 node->buf = ptr;
124 node->size = size;
125 node->prev = node->next = NULL;
126
127 secmem_append(node);
128
129 return ptr;
130 }
131
132
133 /*
134 * Secure memory realloc(). Resize memory by allocating a new memory chunk
135 * and NULL fill old memory, in order to protect sensitive data.
136 */
137 void *
138 srealloc(void *ptr, size_t size)
139 {
140 void *p;
141 secmem_t *node;
142
143 if (!(node = (secmem_t *) secmem_find(ptr))) {
144 ptr = xrealloc(ptr, size);
145 return ptr;
146 }
147 p = smalloc(size);
148 memcpy(p, node->buf, min(node->size, size));
149
150 memset(node->buf, 0, node->size);
151 secmem_remove(node);
152 xfree(node->buf);
153 xfree(node);
154
155 return p;
156 }
157
158
159 /*
160 * Secure memory free(). NULL fill memory before freeing it.
161 */
162 void
163 sfree(void *ptr)
164 {
165 secmem_t *node;
166
167 if (!(node = (secmem_t *) secmem_find(ptr))) {
168 xfree(ptr);
169 return;
170 }
171 memset(node->buf, 0, node->size);
172 secmem_remove(node);
173 xfree(node->buf);
174 xfree(node);
175 }
176
177
178 /*
179 * Secure memory strdup(). Uses secure memory allocation.
180 */
181 char *
182 sstrdup(const char *s)
183 {
184 char *p;
185
186 p = (char *)smalloc(strlen(s) + 1);
187 xstrncpy(p, s, strlen(s));
188
189 return p;
190 }
191
192
193 /*
194 * Append information about the newly allocated memory buffer.
195 */
196 void
197 secmem_append(secmem_t * node)
198 {
199 secmem_t *pos;
200 secmem_t **app;
201
202 app = &smem;
203 pos = smem;
204
205 while (pos) {
206 node->prev = pos;
207 app = &(pos->next);
208 pos = pos->next;
209 }
210
211 *app = node;
212 }
213
214
215 /*
216 * Find the record of a memory buffer in the secure memory linked list.
217 */
218 secmem_t *
219 secmem_find(void *ptr)
220 {
221 secmem_t *pos;
222
223 pos = smem;
224
225 while (pos != NULL && pos->buf != ptr)
226 pos = pos->next;
227
228 return pos;
229 }
230
231
232 /*
233 * Remove a record of a secure memory buffer.
234 */
235 void
236 secmem_remove(secmem_t * node)
237 {
238 if (node->prev != NULL)
239 node->prev->next = node->next;
240 if (node->next != NULL)
241 node->next->prev = node->prev;
242 if (smem == node)
243 smem = node->next;
244
245 }
246
247
248 /*
249 * Overwrite/clear all secure memory.
250 */
251 void
252 secmem_clear(void)
253 {
254 secmem_t *p, *t;
255
256 for (p = smem; p != NULL; p = t) {
257 t = p->next;
258 sfree(p->buf);
259 }
260 }
261
262
263 #ifdef MEMORY_LOCK
264 /*
265 * Lock memory of allocated buffers.
266 */
267 void
268 secmem_lock(void)
269 {
270 secmem_t *p;
271
272 seteuid(euid); /* Gain root privileges. */
273 for (p = smem; p != NULL; p = p->next)
274 mlock(p->buf, p->size);
275 seteuid(ruid); /* Drop root privileges. */
276
277 if (getuid() != geteuid())
278 fatal(ERROR_SETUID, "failed to drop privileges\n");
279 }
280
281 #endif
282
283
284 /*
285 * Disable core file dumping.
286 */
287 void
288 corefile_disable(void)
289 {
290 struct rlimit rl;
291
292 getrlimit(RLIMIT_CORE, &rl);
293
294 rl.rlim_cur = rl.rlim_max = 0;
295 setrlimit(RLIMIT_CORE, &rl);
296 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26