diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/Makefile.am | 2 | ||||
-rw-r--r-- | util/Makefile.in | 28 | ||||
-rw-r--r-- | util/argparse.c | 2 | ||||
-rw-r--r-- | util/logger.c | 2 | ||||
-rw-r--r-- | util/memory.c | 16 | ||||
-rw-r--r-- | util/secmem.c | 243 |
6 files changed, 271 insertions, 22 deletions
diff --git a/util/Makefile.am b/util/Makefile.am index 5fd3e59ca..222b4d876 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -6,7 +6,7 @@ noinst_LIBRARIES = util util_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \ - ttyio.c argparse.c memory.c errors.c iobuf.c + ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c diff --git a/util/Makefile.in b/util/Makefile.in index ca24380d6..9ca5f0fd2 100644 --- a/util/Makefile.in +++ b/util/Makefile.in @@ -43,7 +43,7 @@ INCLUDES = -I$(top_srcdir)/include noinst_LIBRARIES = util util_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \ - ttyio.c argparse.c memory.c errors.c iobuf.c + ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = ../config.h LIBRARIES = $(noinst_LIBRARIES) @@ -64,7 +64,7 @@ COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(LDFLAGS) -o $@ util_LIBADD = util_OBJECTS = logger.o fileutil.o miscutil.o strgutil.o ttyio.o \ -argparse.o memory.o errors.o iobuf.o +argparse.o memory.o secmem.o errors.o iobuf.o EXTRA_util_SOURCES = LIBFILES = libutil.a AR = ar @@ -84,8 +84,8 @@ TAR = tar DEP_FILES = $(srcdir)/.deps/argparse.P $(srcdir)/.deps/errors.P \ $(srcdir)/.deps/fileutil.P $(srcdir)/.deps/iobuf.P \ $(srcdir)/.deps/logger.P $(srcdir)/.deps/memory.P \ -$(srcdir)/.deps/miscutil.P $(srcdir)/.deps/strgutil.P \ -$(srcdir)/.deps/ttyio.P +$(srcdir)/.deps/miscutil.P $(srcdir)/.deps/secmem.P \ +$(srcdir)/.deps/strgutil.P $(srcdir)/.deps/ttyio.P SOURCES = $(util_SOURCES) OBJECTS = $(util_OBJECTS) @@ -170,11 +170,11 @@ $(srcdir)/.deps/%.P: $(srcdir)/%.c @echo "mkdeps $< > $@" @re=`echo 's,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g' | sed 's,\.,\\\\.,g'`; \ $(MKDEP) $< | sed "$$re" > $@-tmp - @if test -n "$o"; then \ - sed 's/\.o:/$$o:/' $@-tmp > $@; \ + @if test -n "$o"; then \ + sed 's/\.o:/$$o:/' $@-tmp > $@; \ rm $@-tmp; \ else \ - mv $@-tmp $@; \ + mv $@-tmp $@; \ fi # End of maintainer-only section @@ -186,14 +186,14 @@ check: all installcheck: -install-exec: +install-exec: -install-data: +install-data: install: install-exec install-data all @: -uninstall: +uninstall: all: $(LIBFILES) Makefile @@ -218,16 +218,16 @@ maintainer-clean-generic: mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \ mostlyclean-tags mostlyclean-generic -clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ - mostlyclean +clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ + mostlyclean distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \ - distclean-generic clean + distclean-generic clean rm -f config.status maintainer-clean: maintainer-clean-noinstLIBRARIES \ maintainer-clean-compile maintainer-clean-tags \ - maintainer-clean-generic distclean + maintainer-clean-generic distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." diff --git a/util/argparse.c b/util/argparse.c index 09c820a72..795e87648 100644 --- a/util/argparse.c +++ b/util/argparse.c @@ -545,7 +545,7 @@ show_help( ARGPARSE_OPTS *opts, unsigned flags ) indent += 10; puts("Options:"); for(i=0; opts[i].short_opt; i++ ) { - s = _(opts[i].description); + s = _( opts[i].description ); if( s && *s== '\r' ) /* hide this line */ continue; if( opts[i].short_opt < 256 ) diff --git a/util/logger.c b/util/logger.c index 2355b6267..04dac2ce6 100644 --- a/util/logger.c +++ b/util/logger.c @@ -111,6 +111,7 @@ log_fatal( const char *fmt, ... ) va_start( arg_ptr, fmt ) ; vfprintf(stderr,fmt,arg_ptr) ; va_end(arg_ptr); + secmem_dump_stats(); exit(2); } @@ -124,6 +125,7 @@ log_bug( const char *fmt, ... ) vfprintf(stderr,fmt,arg_ptr) ; va_end(arg_ptr); fflush(stderr); + secmem_dump_stats(); abort(); } diff --git a/util/memory.c b/util/memory.c index 1a60b4931..cd4dc815d 100644 --- a/util/memory.c +++ b/util/memory.c @@ -314,9 +314,10 @@ membug( const char *fmt, ... ) static void -out_of_core(size_t n) +out_of_core(size_t n, int secure) { - log_fatal("out of memory while allocating %u bytes\n", (unsigned)n ); + log_fatal("out of %s memory while allocating %u bytes\n", + secure? "secure":"" ,(unsigned)n ); } /**************** @@ -329,7 +330,7 @@ FNAME(alloc)( size_t n FNAMEPRT ) char *p; if( !(p = malloc( n + 5 )) ) - out_of_core(n); + out_of_core(n,0); store_len(p,n,0); p[4+n] = MAGIC_END_BYTE; /* need to add the length somewhere */ return p+4; @@ -344,8 +345,8 @@ FNAME(alloc_secure)( size_t n FNAMEPRT ) { char *p; - if( !(p = malloc( n + 5 )) ) /* fixme: should alloc from the secure heap*/ - out_of_core(n); + if( !(p = secmem_malloc( n + 5 )) ) + out_of_core(n,1); store_len(p,n,1); p[4+n] = MAGIC_END_BYTE; return p+4; @@ -408,7 +409,10 @@ FNAME(free)( void *a FNAMEPRT ) free_entry(p-4, info); #else m_check(p); - free(p-4); + if( m_is_secure(a) ) + secmem_free(p-4); + else + free(p-4); #endif } diff --git a/util/secmem.c b/util/secmem.c new file mode 100644 index 000000000..097a71fe8 --- /dev/null +++ b/util/secmem.c @@ -0,0 +1,243 @@ +/* secmem.c - memory allocation from a secure heap + * Copyright (c) 1997 by Werner Koch (dd9jn) + * + * This file is part of G10. + * + * G10 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * G10 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <stdarg.h> +#if defined(HAVE_MLOCK) || defined(HAVE_MMAP) + #include <unistd.h> + #include <sys/mman.h> + #include <sys/types.h> +#endif + +#include "types.h" +#include "memory.h" +#include "util.h" + + +#define DEFAULT_POOLSIZE 8196 + +typedef struct memblock_struct MEMBLOCK; +struct memblock_struct { + unsigned size; + union { + MEMBLOCK *next; + long align_dummy; + char d[1]; + } u; +}; + + + +static void *pool; +static int pool_okay; +static int pool_is_mmapped; +static size_t poolsize; /* allocated length */ +static size_t poollen; /* used length */ +static MEMBLOCK *unused_blocks; +static unsigned max_alloced; +static unsigned cur_alloced; +static unsigned max_blocks; +static unsigned cur_blocks; + + +static void +lock_pool( void *p, size_t n ) +{ + #ifdef HAVE_MLOCK + uid_t uid; + int err; + + err = mlock( p, n ); + if( err && errno ) + err = errno; + + uid = getuid(); + if( uid && !geteuid() ) { + if( setuid( uid ) ) + log_fatal("failed to reset uid: %s\n", strerror(errno)); + } + + if( err ) { + log_error("can�t lock memory: %s\n", strerror(err)); + log_info("Warning: using insecure memory!\n"); + } + + #else + log_info("Please note that you don�t have secure memory on this system\n"); + #endif +} + + +static void +init_pool( size_t n) +{ + poolsize = n; + + #if HAVE_MMAP && defined(MAP_ANONYMOUS) + poolsize = (poolsize + 4095) & ~4095; + pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if( pool == (void*)-1 ) + log_error("can�t mmap pool of %u bytes: %s - using malloc\n", + (unsigned)poolsize, strerror(errno)); + else { + pool_is_mmapped = 1; + pool_okay = 1; + } + + #endif + if( !pool_okay ) { + pool = malloc( poolsize ); + if( !pool ) + log_fatal("can�t allocate memory pool of %u bytes\n", + (unsigned)poolsize); + else + pool_okay = 1; + } + lock_pool( pool, poolsize ); + poollen = 0; +} + + +/* concatenate unused blocks */ +static void +compress_pool(void) +{ + +} + + +void +secmem_init( size_t n ) +{ + if( n < DEFAULT_POOLSIZE ) + n = DEFAULT_POOLSIZE; + if( !pool_okay ) + init_pool(n); + else + log_error("Oops, secure memory pool already initialized\n"); +} + + +void * +secmem_malloc( size_t size ) +{ + MEMBLOCK *mb, *mb2; + int compressed=0; + + if( !pool_okay ) + init_pool(DEFAULT_POOLSIZE); + + /* blocks are always a multiple of 32 */ + size += sizeof(MEMBLOCK); + size = ((size + 31) / 32) * 32; + + retry: + /* try to get it from the used blocks */ + for(mb = unused_blocks,mb2=NULL; mb; mb2=mb, mb = mb->u.next ) + if( mb->size >= size ) { + if( mb2 ) + mb2->u.next = mb->u.next; + else + unused_blocks = mb->u.next; + goto leave; + } + /* allocate a new block */ + if( (poollen + size <= poolsize) ) { + mb = pool + poollen; + poollen += size; + mb->size = size; + } + else if( !compressed ) { + compressed=1; + compress_pool(); + goto retry; + } + else + return NULL; + + leave: + cur_alloced += mb->size; + cur_blocks++; + if( cur_alloced > max_alloced ) + max_alloced = cur_alloced; + if( cur_blocks > max_blocks ) + max_blocks = cur_blocks; + return &mb->u.d; +} + + +void +secmem_free( void *a ) +{ + MEMBLOCK *mb; + size_t size; + + if( !a ) + return; + + mb = (MEMBLOCK*)((char*)a - ((size_t) &((MEMBLOCK*)0)->u.d)); + size = mb->size; + memset(mb, 0xff, size ); + memset(mb, 0xaa, size ); + memset(mb, 0x55, size ); + memset(mb, 0x00, size ); + mb->size = size; + mb->u.next = unused_blocks; + unused_blocks = mb; + cur_blocks--; + cur_alloced -= size; +} + +void +secmem_term() +{ + if( !pool_okay ) + return; + + memset( pool, 0xff, poolsize); + memset( pool, 0xaa, poolsize); + memset( pool, 0x55, poolsize); + memset( pool, 0x00, poolsize); + #if HAVE_MMAP + if( pool_is_mmapped ) + munmap( pool, poolsize ); + #endif + pool = NULL; + pool_okay = 0; + poolsize=0; + poollen=0; + unused_blocks=NULL; +} + + +void +secmem_dump_stats() +{ + fprintf(stderr, + "secmem usage: %u/%u bytes in %u/%u blocks of pool %lu/%lu\n", + cur_alloced, max_alloced, cur_blocks, max_blocks, + (ulong)poollen, (ulong)poolsize ); +} + |