diff options
-rw-r--r-- | egg/Makefile.am | 4 | ||||
-rw-r--r-- | egg/egg-secure-memory.c | 69 | ||||
-rw-r--r-- | egg/egg-secure-memory.h | 42 | ||||
-rw-r--r-- | egg/tests/test-dh.c | 2 | ||||
-rw-r--r-- | egg/tests/test-hkdf.c | 12 | ||||
-rw-r--r-- | egg/tests/test-openssl.c | 2 | ||||
-rw-r--r-- | egg/tests/test-secmem.c | 2 | ||||
-rw-r--r-- | egg/tests/test-symkey.c | 2 | ||||
-rw-r--r-- | gck/Makefile.am | 3 | ||||
-rw-r--r-- | gck/gck-misc.c | 4 | ||||
-rw-r--r-- | gck/gck.symbols | 1 | ||||
-rw-r--r-- | gcr/Makefile.am | 2 | ||||
-rw-r--r-- | gcr/gcr-memory.c | 66 |
13 files changed, 89 insertions, 122 deletions
diff --git a/egg/Makefile.am b/egg/Makefile.am index a9de41a..64b0934 100644 --- a/egg/Makefile.am +++ b/egg/Makefile.am @@ -5,6 +5,7 @@ noinst_LTLIBRARIES = \ libegg-asn1x.la \ libegg-entry-buffer.la \ libegg-hex.la \ + libegg-secmem.la \ libegg-test.la ASN_FILES = \ @@ -79,6 +80,9 @@ libegg_hex_la_CFLAGS = \ libegg_hex_la_LIBS = \ $(GLIB_LIBS) +libegg_secmem_la_SOURCES = \ + egg-secure-memory.c egg-secure-memory.h + libegg_test_la_SOURCES = \ egg-testing.c egg-testing.h diff --git a/egg/egg-secure-memory.c b/egg/egg-secure-memory.c index dca9bac..ca5e38d 100644 --- a/egg/egg-secure-memory.c +++ b/egg/egg-secure-memory.c @@ -66,12 +66,12 @@ #endif #define DO_LOCK() \ - egg_memory_lock (); - + EGG_SECURE_GLOBALS.lock (); + #define DO_UNLOCK() \ - egg_memory_unlock (); + EGG_SECURE_GLOBALS.unlock (); -static int lock_warning = 1; +static int show_warning = 1; int egg_secure_warnings = 1; /* @@ -163,17 +163,25 @@ typedef struct _Pool { Item items[1]; /* Actual items hang off here */ } Pool; -static Pool *all_pools = NULL; - -static void* +static void * pool_alloc (void) { Pool *pool; void *pages, *item; size_t len, i; - + + if (!EGG_SECURE_GLOBALS.pool_version || + strcmp (EGG_SECURE_GLOBALS.pool_version, EGG_SECURE_POOL_VER_STR) != 0) { + if (show_warning && egg_secure_warnings) + fprintf (stderr, "the secure memory pool version does not match the code '%s' != '%s'\n", + EGG_SECURE_GLOBALS.pool_version ? EGG_SECURE_GLOBALS.pool_version : "(null)", + EGG_SECURE_POOL_VER_STR); + show_warning = 0; + return NULL; + } + /* A pool with an available item */ - for (pool = all_pools; pool; pool = pool->next) { + for (pool = EGG_SECURE_GLOBALS.pool_data; pool; pool = pool->next) { if (unused_peek (&pool->unused)) break; } @@ -187,8 +195,8 @@ pool_alloc (void) /* Fill in the block header, and inlude in block list */ pool = pages; - pool->next = all_pools; - all_pools = pool; + pool->next = EGG_SECURE_GLOBALS.pool_data; + EGG_SECURE_GLOBALS.pool_data = pool; pool->length = len; pool->used = 0; pool->unused = NULL; @@ -223,7 +231,8 @@ pool_free (void* item) ptr = item; /* Find which block this one belongs to */ - for (at = &all_pools, pool = *at; pool; at = &pool->next, pool = *at) { + for (at = (Pool **)&EGG_SECURE_GLOBALS.pool_data, pool = *at; + pool != NULL; at = &pool->next, pool = *at) { beg = (char*)pool->items; end = (char*)pool + pool->length - sizeof (Item); if (ptr >= beg && ptr <= end) { @@ -270,7 +279,7 @@ pool_valid (void* item) ptr = item; /* Find which block this one belongs to */ - for (pool = all_pools; pool; pool = pool->next) { + for (pool = EGG_SECURE_GLOBALS.pool_data; pool; pool = pool->next) { beg = (char*)pool->items; end = (char*)pool + pool->length - sizeof (Item); if (ptr >= beg && ptr <= end) @@ -858,18 +867,18 @@ sec_acquire_pages (size_t *sz, #if defined(HAVE_MLOCK) pages = mmap (0, *sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (pages == MAP_FAILED) { - if (lock_warning && egg_secure_warnings) + if (show_warning && egg_secure_warnings) fprintf (stderr, "couldn't map %lu bytes of memory (%s): %s\n", (unsigned long)*sz, during_tag, strerror (errno)); - lock_warning = 0; + show_warning = 0; return NULL; } if (mlock (pages, *sz) < 0) { - if (lock_warning && egg_secure_warnings && errno != EPERM) { + if (show_warning && egg_secure_warnings && errno != EPERM) { fprintf (stderr, "couldn't lock %lu bytes of memory (%s): %s\n", (unsigned long)*sz, during_tag, strerror (errno)); - lock_warning = 0; + show_warning = 0; } munmap (pages, *sz); return NULL; @@ -877,13 +886,13 @@ sec_acquire_pages (size_t *sz, DEBUG_ALLOC ("gkr-secure-memory: new block ", *sz); - lock_warning = 1; + show_warning = 1; return pages; #else - if (lock_warning && egg_secure_warnings) + if (show_warning && egg_secure_warnings) fprintf (stderr, "your system does not support private memory"); - lock_warning = 0; + show_warning = 0; return NULL; #endif @@ -1050,8 +1059,8 @@ egg_secure_alloc_full (const char *tag, DO_UNLOCK (); - if (!memory && (flags & EGG_SECURE_USE_FALLBACK)) { - memory = egg_memory_fallback (NULL, length); + if (!memory && (flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback != NULL) { + memory = EGG_SECURE_GLOBALS.fallback (NULL, length); if (memory) /* Our returned memory is always zeroed */ memset (memory, 0, length); } @@ -1124,17 +1133,17 @@ egg_secure_realloc_full (const char *tag, DO_UNLOCK (); if (!block) { - if ((flags & EGG_SECURE_USE_FALLBACK)) { + if ((flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback) { /* * In this case we can't zero the returned memory, * because we don't know what the block size was. */ - return egg_memory_fallback (memory, length); + return EGG_SECURE_GLOBALS.fallback (memory, length); } else { if (egg_secure_warnings) - fprintf (stderr, "memory does not belong to gnome-keyring: 0x%08lx\n", + fprintf (stderr, "memory does not belong to secure memory pool: 0x%08lx\n", (unsigned long)memory); - ASSERT (0 && "memory does does not belong to gnome-keyring"); + ASSERT (0 && "memory does does not belong to secure memory pool"); return NULL; } } @@ -1190,13 +1199,13 @@ egg_secure_free_full (void *memory, int flags) DO_UNLOCK (); if (!block) { - if ((flags & EGG_SECURE_USE_FALLBACK)) { - egg_memory_fallback (memory, 0); + if ((flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback) { + EGG_SECURE_GLOBALS.fallback (memory, 0); } else { if (egg_secure_warnings) - fprintf (stderr, "memory does not belong to gnome-keyring: 0x%08lx\n", + fprintf (stderr, "memory does not belong to secure memory pool: 0x%08lx\n", (unsigned long)memory); - ASSERT (0 && "memory does does not belong to gnome-keyring"); + ASSERT (0 && "memory does does not belong to secure memory pool"); } } } diff --git a/egg/egg-secure-memory.h b/egg/egg-secure-memory.h index 682811d..3ef0ab5 100644 --- a/egg/egg-secure-memory.h +++ b/egg/egg-secure-memory.h @@ -39,30 +39,32 @@ * must be defined somewhere, and provide appropriate locking for * secure memory between threads: */ - -extern void egg_memory_lock (void); - -extern void egg_memory_unlock (void); - -/* - * Allocation Fallbacks - * - * If we cannot allocate secure memory, then this function - * (defined elsewhere) will be called which has a chance to - * allocate other memory abort or do whatever. - * - * Same call semantics as realloc with regard to NULL and zeros - */ -extern void* egg_memory_fallback (void *p, size_t length); -#define EGG_SECURE_GLIB_DEFINITIONS() \ +typedef struct { + void (* lock) (void); + void (* unlock) (void); + void * (* fallback) (void *pointer, + size_t length); + void * pool_data; + const char * pool_version; +} egg_secure_glob; + +#define EGG_SECURE_POOL_VER_STR "1.0" +#define EGG_SECURE_GLOBALS SECMEM_pool_data_v1_0 + +#define EGG_SECURE_DEFINE_GLOBALS(lock, unlock, fallback) \ + egg_secure_glob EGG_SECURE_GLOBALS = { \ + lock, unlock, fallback, NULL, EGG_SECURE_POOL_VER_STR }; + +#define EGG_SECURE_DEFINE_GLIB_GLOBALS() \ static GStaticMutex memory_mutex = G_STATIC_MUTEX_INIT; \ - void egg_memory_lock (void) \ + static void egg_memory_lock (void) \ { g_static_mutex_lock (&memory_mutex); } \ - void egg_memory_unlock (void) \ + static void egg_memory_unlock (void) \ { g_static_mutex_unlock (&memory_mutex); } \ - void* egg_memory_fallback (void *p, size_t sz) \ - { return g_realloc (p, sz); } \ + EGG_SECURE_DEFINE_GLOBALS (egg_memory_lock, egg_memory_unlock, g_realloc); + +extern egg_secure_glob EGG_SECURE_GLOBALS; /* * Main functionality diff --git a/egg/tests/test-dh.c b/egg/tests/test-dh.c index ba9fcfc..a676f93 100644 --- a/egg/tests/test-dh.c +++ b/egg/tests/test-dh.c @@ -34,7 +34,7 @@ #include <glib.h> #include <gcrypt.h> -EGG_SECURE_GLIB_DEFINITIONS (); +EGG_SECURE_DEFINE_GLIB_GLOBALS (); static void test_perform (void) diff --git a/egg/tests/test-hkdf.c b/egg/tests/test-hkdf.c index 93f16df..d8002f4 100644 --- a/egg/tests/test-hkdf.c +++ b/egg/tests/test-hkdf.c @@ -33,7 +33,17 @@ #include <gcrypt.h> -EGG_SECURE_GLIB_DEFINITIONS (); +/* + static GStaticMutex memory_mutex = G_STATIC_MUTEX_INIT; + static void egg_memory_lock (void) + { g_static_mutex_lock (&memory_mutex); } + static void egg_memory_unlock (void) + { g_static_mutex_unlock (&memory_mutex); } + EGG_SECURE_DEFINE_GLOBALS (egg_memory_lock, egg_memory_unlock, g_realloc); +*/ + +EGG_SECURE_DEFINE_GLIB_GLOBALS (); + static void test_hkdf_test_case_1 (void) diff --git a/egg/tests/test-openssl.c b/egg/tests/test-openssl.c index 6c39496..87596fd 100644 --- a/egg/tests/test-openssl.c +++ b/egg/tests/test-openssl.c @@ -38,7 +38,7 @@ #include <egg/egg-bytes.h> -EGG_SECURE_GLIB_DEFINITIONS (); +EGG_SECURE_DEFINE_GLIB_GLOBALS (); typedef struct { EggBytes *input; diff --git a/egg/tests/test-secmem.c b/egg/tests/test-secmem.c index 3a66fc4..e0b6e24 100644 --- a/egg/tests/test-secmem.c +++ b/egg/tests/test-secmem.c @@ -32,7 +32,7 @@ #include <string.h> -EGG_SECURE_GLIB_DEFINITIONS (); +EGG_SECURE_DEFINE_GLIB_GLOBALS (); /* Declared in egg-secure-memory.c */ extern int egg_secure_warnings; diff --git a/egg/tests/test-symkey.c b/egg/tests/test-symkey.c index 409ec44..b4c1e2d 100644 --- a/egg/tests/test-symkey.c +++ b/egg/tests/test-symkey.c @@ -33,7 +33,7 @@ #include <stdio.h> #include <string.h> -EGG_SECURE_GLIB_DEFINITIONS (); +EGG_SECURE_DEFINE_GLIB_GLOBALS (); static const struct { const gchar *password; diff --git a/gck/Makefile.am b/gck/Makefile.am index 9d83836..aab5feb 100644 --- a/gck/Makefile.am +++ b/gck/Makefile.am @@ -63,10 +63,11 @@ libgck_@GCK_MAJOR@_la_SOURCES = \ libgck_@GCK_MAJOR@_la_LDFLAGS = \ -version-info $(GCK_LT_RELEASE) \ -no-undefined \ - -export-symbols-regex '^gck_*' + -export-symbols-regex '^gck_.*|^SECMEM_.*' libgck_@GCK_MAJOR@_la_LIBADD = \ $(top_builddir)/egg/libegg-hex.la \ + $(top_builddir)/egg/libegg-secmem.la \ $(P11_KIT_LIBS) \ $(GTHREAD_LIBS) \ $(GIO_LIBS) \ diff --git a/gck/gck-misc.c b/gck/gck-misc.c index 47d444e..1049142 100644 --- a/gck/gck-misc.c +++ b/gck/gck-misc.c @@ -26,10 +26,14 @@ #include "gck.h" #include "gck-private.h" +#include "egg/egg-secure-memory.h" + #include <p11-kit/p11-kit.h> #include <glib/gi18n-lib.h> +EGG_SECURE_DEFINE_GLIB_GLOBALS (); + /** * SECTION:gck-error * @title: Errors diff --git a/gck/gck.symbols b/gck/gck.symbols index d3aef3e..8d18816 100644 --- a/gck/gck.symbols +++ b/gck/gck.symbols @@ -257,3 +257,4 @@ gck_uri_get_error_quark gck_uri_parse gck_value_to_boolean gck_value_to_ulong +SECMEM_pool_data_v1_0
\ No newline at end of file diff --git a/gcr/Makefile.am b/gcr/Makefile.am index 924056c..544063e 100644 --- a/gcr/Makefile.am +++ b/gcr/Makefile.am @@ -190,7 +190,7 @@ libgcr_@GCR_MAJOR@_la_CFLAGS = \ libgcr_base_@GCR_MAJOR@_la_LDFLAGS = \ -version-info $(GCR_LT_RELEASE) \ -no-undefined \ - -export-symbols-regex '^gcr_*' + -export-symbols-regex '^gcr_.*|^SECMEM_.*' libgcr_@GCR_MAJOR@_la_LDFLAGS = \ $(libgcr_base_@GCR_MAJOR@_la_LDFLAGS) diff --git a/gcr/gcr-memory.c b/gcr/gcr-memory.c index 04d216d..0e378a4 100644 --- a/gcr/gcr-memory.c +++ b/gcr/gcr-memory.c @@ -25,68 +25,4 @@ #include <glib.h> -/* ----------------------------------------------------------------------------- - * MEMORY - */ - -static gboolean do_warning = TRUE; -#define WARNING "couldn't allocate secure memory to keep passwords " \ - "and or keys from being written to the disk" - -#define ABORTMSG "The GNOME_KEYRING_PARANOID environment variable was set. " \ - "Exiting..." - -static G_LOCK_DEFINE (memory_lock); - -/* - * These are called from egg-secure-memory.c to provide appropriate - * locking for memory between threads - */ - -void -egg_memory_lock (void) -{ - G_LOCK (memory_lock); -} - -void -egg_memory_unlock (void) -{ - G_UNLOCK (memory_lock); -} - -void* -egg_memory_fallback (void *p, size_t sz) -{ - const gchar *env; - - /* We were asked to free memory */ - if (!sz) { - g_free (p); - return NULL; - } - - /* We were asked to allocate */ - if (!p) { - if (do_warning) { - g_message (WARNING); - do_warning = FALSE; - } - - env = g_getenv ("GNOME_KEYRING_PARANOID"); - if (env && *env) - g_error (ABORTMSG); - - return g_malloc0 (sz); - } - - /* - * Reallocation is a bit of a gray area, as we can be asked - * by external libraries (like libgcrypt) to reallocate a - * non-secure block into secure memory. We cannot satisfy - * this request (as we don't know the size of the original - * block) so we just try our best here. - */ - - return g_realloc (p, sz); -} +EGG_SECURE_DEFINE_GLIB_GLOBALS (); |