Fix pthread locking and remove defunctional support for static lock init.
[libgcrypt.git] / src / secmem.c
1 /* secmem.c  -  memory allocation from a secure heap
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3  *               2003, 2007 Free Software Foundation, Inc.
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser general Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <stdarg.h>
27 #include <unistd.h>
28 #include <stddef.h>
29
30 #if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
31 #include <sys/mman.h>
32 #include <sys/types.h>
33 #include <fcntl.h>
34 #ifdef USE_CAPABILITIES
35 #include <sys/capability.h>
36 #endif
37 #endif
38
39 #include "ath.h"
40 #include "g10lib.h"
41 #include "secmem.h"
42
43 #if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS)
44 #define MAP_ANONYMOUS MAP_ANON
45 #endif
46
47 #define MINIMUM_POOL_SIZE 16384
48 #define STANDARD_POOL_SIZE 32768
49 #define DEFAULT_PAGE_SIZE 4096
50
51 typedef struct memblock
52 {
53   unsigned size;                /* Size of the memory available to the
54                                    user.  */
55   int flags;                    /* See below.  */
56   PROPERLY_ALIGNED_TYPE aligned;
57 } memblock_t;
58
59 /* This flag specifies that the memory block is in use.  */
60 #define MB_FLAG_ACTIVE (1 << 0)
61
62 /* The pool of secure memory.  */
63 static void *pool;
64
65 /* Size of POOL in bytes.  */
66 static size_t pool_size;
67
68 /* True, if the memory pool is ready for use.  May be checked in an
69    atexit function.  */
70 static volatile int pool_okay;
71
72 /* True, if the memory pool is mmapped.  */
73 static volatile int pool_is_mmapped;
74
75 /* FIXME?  */
76 static int disable_secmem;
77 static int show_warning;
78 static int not_locked;
79 static int no_warning;
80 static int suspend_warning;
81
82 /* Stats.  */
83 static unsigned int cur_alloced, cur_blocks;
84
85 /* Lock protecting accesses to the memory pool.  */
86 static ath_mutex_t secmem_lock;
87
88 /* Convenient macros.  */
89 #define SECMEM_LOCK   ath_mutex_lock   (&secmem_lock)
90 #define SECMEM_UNLOCK ath_mutex_unlock (&secmem_lock)
91
92 /* The size of the memblock structure; this does not include the
93    memory that is available to the user.  */
94 #define BLOCK_HEAD_SIZE \
95   offsetof (memblock_t, aligned)
96
97 /* Convert an address into the according memory block structure.  */
98 #define ADDR_TO_BLOCK(addr) \
99   (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE)
100
101 /* Check whether P points into the pool.  */
102 static int
103 ptr_into_pool_p (const void *p)
104 {
105   /* We need to convert pointers to addresses.  This is required by
106      C-99 6.5.8 to avoid undefined behaviour.  Using size_t is at
107      least only implementation defined.  See also
108      http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
109   */
110   size_t p_addr = (size_t)p;
111   size_t pool_addr = (size_t)pool;
112
113   return p_addr >= pool_addr && p_addr <  pool_addr+pool_size;
114 }
115
116 /* Update the stats.  */
117 static void
118 stats_update (size_t add, size_t sub)
119 {
120   if (add)
121     {
122       cur_alloced += add;
123       cur_blocks++;
124     }
125   if (sub)
126     {
127       cur_alloced -= sub;
128       cur_blocks--;
129     }
130 }
131
132 /* Return the block following MB or NULL, if MB is the last block.  */
133 static memblock_t *
134 mb_get_next (memblock_t *mb)
135 {
136   memblock_t *mb_next;
137
138   mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size);
139
140   if (! ptr_into_pool_p (mb_next))
141     mb_next = NULL;
142
143   return mb_next;
144 }
145
146 /* Return the block preceding MB or NULL, if MB is the first
147    block.  */
148 static memblock_t *
149 mb_get_prev (memblock_t *mb)
150 {
151   memblock_t *mb_prev, *mb_next;
152
153   if (mb == pool)
154     mb_prev = NULL;
155   else
156     {
157       mb_prev = (memblock_t *) pool;
158       while (1)
159         {
160           mb_next = mb_get_next (mb_prev);
161           if (mb_next == mb)
162             break;
163           else
164             mb_prev = mb_next;
165         }
166     }
167
168   return mb_prev;
169 }
170
171 /* If the preceding block of MB and/or the following block of MB
172    exist and are not active, merge them to form a bigger block.  */
173 static void
174 mb_merge (memblock_t *mb)
175 {
176   memblock_t *mb_prev, *mb_next;
177
178   mb_prev = mb_get_prev (mb);
179   mb_next = mb_get_next (mb);
180
181   if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE)))
182     {
183       mb_prev->size += BLOCK_HEAD_SIZE + mb->size;
184       mb = mb_prev;
185     }
186   if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE)))
187     mb->size += BLOCK_HEAD_SIZE + mb_next->size;
188 }
189
190 /* Return a new block, which can hold SIZE bytes.  */
191 static memblock_t *
192 mb_get_new (memblock_t *block, size_t size)
193 {
194   memblock_t *mb, *mb_split;
195
196   for (mb = block; ptr_into_pool_p (mb); mb = mb_get_next (mb))
197     if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size)
198       {
199         /* Found a free block.  */
200         mb->flags |= MB_FLAG_ACTIVE;
201
202         if (mb->size - size > BLOCK_HEAD_SIZE)
203           {
204             /* Split block.  */
205
206             mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size);
207             mb_split->size = mb->size - size - BLOCK_HEAD_SIZE;
208             mb_split->flags = 0;
209
210             mb->size = size;
211
212             mb_merge (mb_split);
213
214           }
215
216         break;
217       }
218
219   if (! ptr_into_pool_p (mb))
220     {
221       gpg_err_set_errno (ENOMEM);
222       mb = NULL;
223     }
224
225   return mb;
226 }
227
228 /* Print a warning message.  */
229 static void
230 print_warn (void)
231 {
232   if (!no_warning)
233     log_info (_("Warning: using insecure memory!\n"));
234 }
235
236 /* Lock the memory pages into core and drop privileges.  */
237 static void
238 lock_pool (void *p, size_t n)
239 {
240 #if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
241   int err;
242
243   cap_set_proc (cap_from_text ("cap_ipc_lock+ep"));
244   err = mlock (p, n);
245   if (err && errno)
246     err = errno;
247   cap_set_proc (cap_from_text ("cap_ipc_lock+p"));
248
249   if (err)
250     {
251       if (errno != EPERM
252 #ifdef EAGAIN   /* OpenBSD returns this */
253           && errno != EAGAIN
254 #endif
255 #ifdef ENOSYS   /* Some SCOs return this (function not implemented) */
256           && errno != ENOSYS
257 #endif
258 #ifdef ENOMEM  /* Linux might return this. */
259             && errno != ENOMEM
260 #endif
261           )
262         log_error ("can't lock memory: %s\n", strerror (err));
263       show_warning = 1;
264       not_locked = 1;
265     }
266
267 #elif defined(HAVE_MLOCK)
268   uid_t uid;
269   int err;
270
271   uid = getuid ();
272
273 #ifdef HAVE_BROKEN_MLOCK
274   /* Under HP/UX mlock segfaults if called by non-root.  Note, we have
275      noch checked whether mlock does really work under AIX where we
276      also detected a broken nlock.  Note further, that using plock ()
277      is not a good idea under AIX. */
278   if (uid)
279     {
280       errno = EPERM;
281       err = errno;
282     }
283   else
284     {
285       err = mlock (p, n);
286       if (err && errno)
287         err = errno;
288     }
289 #else /* !HAVE_BROKEN_MLOCK */
290   err = mlock (p, n);
291   if (err && errno)
292     err = errno;
293 #endif /* !HAVE_BROKEN_MLOCK */
294
295   if (uid && ! geteuid ())
296     {
297       /* check that we really dropped the privs.
298        * Note: setuid(0) should always fail */
299       if (setuid (uid) || getuid () != geteuid () || !setuid (0))
300         log_fatal ("failed to reset uid: %s\n", strerror (errno));
301     }
302
303   if (err)
304     {
305       if (errno != EPERM
306 #ifdef EAGAIN   /* OpenBSD returns this. */
307           && errno != EAGAIN
308 #endif
309 #ifdef ENOSYS   /* Some SCOs return this (function not implemented). */
310           && errno != ENOSYS
311 #endif
312 #ifdef ENOMEM  /* Linux might return this. */
313             && errno != ENOMEM
314 #endif
315           )
316         log_error ("can't lock memory: %s\n", strerror (err));
317       show_warning = 1;
318       not_locked = 1;
319     }
320
321 #elif defined ( __QNX__ )
322   /* QNX does not page at all, so the whole secure memory stuff does
323    * not make much sense.  However it is still of use because it
324    * wipes out the memory on a free().
325    * Therefore it is sufficient to suppress the warning.  */
326   (void)p;
327   (void)n;
328 #elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
329     /* It does not make sense to print such a warning, given the fact that
330      * this whole Windows !@#$% and their user base are inherently insecure. */
331   (void)p;
332   (void)n;
333 #elif defined (__riscos__)
334     /* No virtual memory on RISC OS, so no pages are swapped to disc,
335      * besides we don't have mmap, so we don't use it! ;-)
336      * But don't complain, as explained above.  */
337   (void)p;
338   (void)n;
339 #else
340   (void)p;
341   (void)n;
342   log_info ("Please note that you don't have secure memory on this system\n");
343 #endif
344 }
345
346 /* Initialize POOL.  */
347 static void
348 init_pool (size_t n)
349 {
350   size_t pgsize;
351   long int pgsize_val;
352   memblock_t *mb;
353
354   pool_size = n;
355
356   if (disable_secmem)
357     log_bug ("secure memory is disabled");
358
359 #if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
360   pgsize_val = sysconf (_SC_PAGESIZE);
361 #elif defined(HAVE_GETPAGESIZE)
362   pgsize_val = getpagesize ();
363 #else
364   pgsize_val = -1;
365 #endif
366   pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
367
368
369 #if HAVE_MMAP
370   pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1);
371 #ifdef MAP_ANONYMOUS
372   pool = mmap (0, pool_size, PROT_READ | PROT_WRITE,
373                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
374 #else /* map /dev/zero instead */
375   {
376     int fd;
377
378     fd = open ("/dev/zero", O_RDWR);
379     if (fd == -1)
380       {
381         log_error ("can't open /dev/zero: %s\n", strerror (errno));
382         pool = (void *) -1;
383       }
384     else
385       {
386         pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
387         close (fd);
388       }
389   }
390 #endif
391   if (pool == (void *) -1)
392     log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
393               (unsigned) pool_size, strerror (errno));
394   else
395     {
396       pool_is_mmapped = 1;
397       pool_okay = 1;
398     }
399
400 #endif
401   if (!pool_okay)
402     {
403       pool = malloc (pool_size);
404       if (!pool)
405         log_fatal ("can't allocate memory pool of %u bytes\n",
406                    (unsigned) pool_size);
407       else
408         pool_okay = 1;
409     }
410
411   /* Initialize first memory block.  */
412   mb = (memblock_t *) pool;
413   mb->size = pool_size;
414   mb->flags = 0;
415 }
416
417 void
418 _gcry_secmem_set_flags (unsigned flags)
419 {
420   int was_susp;
421
422   SECMEM_LOCK;
423
424   was_susp = suspend_warning;
425   no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
426   suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
427
428   /* and now issue the warning if it is not longer suspended */
429   if (was_susp && !suspend_warning && show_warning)
430     {
431       show_warning = 0;
432       print_warn ();
433     }
434
435   SECMEM_UNLOCK;
436 }
437
438 unsigned int
439 _gcry_secmem_get_flags (void)
440 {
441   unsigned flags;
442
443   SECMEM_LOCK;
444
445   flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
446   flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
447   flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
448
449   SECMEM_UNLOCK;
450
451   return flags;
452 }
453
454
455 /* See _gcry_secmem_init.  This function is expected to be called with
456    the secmem lock held. */
457 static void
458 secmem_init (size_t n)
459 {
460   if (!n)
461     {
462 #ifdef USE_CAPABILITIES
463       /* drop all capabilities */
464       cap_set_proc (cap_from_text ("all-eip"));
465
466 #elif !defined(HAVE_DOSISH_SYSTEM)
467       uid_t uid;
468
469       disable_secmem = 1;
470       uid = getuid ();
471       if (uid != geteuid ())
472         {
473           if (setuid (uid) || getuid () != geteuid () || !setuid (0))
474             log_fatal ("failed to drop setuid\n");
475         }
476 #endif
477     }
478   else
479     {
480       if (n < MINIMUM_POOL_SIZE)
481         n = MINIMUM_POOL_SIZE;
482       if (! pool_okay)
483         {
484           init_pool (n);
485           lock_pool (pool, n);
486         }
487       else
488         log_error ("Oops, secure memory pool already initialized\n");
489     }
490 }
491
492
493
494 /* Initialize the secure memory system.  If running with the necessary
495    privileges, the secure memory pool will be locked into the core in
496    order to prevent page-outs of the data.  Furthermore allocated
497    secure memory will be wiped out when released.  */
498 void
499 _gcry_secmem_init (size_t n)
500 {
501   SECMEM_LOCK;
502
503   secmem_init (n);
504
505   SECMEM_UNLOCK;
506 }
507
508
509 gcry_err_code_t
510 _gcry_secmem_module_init ()
511 {
512   int err;
513
514   err = ath_mutex_init (&secmem_lock);
515   if (err)
516     log_fatal ("could not allocate secmem lock\n");
517
518   return 0;
519 }
520
521
522 static void *
523 _gcry_secmem_malloc_internal (size_t size)
524 {
525   memblock_t *mb;
526
527   if (!pool_okay)
528     {
529       /* Try to initialize the pool if the user forgot about it.  */
530       secmem_init (STANDARD_POOL_SIZE);
531       if (!pool_okay)
532         {
533           log_info (_("operation is not possible without "
534                       "initialized secure memory\n"));
535           gpg_err_set_errno (ENOMEM);
536           return NULL;
537         }
538     }
539   if (not_locked && fips_mode ())
540     {
541       log_info (_("secure memory pool is not locked while in FIPS mode\n"));
542       gpg_err_set_errno (ENOMEM);
543       return NULL;
544     }
545   if (show_warning && !suspend_warning)
546     {
547       show_warning = 0;
548       print_warn ();
549     }
550
551   /* Blocks are always a multiple of 32. */
552   size = ((size + 31) / 32) * 32;
553
554   mb = mb_get_new ((memblock_t *) pool, size);
555   if (mb)
556     stats_update (size, 0);
557
558   return mb ? &mb->aligned.c : NULL;
559 }
560
561 void *
562 _gcry_secmem_malloc (size_t size)
563 {
564   void *p;
565
566   SECMEM_LOCK;
567   p = _gcry_secmem_malloc_internal (size);
568   SECMEM_UNLOCK;
569
570   return p;
571 }
572
573 static void
574 _gcry_secmem_free_internal (void *a)
575 {
576   memblock_t *mb;
577   int size;
578
579   if (!a)
580     return;
581
582   mb = ADDR_TO_BLOCK (a);
583   size = mb->size;
584
585   /* This does not make much sense: probably this memory is held in the
586    * cache. We do it anyway: */
587 #define MB_WIPE_OUT(byte) \
588   wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size);
589
590   MB_WIPE_OUT (0xff);
591   MB_WIPE_OUT (0xaa);
592   MB_WIPE_OUT (0x55);
593   MB_WIPE_OUT (0x00);
594
595   stats_update (0, size);
596
597   mb->flags &= ~MB_FLAG_ACTIVE;
598
599   /* Update stats.  */
600
601   mb_merge (mb);
602 }
603
604 /* Wipe out and release memory.  */
605 void
606 _gcry_secmem_free (void *a)
607 {
608   SECMEM_LOCK;
609   _gcry_secmem_free_internal (a);
610   SECMEM_UNLOCK;
611 }
612
613 /* Realloc memory.  */
614 void *
615 _gcry_secmem_realloc (void *p, size_t newsize)
616 {
617   memblock_t *mb;
618   size_t size;
619   void *a;
620
621   SECMEM_LOCK;
622
623   mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c));
624   size = mb->size;
625   if (newsize < size)
626     {
627       /* It is easier to not shrink the memory.  */
628       a = p;
629     }
630   else
631     {
632       a = _gcry_secmem_malloc_internal (newsize);
633       if (a)
634         {
635           memcpy (a, p, size);
636           memset ((char *) a + size, 0, newsize - size);
637           _gcry_secmem_free_internal (p);
638         }
639     }
640
641   SECMEM_UNLOCK;
642
643   return a;
644 }
645
646
647 /* Return true if P points into the secure memory area.  */
648 int
649 _gcry_private_is_secure (const void *p)
650 {
651   return pool_okay && ptr_into_pool_p (p);
652 }
653
654
655 /****************
656  * Warning:  This code might be called by an interrupt handler
657  *           and frankly, there should really be such a handler,
658  *           to make sure that the memory is wiped out.
659  *           We hope that the OS wipes out mlocked memory after
660  *           receiving a SIGKILL - it really should do so, otherwise
661  *           there is no chance to get the secure memory cleaned.
662  */
663 void
664 _gcry_secmem_term ()
665 {
666   if (!pool_okay)
667     return;
668
669   wipememory2 (pool, 0xff, pool_size);
670   wipememory2 (pool, 0xaa, pool_size);
671   wipememory2 (pool, 0x55, pool_size);
672   wipememory2 (pool, 0x00, pool_size);
673 #if HAVE_MMAP
674   if (pool_is_mmapped)
675     munmap (pool, pool_size);
676 #endif
677   pool = NULL;
678   pool_okay = 0;
679   pool_size = 0;
680   not_locked = 0;
681 }
682
683
684 void
685 _gcry_secmem_dump_stats ()
686 {
687 #if 1
688   SECMEM_LOCK;
689
690  if (pool_okay)
691     log_info ("secmem usage: %u/%lu bytes in %u blocks\n",
692               cur_alloced, (unsigned long)pool_size, cur_blocks);
693   SECMEM_UNLOCK;
694 #else
695   memblock_t *mb;
696   int i;
697
698   SECMEM_LOCK;
699
700   for (i = 0, mb = (memblock_t *) pool;
701        ptr_into_pool_p (mb);
702        mb = mb_get_next (mb), i++)
703     log_info ("SECMEM: [%s] block: %i; size: %i\n",
704               (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
705               i,
706               mb->size);
707   SECMEM_UNLOCK;
708 #endif
709 }