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

Diff of /imapfilter/memory.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.1.11.2.2  
changed lines
  Added in v.1.22

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26