aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/Makefile.am2
-rw-r--r--util/Makefile.in28
-rw-r--r--util/argparse.c2
-rw-r--r--util/logger.c2
-rw-r--r--util/memory.c16
-rw-r--r--util/secmem.c243
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 );
+}
+