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

Annotation of /imapfilter/memory.c

Parent Directory Parent Directory | Revision Log Revision Log


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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26