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