1 /* secmem.c - memory allocation from a secure heap
2 * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
29 #if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
31 #include <sys/types.h>
33 #ifdef USE_CAPABILITIES
34 #include <sys/capability.h>
46 /* MinGW doesn't seem to prototype getpagesize, though it does have
48 #if !HAVE_DECL_GETPAGESIZE
49 int getpagesize(void);
52 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
53 #define MAP_ANONYMOUS MAP_ANON
55 /* It seems that Slackware 7.1 does not know about EPERM */
56 #if !defined(EPERM) && defined(ENOMEM)
61 #define DEFAULT_POOLSIZE 16384
63 typedef struct memblock_struct MEMBLOCK
;
64 struct memblock_struct
{
68 PROPERLY_ALIGNED_TYPE aligned
;
75 static volatile int pool_okay
; /* may be checked in an atexit function */
77 static volatile int pool_is_mmapped
;
79 static size_t poolsize
; /* allocated length */
80 static size_t poollen
; /* used length */
81 static MEMBLOCK
*unused_blocks
;
82 static unsigned max_alloced
;
83 static unsigned cur_alloced
;
84 static unsigned max_blocks
;
85 static unsigned cur_blocks
;
86 static int disable_secmem
;
87 static int show_warning
;
88 static int no_warning
;
89 static int suspend_warning
;
97 log_info(_("WARNING: using insecure memory!\n"));
98 log_info(_("please see http://www.gnupg.org/faq.html"
99 " for more information\n"));
105 lock_pool( void *p
, size_t n
)
107 #if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
110 cap_set_proc( cap_from_text("cap_ipc_lock+ep") );
114 cap_set_proc( cap_from_text("cap_ipc_lock+p") );
118 #ifdef EAGAIN /* OpenBSD returns this */
121 #ifdef ENOSYS /* Some SCOs return this (function not implemented) */
124 #ifdef ENOMEM /* Linux can return this */
128 log_error("can't lock memory: %s\n", strerror(err
));
132 #elif defined(HAVE_MLOCK)
138 #ifdef HAVE_BROKEN_MLOCK
139 /* ick. but at least we get secured memory. about to lock
140 entire data segment. */
143 /* The configure for AIX returns broken mlock but the plock has
144 the strange requirement to somehow set the stack limit first.
145 The problem might turn out in indeterministic program behaviour
146 and hanging processes which can somehow be solved when enough
147 processes are clogging up the memory. To get this problem out
148 of the way we simply don't try to lock the memory at all.
153 err
= plock( DATLOCK
);
157 #else /*!HAVE_PLOCK*/
167 #endif /*!HAVE_PLOCK*/
174 if( uid
&& !geteuid() ) {
175 /* check that we really dropped the privs.
176 * Note: setuid(0) should always fail */
177 if( setuid( uid
) || getuid() != geteuid() || !setuid(0) )
178 log_fatal("failed to reset uid: %s\n", strerror(errno
));
183 #ifdef EAGAIN /* OpenBSD returns this */
186 #ifdef ENOSYS /* Some SCOs return this (function not implemented) */
189 #ifdef ENOMEM /* Linux can return this */
193 log_error("can't lock memory: %s\n", strerror(err
));
197 #elif defined ( __QNX__ )
198 /* QNX does not page at all, so the whole secure memory stuff does
199 * not make much sense. However it is still of use because it
200 * wipes out the memory on a free().
201 * Therefore it is sufficient to suppress the warning
203 #elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
204 /* It does not make sense to print such a warning, given the fact that
205 * this whole Windows !@#$% and their user base are inherently insecure
207 #elif defined (__riscos__)
208 /* no virtual memory on RISC OS, so no pages are swapped to disc,
209 * besides we don't have mmap, so we don't use it! ;-)
210 * But don't complain, as explained above.
213 log_info("Please note that you don't have secure memory on this system\n");
226 log_bug("secure memory is disabled");
228 #ifdef HAVE_GETPAGESIZE
229 pgsize
= getpagesize();
235 poolsize
= (poolsize
+ pgsize
-1 ) & ~(pgsize
-1);
237 pool
= mmap( 0, poolsize
, PROT_READ
|PROT_WRITE
,
238 MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
239 #else /* map /dev/zero instead */
242 fd
= open("/dev/zero", O_RDWR
);
244 log_error("can't open /dev/zero: %s\n", strerror(errno
) );
248 pool
= mmap( 0, poolsize
, PROT_READ
|PROT_WRITE
,
253 if( pool
== (void*)-1 )
254 log_info("can't mmap pool of %u bytes: %s - using malloc\n",
255 (unsigned)poolsize
, strerror(errno
));
263 pool
= malloc( poolsize
);
265 log_fatal("can't allocate memory pool of %u bytes\n",
270 lock_pool( pool
, poolsize
);
275 /* concatenate unused blocks */
279 /* fixme: we really should do this */
283 secmem_set_flags( unsigned flags
)
285 int was_susp
= suspend_warning
;
287 no_warning
= flags
& 1;
288 suspend_warning
= flags
& 2;
290 /* and now issue the warning if it is not longer suspended */
291 if( was_susp
&& !suspend_warning
&& show_warning
) {
298 secmem_get_flags(void)
302 flags
= no_warning
? 1:0;
303 flags
|= suspend_warning
? 2:0;
307 /* Returns 1 if memory was locked, 0 if not. */
309 secmem_init( size_t n
)
313 #ifdef USE_CAPABILITIES
314 /* drop all capabilities */
315 cap_set_proc( cap_from_text("all-eip") );
317 #elif !defined(HAVE_DOSISH_SYSTEM)
322 if( uid
!= geteuid() ) {
323 if( setuid( uid
) || getuid() != geteuid() || !setuid(0) )
324 log_fatal("failed to drop setuid\n" );
327 #endif /* !__riscos__ */
330 if( n
< DEFAULT_POOLSIZE
)
331 n
= DEFAULT_POOLSIZE
;
335 log_error("Oops, secure memory pool already initialized\n");
338 return !show_warning
;
343 secmem_malloc( size_t size
)
350 _("operation is not possible without initialized secure memory\n"));
351 log_info(_("(you may have used the wrong program for this task)\n"));
354 if( show_warning
&& !suspend_warning
) {
359 /* Blocks are always a multiple of 32. Note that we allocate an
360 extra of the size of an entire MEMBLOCK. This is required
361 becuase we do not only need the SIZE info but also extra space
362 to chain up unused memory blocks. */
363 size
+= sizeof(MEMBLOCK
);
364 size
= ((size
+ 31) / 32) * 32;
367 /* try to get it from the used blocks */
368 for(mb
= unused_blocks
,mb2
=NULL
; mb
; mb2
=mb
, mb
= mb
->u
.next
)
369 if( mb
->size
>= size
) {
371 mb2
->u
.next
= mb
->u
.next
;
373 unused_blocks
= mb
->u
.next
;
376 /* allocate a new block */
377 if( (poollen
+ size
<= poolsize
) ) {
378 mb
= (void*)((char*)pool
+ poollen
);
382 else if( !compressed
) {
391 cur_alloced
+= mb
->size
;
393 if( cur_alloced
> max_alloced
)
394 max_alloced
= cur_alloced
;
395 if( cur_blocks
> max_blocks
)
396 max_blocks
= cur_blocks
;
398 return &mb
->u
.aligned
.c
;
403 secmexrealloc( void *p
, size_t newsize
)
409 mb
= (MEMBLOCK
*)((char*)p
- ((size_t) &((MEMBLOCK
*)0)->u
.aligned
.c
));
411 if (size
< sizeof(MEMBLOCK
))
412 log_bug ("secure memory corrupted at block %p\n", (void *)mb
);
413 size
-= ((size_t) &((MEMBLOCK
*)0)->u
.aligned
.c
);
415 if( newsize
<= size
)
416 return p
; /* It is easier not to shrink the memory. */
417 a
= secmem_malloc( newsize
);
420 memset((char*)a
+size
, 0, newsize
-size
);
428 secmem_free( void *a
)
436 mb
= (MEMBLOCK
*)((char*)a
- ((size_t) &((MEMBLOCK
*)0)->u
.aligned
.c
));
438 /* This does not make much sense: probably this memory is held in the
439 * cache. We do it anyway: */
440 wipememory2(mb
, 0xff, size
);
441 wipememory2(mb
, 0xaa, size
);
442 wipememory2(mb
, 0x55, size
);
443 wipememory2(mb
, 0x00, size
);
445 mb
->u
.next
= unused_blocks
;
452 m_is_secure( const void *p
)
454 return p
>= pool
&& p
< (void*)((char*)pool
+poolsize
);
460 * Warning: This code might be called by an interrupt handler
461 * and frankly, there should really be such a handler,
462 * to make sure that the memory is wiped out.
463 * We hope that the OS wipes out mlocked memory after
464 * receiving a SIGKILL - it really should do so, otherwise
465 * there is no chance to get the secure memory cleaned.
473 wipememory2( pool
, 0xff, poolsize
);
474 wipememory2( pool
, 0xaa, poolsize
);
475 wipememory2( pool
, 0x55, poolsize
);
476 wipememory2( pool
, 0x00, poolsize
);
478 if( pool_is_mmapped
)
479 munmap( pool
, poolsize
);
495 "secmem usage: %u/%u bytes in %u/%u blocks of pool %lu/%lu\n",
496 cur_alloced
, max_alloced
, cur_blocks
, max_blocks
,
497 (ulong
)poollen
, (ulong
)poolsize
);