summaryrefslogtreecommitdiff
path: root/egg
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-12-05 14:31:39 +0100
committerStef Walter <stefw@collabora.co.uk>2011-12-08 20:13:45 +0100
commit007f81cb2856fdfa8879e39f8032057e521867b4 (patch)
tree2ddeebf2d49a5b56682fa7af8bfb4c93f47d5e85 /egg
parenta16ba63c2d0d7018fcd19ec895160fe44fd6b8ca (diff)
downloadgcr-007f81cb2856fdfa8879e39f8032057e521867b4.tar.gz
egg: Make secure memory pool shared across modules
* The globals for the secure memory pool need to be shared across linked modules. So that for example gck, gcr, and gsecret libraries can share the same pool, even though code is compiled into each library. * There's versioning so they'll only work with each other if they all share the same code.
Diffstat (limited to 'egg')
-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
8 files changed, 80 insertions, 55 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;