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

Contents of /imapfilter/memory.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (show annotations)
Sat Feb 22 16:06:41 2003 UTC (21 years, 2 months ago) by lefcha
Branch: MAIN
Changes since 1.12: +134 -117 lines
File MIME type: text/plain
Coding style to KNF and some code cleanup.

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
173 secmem_remove(node);
174 xfree(node->buf);
175 xfree(node);
176 }
177
178
179 /*
180 * Secure memory strdup(). Uses secure memory allocation.
181 */
182 char *
183 sstrdup(const char *s)
184 {
185 char *p;
186
187 p = (char *)smalloc(strlen(s) + 1);
188 xstrncpy(p, s, strlen(s));
189
190 return p;
191 }
192
193
194 /*
195 * Append information about the newly allocated memory buffer.
196 */
197 void
198 secmem_append(secmem_t * node)
199 {
200 secmem_t *pos;
201 secmem_t **app;
202
203 app = &smem;
204 pos = smem;
205
206 while (pos) {
207 node->prev = pos;
208 app = &(pos->next);
209 pos = pos->next;
210 }
211
212 *app = node;
213 }
214
215
216 /*
217 * Find the record of a memory buffer in the secure memory linked list.
218 */
219 secmem_t *
220 secmem_find(void *ptr)
221 {
222 secmem_t *pos;
223
224 pos = smem;
225
226 while (pos != NULL && pos->buf != ptr)
227 pos = pos->next;
228
229 return pos;
230 }
231
232
233 /*
234 * Remove a record of a secure memory buffer.
235 */
236 void
237 secmem_remove(secmem_t * node)
238 {
239 if (node->prev != NULL)
240 node->prev->next = node->next;
241 if (node->next != NULL)
242 node->next->prev = node->prev;
243 }
244
245
246 /*
247 * Overwrite/clear all secure memory.
248 */
249 void
250 secmem_clear(void)
251 {
252 secmem_t *p;
253
254 for (p = smem; p != NULL; p = p->next)
255 sfree(p);
256 }
257
258
259 #ifdef MEMORY_LOCK
260 /*
261 * Lock memory of allocated buffers.
262 */
263 void
264 secmem_lock(void)
265 {
266 secmem_t *p;
267
268 seteuid(euid); /* Gain root privileges. */
269 for (p = smem; p != NULL; p = p->next)
270 mlock(p->buf, p->size);
271 seteuid(ruid); /* Drop root privileges. */
272
273 if (getuid() != geteuid())
274 fatal(ERROR_SETUID, "failed to drop privileges\n");
275 }
276
277 #endif
278
279
280 /*
281 * Disable core file dumping.
282 */
283 void
284 corefile_disable(void)
285 {
286 struct rlimit rl;
287
288 getrlimit(RLIMIT_CORE, &rl);
289
290 rl.rlim_cur = rl.rlim_max = 0;
291 setrlimit(RLIMIT_CORE, &rl);
292 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26