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