summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--egg/Makefile.am4
-rw-r--r--egg/egg-secure-memory.c69
-rw-r--r--egg/egg-secure-memory.h42
-rw-r--r--egg/tests/test-dh.c2
-rw-r--r--egg/tests/test-hkdf.c12
-rw-r--r--egg/tests/test-openssl.c2
-rw-r--r--egg/tests/test-secmem.c2
-rw-r--r--egg/tests/test-symkey.c2
-rw-r--r--gck/Makefile.am3
-rw-r--r--gck/gck-misc.c4
-rw-r--r--gck/gck.symbols1
-rw-r--r--gcr/Makefile.am2
-rw-r--r--gcr/gcr-memory.c66
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 ();