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

Contents of /imapfilter/memory.c

Parent Directory Parent Directory | Revision Log Revision Log


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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26