summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059>2013-11-11 03:19:22 +0800
committergusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059>2013-11-11 03:19:22 +0800
commitdafa386080bf73269d65a238868235dddef47c63 (patch)
tree3317a5cd1b9959b4285d9f376f9cd9168a5b9f51
parentf45a3e8bcb9a8d79f1d6b9f786f7b86b5cf38f2f (diff)
downloadmarcuscom-ports-dafa386080bf73269d65a238868235dddef47c63.tar
marcuscom-ports-dafa386080bf73269d65a238868235dddef47c63.tar.gz
marcuscom-ports-dafa386080bf73269d65a238868235dddef47c63.tar.bz2
marcuscom-ports-dafa386080bf73269d65a238868235dddef47c63.tar.lz
marcuscom-ports-dafa386080bf73269d65a238868235dddef47c63.tar.xz
marcuscom-ports-dafa386080bf73269d65a238868235dddef47c63.tar.zst
marcuscom-ports-dafa386080bf73269d65a238868235dddef47c63.zip
Bring in some patches from OpenBSD [1]. Those fix a problem accessing the gnome keyring, which caused gnome-shell to crash and respawn.
Tested by: rut on #freebsd-gnone, gusi Reviewed by: kwm, gusi [1] thanks to ajacoutot (ajacoutot@openbsd.org) on #freebsd-gnome git-svn-id: svn://creme-brulee.marcuscom.com/ports/trunk@18875 df743ca5-7f9a-e211-a948-0013205c9059
-rw-r--r--security/gcr/files/patch-egg_egg-secure-memory.c959
-rw-r--r--security/gcr/files/patch-egg_egg-secure-memory.h75
-rw-r--r--security/gnome-keyring3/files/patch-egg_egg-secure-memory.c959
-rw-r--r--security/gnome-keyring3/files/patch-egg_egg-secure-memory.h75
-rw-r--r--security/gnome-keyring3/files/patch-egg_tests_test-secmem.c66
-rw-r--r--security/libgnome-keyring/files/patch-egg_egg-dh.c11
-rw-r--r--security/libgnome-keyring/files/patch-egg_egg-libgcrypt.c11
-rw-r--r--security/libgnome-keyring/files/patch-egg_egg-secure-memory.c966
-rw-r--r--security/libgnome-keyring/files/patch-egg_egg-secure-memory.h107
-rw-r--r--security/libgnome-keyring/files/patch-egg_tests_Makefile.in10
-rw-r--r--security/libgnome-keyring/files/patch-egg_tests_test-dh.c11
-rw-r--r--security/libgnome-keyring/files/patch-egg_tests_test-hkdf.c11
-rw-r--r--security/libgnome-keyring/files/patch-egg_tests_test-secmem.c167
-rw-r--r--security/libgnome-keyring/files/patch-library_Makefile.in11
-rw-r--r--security/libgnome-keyring/files/patch-library_gkr-session.c11
-rw-r--r--security/libgnome-keyring/files/patch-library_gnome-keyring-memory.c81
-rw-r--r--security/libgnome-keyring/files/patch-library_gnome-keyring-utils.c11
-rw-r--r--security/libgnome-keyring/files/patch-library_gnome-keyring.c11
18 files changed, 3553 insertions, 0 deletions
diff --git a/security/gcr/files/patch-egg_egg-secure-memory.c b/security/gcr/files/patch-egg_egg-secure-memory.c
new file mode 100644
index 000000000..1f64ec729
--- /dev/null
+++ b/security/gcr/files/patch-egg_egg-secure-memory.c
@@ -0,0 +1,959 @@
+--- egg/egg-secure-memory.c.orig Wed Sep 19 11:01:27 2012
++++ egg/egg-secure-memory.c Sat Oct 27 14:41:49 2012
+@@ -22,8 +22,8 @@
+ */
+
+ /*
+- * IMPORTANT: This is pure vanila standard C, no glib. We need this
+- * because certain consumers of this protocol need to be built
++ * IMPORTANT: This is pure vanila standard C, no glib. We need this
++ * because certain consumers of this protocol need to be built
+ * without linking in any special libraries. ie: the PKCS#11 module.
+ */
+
+@@ -48,8 +48,8 @@
+
+ #define DEBUG_SECURE_MEMORY 0
+
+-#if DEBUG_SECURE_MEMORY
+-#define DEBUG_ALLOC(msg, n) fprintf(stderr, "%s %lu bytes\n", msg, n);
++#if DEBUG_SECURE_MEMORY
++#define DEBUG_ALLOC(msg, n) fprintf(stderr, "%s %lu bytes\n", msg, n);
+ #else
+ #define DEBUG_ALLOC(msg, n)
+ #endif
+@@ -59,8 +59,8 @@
+ /* Use our own assert to guarantee no glib allocations */
+ #ifndef ASSERT
+ #ifdef G_DISABLE_ASSERT
+-#define ASSERT(x)
+-#else
++#define ASSERT(x)
++#else
+ #define ASSERT(x) assert(x)
+ #endif
+ #endif
+@@ -74,18 +74,18 @@
+ static int show_warning = 1;
+ int egg_secure_warnings = 1;
+
+-/*
+- * We allocate all memory in units of sizeof(void*). This
++/*
++ * We allocate all memory in units of sizeof(void*). This
+ * is our definition of 'word'.
+ */
+ typedef void* word_t;
+
+-/* The amount of extra words we can allocate */
++/* The amount of extra words we can allocate */
+ #define WASTE 4
+
+-/*
+- * Track allocated memory or a free block. This structure is not stored
+- * in the secure memory area. It is allocated from a pool of other
++/*
++ * Track allocated memory or a free block. This structure is not stored
++ * in the secure memory area. It is allocated from a pool of other
+ * memory. See meta_pool_xxx ().
+ */
+ typedef struct _Cell {
+@@ -97,7 +97,7 @@ typedef struct _Cell {
+ struct _Cell *prev; /* Previous in memory ring */
+ } Cell;
+
+-/*
++/*
+ * A block of secure memory. This structure is the header in that block.
+ */
+ typedef struct _Block {
+@@ -130,20 +130,20 @@ unused_pop (void **stack)
+ ptr = *stack;
+ *stack = *(void**)ptr;
+ return ptr;
+-
++
+ }
+
+ static inline void*
+ unused_peek (void **stack)
+ {
+ ASSERT (stack);
+- return *stack;
++ return *stack;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * POOL META DATA ALLOCATION
+- *
+- * A pool for memory meta data. We allocate fixed size blocks. There are actually
++ *
++ * A pool for memory meta data. We allocate fixed size blocks. There are actually
+ * two different structures stored in this pool: Cell and Block. Cell is allocated
+ * way more often, and is bigger so we just allocate that size for both.
+ */
+@@ -185,7 +185,7 @@ pool_alloc (void)
+ if (unused_peek (&pool->unused))
+ break;
+ }
+-
++
+ /* Create a new pool */
+ if (pool == NULL) {
+ len = getpagesize () * 2;
+@@ -205,7 +205,7 @@ pool_alloc (void)
+ pool->n_items = (len - sizeof (Pool)) / sizeof (Item);
+ for (i = 0; i < pool->n_items; ++i)
+ unused_push (&pool->unused, pool->items + i);
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_CREATE_MEMPOOL(pool, 0, 0);
+ #endif
+@@ -227,9 +227,9 @@ pool_free (void* item)
+ {
+ Pool *pool, **at;
+ char *ptr, *beg, *end;
+-
++
+ ptr = item;
+-
++
+ /* Find which block this one belongs to */
+ for (at = (Pool **)&EGG_SECURE_GLOBALS.pool_data, pool = *at;
+ pool != NULL; at = &pool->next, pool = *at) {
+@@ -275,17 +275,17 @@ pool_valid (void* item)
+ {
+ Pool *pool;
+ char *ptr, *beg, *end;
+-
++
+ ptr = item;
+-
++
+ /* Find which block this one belongs to */
+ 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)
++ if (ptr >= beg && ptr <= end)
+ return (pool->used && (ptr - beg) % sizeof (Item) == 0);
+ }
+-
++
+ return 0;
+ }
+
+@@ -293,9 +293,9 @@ pool_valid (void* item)
+
+ /* -----------------------------------------------------------------------------
+ * SEC ALLOCATION
+- *
++ *
+ * Each memory cell begins and ends with a pointer to its metadata. These are also
+- * used as guards or red zones. Since they're treated as redzones by valgrind we
++ * used as guards or red zones. Since they're treated as redzones by valgrind we
+ * have to jump through a few hoops before reading and/or writing them.
+ */
+
+@@ -315,11 +315,11 @@ sec_write_guards (Cell *cell)
+
+ ((void**)cell->words)[0] = (void*)cell;
+ ((void**)cell->words)[cell->n_words - 1] = (void*)cell;
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS (cell->words, sizeof (word_t));
+ VALGRIND_MAKE_MEM_NOACCESS (cell->words + cell->n_words - 1, sizeof (word_t));
+-#endif
++#endif
+ }
+
+ static inline void
+@@ -327,16 +327,16 @@ sec_check_guards (Cell *cell)
+ {
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (cell->words, sizeof (word_t));
+- VALGRIND_MAKE_MEM_DEFINED (cell->words + cell->n_words - 1, sizeof (word_t));
+-#endif
+-
++ VALGRIND_MAKE_MEM_DEFINED (cell->words + cell->n_words - 1, sizeof (word_t));
++#endif
++
+ ASSERT(((void**)cell->words)[0] == (void*)cell);
+ ASSERT(((void**)cell->words)[cell->n_words - 1] == (void*)cell);
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS (cell->words, sizeof (word_t));
+ VALGRIND_MAKE_MEM_NOACCESS (cell->words + cell->n_words - 1, sizeof (word_t));
+-#endif
++#endif
+ }
+
+ static void
+@@ -347,9 +347,9 @@ sec_insert_cell_ring (Cell **ring, Cell *cell)
+ ASSERT (cell != *ring);
+ ASSERT (cell->next == NULL);
+ ASSERT (cell->prev == NULL);
+-
+- /* Insert back into the mix of available memory */
+- if (*ring) {
++
++ /* Insert back into the mix of available memory */
++ if (*ring) {
+ cell->next = (*ring)->next;
+ cell->prev = *ring;
+ cell->next->prev = cell;
+@@ -358,7 +358,7 @@ sec_insert_cell_ring (Cell **ring, Cell *cell)
+ cell->next = cell;
+ cell->prev = cell;
+ }
+-
++
+ *ring = cell;
+ ASSERT (cell->next->prev == cell);
+ ASSERT (cell->prev->next == cell);
+@@ -391,7 +391,7 @@ sec_remove_cell_ring (Cell **ring, Cell *cell)
+ cell->next->prev = cell->prev;
+ cell->prev->next = cell->next;
+ cell->next = cell->prev = NULL;
+-
++
+ ASSERT (*ring != cell);
+ }
+
+@@ -440,10 +440,10 @@ static Cell*
+ sec_neighbor_before (Block *block, Cell *cell)
+ {
+ word_t *word;
+-
++
+ ASSERT (cell);
+ ASSERT (block);
+-
++
+ word = cell->words - 1;
+ if (!sec_is_valid_word (block, word))
+ return NULL;
+@@ -451,7 +451,7 @@ sec_neighbor_before (Block *block, Cell *cell)
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (word, sizeof (word_t));
+ #endif
+-
++
+ cell = *word;
+ sec_check_guards (cell);
+
+@@ -462,14 +462,14 @@ sec_neighbor_before (Block *block, Cell *cell)
+ return cell;
+ }
+
+-static Cell*
++static Cell*
+ sec_neighbor_after (Block *block, Cell *cell)
+ {
+ word_t *word;
+-
++
+ ASSERT (cell);
+ ASSERT (block);
+-
++
+ word = cell->words + cell->n_words;
+ if (!sec_is_valid_word (block, word))
+ return NULL;
+@@ -480,7 +480,7 @@ sec_neighbor_after (Block *block, Cell *cell)
+
+ cell = *word;
+ sec_check_guards (cell);
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS (word, sizeof (word_t));
+ #endif
+@@ -496,7 +496,7 @@ sec_alloc (Block *block,
+ Cell *cell, *other;
+ size_t n_words;
+ void *memory;
+-
++
+ ASSERT (block);
+ ASSERT (length);
+ ASSERT (tag);
+@@ -504,16 +504,16 @@ sec_alloc (Block *block,
+ if (!block->unused_cells)
+ return NULL;
+
+- /*
+- * Each memory allocation is aligned to a pointer size, and
++ /*
++ * Each memory allocation is aligned to a pointer size, and
+ * then, sandwidched between two pointers to its meta data.
+ * These pointers also act as guards.
+ *
+- * We allocate memory in units of sizeof (void*)
++ * We allocate memory in units of sizeof (void*)
+ */
+-
++
+ n_words = sec_size_to_words (length) + 2;
+-
++
+ /* Look for a cell of at least our required size */
+ cell = block->unused_cells;
+ while (cell->n_words < n_words) {
+@@ -523,7 +523,7 @@ sec_alloc (Block *block,
+ break;
+ }
+ }
+-
++
+ if (!cell)
+ return NULL;
+
+@@ -532,7 +532,7 @@ sec_alloc (Block *block,
+ ASSERT (cell->prev);
+ ASSERT (cell->words);
+ sec_check_guards (cell);
+-
++
+ /* Steal from the cell if it's too long */
+ if (cell->n_words > n_words + WASTE) {
+ other = pool_alloc ();
+@@ -542,13 +542,13 @@ sec_alloc (Block *block,
+ other->words = cell->words;
+ cell->n_words -= n_words;
+ cell->words += n_words;
+-
++
+ sec_write_guards (other);
+ sec_write_guards (cell);
+-
++
+ cell = other;
+ }
+-
++
+ if (cell->next)
+ sec_remove_cell_ring (&block->unused_cells, cell);
+
+@@ -557,11 +557,11 @@ sec_alloc (Block *block,
+ cell->requested = length;
+ sec_insert_cell_ring (&block->used_cells, cell);
+ memory = sec_cell_to_memory (cell);
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_UNDEFINED (memory, length);
+ #endif
+-
++
+ return memset (memory, 0, length);
+ }
+
+@@ -570,13 +570,13 @@ sec_free (Block *block, void *memory)
+ {
+ Cell *cell, *other;
+ word_t *word;
+-
++
+ ASSERT (block);
+ ASSERT (memory);
+-
++
+ word = memory;
+ --word;
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (word, sizeof (word_t));
+ #endif
+@@ -600,39 +600,39 @@ sec_free (Block *block, void *memory)
+ /* Remove from the used cell ring */
+ sec_remove_cell_ring (&block->used_cells, cell);
+
+- /* Find previous unallocated neighbor, and merge if possible */
+- other = sec_neighbor_before (block, cell);
+- if (other && other->requested == 0) {
+- ASSERT (other->tag == NULL);
+- ASSERT (other->next && other->prev);
+- other->n_words += cell->n_words;
+- sec_write_guards (other);
+- pool_free (cell);
+- cell = other;
+- }
+-
+- /* Find next unallocated neighbor, and merge if possible */
+- other = sec_neighbor_after (block, cell);
+- if (other && other->requested == 0) {
+- ASSERT (other->tag == NULL);
+- ASSERT (other->next && other->prev);
+- other->n_words += cell->n_words;
+- other->words = cell->words;
+- if (cell->next)
+- sec_remove_cell_ring (&block->unused_cells, cell);
+- sec_write_guards (other);
+- pool_free (cell);
+- cell = other;
+- }
++ /* Find previous unallocated neighbor, and merge if possible */
++ other = sec_neighbor_before (block, cell);
++ if (other && other->requested == 0) {
++ ASSERT (other->tag == NULL);
++ ASSERT (other->next && other->prev);
++ other->n_words += cell->n_words;
++ sec_write_guards (other);
++ pool_free (cell);
++ cell = other;
++ }
+
+- /* Add to the unused list if not already there */
+- if (!cell->next)
+- sec_insert_cell_ring (&block->unused_cells, cell);
++ /* Find next unallocated neighbor, and merge if possible */
++ other = sec_neighbor_after (block, cell);
++ if (other && other->requested == 0) {
++ ASSERT (other->tag == NULL);
++ ASSERT (other->next && other->prev);
++ other->n_words += cell->n_words;
++ other->words = cell->words;
++ if (cell->next)
++ sec_remove_cell_ring (&block->unused_cells, cell);
++ sec_write_guards (other);
++ pool_free (cell);
++ cell = other;
++ }
+
+- cell->tag = NULL;
+- cell->requested = 0;
+- --block->n_used;
+- return NULL;
++ /* Add to the unused list if not already there */
++ if (!cell->next)
++ sec_insert_cell_ring (&block->unused_cells, cell);
++
++ cell->tag = NULL;
++ cell->requested = 0;
++ --block->n_used;
++ return NULL;
+ }
+
+ static void
+@@ -683,7 +683,7 @@ sec_realloc (Block *block,
+ /* Dig out where the meta should be */
+ word = memory;
+ --word;
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (word, sizeof (word_t));
+ #endif
+@@ -691,7 +691,7 @@ sec_realloc (Block *block,
+ ASSERT (sec_is_valid_word (block, word));
+ ASSERT (pool_valid (*word));
+ cell = *word;
+-
++
+ /* Validate that it's actually for real */
+ sec_check_guards (cell);
+ ASSERT (cell->requested > 0);
+@@ -710,17 +710,17 @@ sec_realloc (Block *block,
+ cell->requested = length;
+ alloc = sec_cell_to_memory (cell);
+
+- /*
++ /*
+ * Even though we may be reusing the same cell, that doesn't
+ * mean that the allocation is shrinking. It could have shrunk
+- * and is now expanding back some.
+- */
++ * and is now expanding back some.
++ */
+ if (length < valid)
+ sec_clear_undefined (alloc, length, valid);
+
+ return alloc;
+ }
+-
++
+ /* Need braaaaaiiiiiinsss... */
+ while (cell->n_words < n_words) {
+
+@@ -728,7 +728,7 @@ sec_realloc (Block *block,
+ other = sec_neighbor_after (block, cell);
+ if (!other || other->requested != 0)
+ break;
+-
++
+ /* Eat the whole neighbor if not too big */
+ if (n_words - cell->n_words + WASTE >= other->n_words) {
+ cell->n_words += other->n_words;
+@@ -745,7 +745,7 @@ sec_realloc (Block *block,
+ sec_write_guards (cell);
+ }
+ }
+-
++
+ if (cell->n_words >= n_words) {
+ cell->requested = length;
+ cell->tag = tag;
+@@ -760,7 +760,7 @@ sec_realloc (Block *block,
+ memcpy_with_vbits (alloc, memory, valid);
+ sec_free (block, memory);
+ }
+-
++
+ return alloc;
+ }
+
+@@ -770,7 +770,7 @@ sec_allocated (Block *block, void *memory)
+ {
+ Cell *cell;
+ word_t *word;
+-
++
+ ASSERT (block);
+ ASSERT (memory);
+
+@@ -780,12 +780,12 @@ sec_allocated (Block *block, void *memory)
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (word, sizeof (word_t));
+ #endif
+-
++
+ /* Lookup the meta for this memory block (using guard pointer) */
+ ASSERT (sec_is_valid_word (block, word));
+ ASSERT (pool_valid (*word));
+ cell = *word;
+-
++
+ sec_check_guards (cell);
+ ASSERT (cell->requested > 0);
+ ASSERT (cell->tag != NULL);
+@@ -817,10 +817,10 @@ sec_validate (Block *block)
+ ASSERT (sec_is_valid_word (block, word));
+ ASSERT (pool_valid (*word));
+ cell = *word;
+-
++
+ /* Validate that it's actually for real */
+ sec_check_guards (cell);
+-
++
+ /* Is it an allocated block? */
+ if (cell->requested > 0) {
+ ASSERT (cell->tag != NULL);
+@@ -829,7 +829,7 @@ sec_validate (Block *block)
+ ASSERT (cell->next->prev == cell);
+ ASSERT (cell->prev->next == cell);
+ ASSERT (cell->requested <= (cell->n_words - 2) * sizeof (word_t));
+-
++
+ /* An unused block */
+ } else {
+ ASSERT (cell->tag == NULL);
+@@ -838,7 +838,7 @@ sec_validate (Block *block)
+ ASSERT (cell->next->prev == cell);
+ ASSERT (cell->prev->next == cell);
+ }
+-
++
+ word += cell->n_words;
+ if (word == last)
+ break;
+@@ -855,7 +855,7 @@ sec_acquire_pages (size_t *sz,
+ {
+ void *pages;
+ unsigned long pgsize;
+-
++
+ ASSERT (sz);
+ ASSERT (*sz);
+ ASSERT (during_tag);
+@@ -863,7 +863,7 @@ sec_acquire_pages (size_t *sz,
+ /* Make sure sz is a multiple of the page size */
+ pgsize = getpagesize ();
+ *sz = (*sz + pgsize -1) & ~(pgsize - 1);
+-
++
+ #if defined(HAVE_MLOCK)
+ pages = mmap (0, *sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (pages == MAP_FAILED) {
+@@ -873,7 +873,7 @@ sec_acquire_pages (size_t *sz,
+ show_warning = 0;
+ return NULL;
+ }
+-
++
+ if (mlock (pages, *sz) < 0) {
+ if (show_warning && egg_secure_warnings && errno != EPERM) {
+ fprintf (stderr, "couldn't lock %lu bytes of memory (%s): %s\n",
+@@ -883,12 +883,12 @@ sec_acquire_pages (size_t *sz,
+ munmap (pages, *sz);
+ return NULL;
+ }
+-
++
+ DEBUG_ALLOC ("gkr-secure-memory: new block ", *sz);
+-
++
+ show_warning = 1;
+ return pages;
+-
++
+ #else
+ if (show_warning && egg_secure_warnings)
+ fprintf (stderr, "your system does not support private memory");
+@@ -898,21 +898,21 @@ sec_acquire_pages (size_t *sz,
+
+ }
+
+-static void
++static void
+ sec_release_pages (void *pages, size_t sz)
+ {
+ ASSERT (pages);
+ ASSERT (sz % getpagesize () == 0);
+-
++
+ #if defined(HAVE_MLOCK)
+ if (munlock (pages, sz) < 0 && egg_secure_warnings)
+ fprintf (stderr, "couldn't unlock private memory: %s\n", strerror (errno));
+-
++
+ if (munmap (pages, sz) < 0 && egg_secure_warnings)
+ fprintf (stderr, "couldn't unmap private anonymous memory: %s\n", strerror (errno));
+-
++
+ DEBUG_ALLOC ("gkr-secure-memory: freed block ", sz);
+-
++
+ #else
+ ASSERT (FALSE);
+ #endif
+@@ -924,7 +924,7 @@ sec_release_pages (void *pages, size_t sz)
+
+ static Block *all_blocks = NULL;
+
+-static Block*
++static Block*
+ sec_block_create (size_t size,
+ const char *during_tag)
+ {
+@@ -950,7 +950,7 @@ sec_block_create (size_t size,
+ /* The size above is a minimum, we're free to go bigger */
+ if (size < DEFAULT_BLOCK_SIZE)
+ size = DEFAULT_BLOCK_SIZE;
+-
++
+ block->words = sec_acquire_pages (&size, during_tag);
+ block->n_words = size / sizeof (word_t);
+ if (!block->words) {
+@@ -958,11 +958,11 @@ sec_block_create (size_t size,
+ pool_free (cell);
+ return NULL;
+ }
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (block->words, size);
+ #endif
+-
++
+ /* The first cell to allocate from */
+ cell->words = block->words;
+ cell->n_words = block->n_words;
+@@ -972,7 +972,7 @@ sec_block_create (size_t size,
+
+ block->next = all_blocks;
+ all_blocks = block;
+-
++
+ return block;
+ }
+
+@@ -985,7 +985,7 @@ sec_block_destroy (Block *block)
+ ASSERT (block);
+ ASSERT (block->words);
+ ASSERT (block->n_used == 0);
+-
++
+ /* Remove from the list */
+ for (at = &all_blocks, bl = *at; bl; at = &bl->next, bl = *at) {
+ if (bl == block) {
+@@ -993,7 +993,7 @@ sec_block_destroy (Block *block)
+ break;
+ }
+ }
+-
++
+ /* Must have been found */
+ ASSERT (bl == block);
+ ASSERT (block->used_cells == NULL);
+@@ -1004,7 +1004,7 @@ sec_block_destroy (Block *block)
+ sec_remove_cell_ring (&block->unused_cells, cell);
+ pool_free (cell);
+ }
+-
++
+ /* Release all pages of secure memory */
+ sec_release_pages (block->words, block->n_words * sizeof (word_t));
+
+@@ -1028,35 +1028,35 @@ egg_secure_alloc_full (const char *tag,
+
+ if (length > 0xFFFFFFFF / 2) {
+ if (egg_secure_warnings)
+- fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
+- (unsigned long)length);
++ fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
++ (unsigned long)length);
+ return NULL;
+ }
+
+ /* Can't allocate zero bytes */
+ if (length == 0)
+ return NULL;
+-
++
+ DO_LOCK ();
+-
++
+ for (block = all_blocks; block; block = block->next) {
+ memory = sec_alloc (block, tag, length);
+ if (memory)
+- break;
++ break;
+ }
+-
++
+ /* None of the current blocks have space, allocate new */
+ if (!memory) {
+ block = sec_block_create (length, tag);
+ if (block)
+ memory = sec_alloc (block, tag, length);
+ }
+-
++
+ #ifdef WITH_VALGRIND
+ if (memory != NULL)
+ VALGRIND_MALLOCLIKE_BLOCK (memory, length, sizeof (void*), 1);
+ #endif
+-
++
+ DO_UNLOCK ();
+
+ if (!memory && (flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback != NULL) {
+@@ -1064,10 +1064,10 @@ egg_secure_alloc_full (const char *tag,
+ if (memory) /* Our returned memory is always zeroed */
+ memset (memory, 0, length);
+ }
+-
++
+ if (!memory)
+ errno = ENOMEM;
+-
++
+ return memory;
+ }
+
+@@ -1087,20 +1087,20 @@ egg_secure_realloc_full (const char *tag,
+
+ if (length > 0xFFFFFFFF / 2) {
+ if (egg_secure_warnings)
+- fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
++ fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
+ (unsigned long)length);
+ return NULL;
+ }
+-
++
+ if (memory == NULL)
+ return egg_secure_alloc_full (tag, length, flags);
+ if (!length) {
+ egg_secure_free_full (memory, flags);
+ return NULL;
+ }
+-
++
+ DO_LOCK ();
+-
++
+ /* Find out where it belongs to */
+ for (block = all_blocks; block; block = block->next) {
+ if (sec_is_valid_word (block, memory)) {
+@@ -1115,10 +1115,10 @@ egg_secure_realloc_full (const char *tag,
+
+ #ifdef WITH_VALGRIND
+ /* Now tell valgrind about either the new block or old one */
+- VALGRIND_MALLOCLIKE_BLOCK (alloc ? alloc : memory,
+- alloc ? length : previous,
++ VALGRIND_MALLOCLIKE_BLOCK (alloc ? alloc : memory,
++ alloc ? length : previous,
+ sizeof (word_t), 1);
+-#endif
++#endif
+ break;
+ }
+ }
+@@ -1129,13 +1129,13 @@ egg_secure_realloc_full (const char *tag,
+
+ if (block && block->n_used == 0)
+ sec_block_destroy (block);
+-
+- DO_UNLOCK ();
+-
++
++ DO_UNLOCK ();
++
+ if (!block) {
+ if ((flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback) {
+- /*
+- * In this case we can't zero the returned memory,
++ /*
++ * In this case we can't zero the returned memory,
+ * because we don't know what the block size was.
+ */
+ return EGG_SECURE_GLOBALS.fallback (memory, length);
+@@ -1155,7 +1155,7 @@ egg_secure_realloc_full (const char *tag,
+ egg_secure_free_full (memory, flags);
+ }
+ }
+-
++
+ if (!alloc)
+ errno = ENOMEM;
+
+@@ -1172,12 +1172,12 @@ void
+ egg_secure_free_full (void *memory, int flags)
+ {
+ Block *block = NULL;
+-
++
+ if (memory == NULL)
+ return;
+-
++
+ DO_LOCK ();
+-
++
+ /* Find out where it belongs to */
+ for (block = all_blocks; block; block = block->next) {
+ if (sec_is_valid_word (block, memory))
+@@ -1195,9 +1195,9 @@ egg_secure_free_full (void *memory, int flags)
+ if (block->n_used == 0)
+ sec_block_destroy (block);
+ }
+-
++
+ DO_UNLOCK ();
+-
++
+ if (!block) {
+ if ((flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback) {
+ EGG_SECURE_GLOBALS.fallback (memory, 0);
+@@ -1208,36 +1208,36 @@ egg_secure_free_full (void *memory, int flags)
+ ASSERT (0 && "memory does does not belong to secure memory pool");
+ }
+ }
+-}
++}
+
+-int
++int
+ egg_secure_check (const void *memory)
+ {
+ Block *block = NULL;
+
+ DO_LOCK ();
+-
++
+ /* Find out where it belongs to */
+ for (block = all_blocks; block; block = block->next) {
+ if (sec_is_valid_word (block, (word_t*)memory))
+ break;
+ }
+-
++
+ DO_UNLOCK ();
+-
++
+ return block == NULL ? 0 : 1;
+-}
++}
+
+ void
+ egg_secure_validate (void)
+ {
+ Block *block = NULL;
+-
++
+ DO_LOCK ();
+-
++
+ for (block = all_blocks; block; block = block->next)
+ sec_validate (block);
+-
++
+ DO_UNLOCK ();
+ }
+
+@@ -1320,20 +1320,42 @@ egg_secure_strdup_full (const char *tag,
+ if (!str)
+ return NULL;
+
+- len = strlen (str) + 1;
++ len = strlen (str) + 1;
+ res = (char *)egg_secure_alloc_full (tag, len, options);
+ strcpy (res, str);
+ return res;
+ }
+
++char *
++egg_secure_strndup_full (const char *tag,
++ const char *str,
++ size_t length,
++ int options)
++{
++ size_t len;
++ char *res;
++ const char *end;
++
++ if (!str)
++ return NULL;
++
++ end = memchr (str, '\0', length);
++ if (end != NULL)
++ length = (end - str);
++ len = length + 1;
++ res = (char *)egg_secure_alloc_full (tag, len, options);
++ memcpy (res, str, len);
++ return res;
++}
++
+ void
+ egg_secure_clear (void *p, size_t length)
+ {
+ volatile char *vp;
+-
++
+ if (p == NULL)
+ return;
+-
++
+ vp = (volatile char*)p;
+ while (length) {
+ *vp = 0xAA;
+@@ -1355,10 +1377,10 @@ egg_secure_strfree (char *str)
+ {
+ /*
+ * If we're using unpageable 'secure' memory, then the free call
+- * should zero out the memory, but because on certain platforms
++ * should zero out the memory, but because on certain platforms
+ * we may be using normal memory, zero it out here just in case.
+ */
+-
++
+ egg_secure_strclear (str);
+ egg_secure_free_full (str, EGG_SECURE_USE_FALLBACK);
+ }
diff --git a/security/gcr/files/patch-egg_egg-secure-memory.h b/security/gcr/files/patch-egg_egg-secure-memory.h
new file mode 100644
index 000000000..56a1607b9
--- /dev/null
+++ b/security/gcr/files/patch-egg_egg-secure-memory.h
@@ -0,0 +1,75 @@
+--- egg/egg-secure-memory.h.orig Wed Sep 19 11:01:27 2012
++++ egg/egg-secure-memory.h Sat Oct 27 14:41:49 2012
+@@ -27,16 +27,16 @@
+ #include <stdlib.h>
+
+ /* -------------------------------------------------------------------
+- * Low Level Secure Memory
+- *
+- * IMPORTANT: This is pure vanila standard C, no glib. We need this
+- * because certain consumers of this protocol need to be built
++ * Low Level Secure Memory
++ *
++ * IMPORTANT: This is pure vanila standard C, no glib. We need this
++ * because certain consumers of this protocol need to be built
+ * without linking in any special libraries. ie: the PKCS#11 module.
+- *
++ *
+ * Thread locking
+- *
++ *
+ * In order to use these functions in a module the following functions
+- * must be defined somewhere, and provide appropriate locking for
++ * must be defined somewhere, and provide appropriate locking for
+ * secure memory between threads:
+ */
+
+@@ -66,12 +66,12 @@ typedef struct {
+
+ extern egg_secure_glob EGG_SECURE_GLOBALS;
+
+-/*
++/*
+ * Main functionality
+- *
++ *
+ * Allocations return NULL on failure.
+- */
+-
++ */
++
+ #define EGG_SECURE_USE_FALLBACK 0x0001
+
+ #define EGG_SECURE_DECLARE(tag) \
+@@ -83,23 +83,28 @@ extern egg_secure_glob EGG_SECURE_GLOBALS;
+ } \
+ static inline void* egg_secure_strdup (const char *str) { \
+ return egg_secure_strdup_full (G_STRINGIFY (tag), str, EGG_SECURE_USE_FALLBACK); \
++ } \
++ static inline void* egg_secure_strndup (const char *str, size_t length) { \
++ return egg_secure_strndup_full (G_STRINGIFY (tag), str, length, EGG_SECURE_USE_FALLBACK); \
+ }
+
+ void* egg_secure_alloc_full (const char *tag, size_t length, int options);
+
+ void* egg_secure_realloc_full (const char *tag, void *p, size_t length, int options);
+
+-void egg_secure_free (void* p);
++void egg_secure_free (void* p);
+
+-void egg_secure_free_full (void* p, int fallback);
++void egg_secure_free_full (void* p, int fallback);
+
+ void egg_secure_clear (void *p, size_t length);
+
+-int egg_secure_check (const void* p);
++int egg_secure_check (const void* p);
+
+ void egg_secure_validate (void);
+
+ char* egg_secure_strdup_full (const char *tag, const char *str, int options);
++
++char* egg_secure_strndup_full (const char *tag, const char *str, size_t length, int options);
+
+ void egg_secure_strclear (char *str);
+
diff --git a/security/gnome-keyring3/files/patch-egg_egg-secure-memory.c b/security/gnome-keyring3/files/patch-egg_egg-secure-memory.c
new file mode 100644
index 000000000..a3874cbfe
--- /dev/null
+++ b/security/gnome-keyring3/files/patch-egg_egg-secure-memory.c
@@ -0,0 +1,959 @@
+--- egg/egg-secure-memory.c.orig Wed Sep 26 10:28:35 2012
++++ egg/egg-secure-memory.c Sat Oct 27 14:46:28 2012
+@@ -22,8 +22,8 @@
+ */
+
+ /*
+- * IMPORTANT: This is pure vanila standard C, no glib. We need this
+- * because certain consumers of this protocol need to be built
++ * IMPORTANT: This is pure vanila standard C, no glib. We need this
++ * because certain consumers of this protocol need to be built
+ * without linking in any special libraries. ie: the PKCS#11 module.
+ */
+
+@@ -48,8 +48,8 @@
+
+ #define DEBUG_SECURE_MEMORY 0
+
+-#if DEBUG_SECURE_MEMORY
+-#define DEBUG_ALLOC(msg, n) fprintf(stderr, "%s %lu bytes\n", msg, n);
++#if DEBUG_SECURE_MEMORY
++#define DEBUG_ALLOC(msg, n) fprintf(stderr, "%s %lu bytes\n", msg, n);
+ #else
+ #define DEBUG_ALLOC(msg, n)
+ #endif
+@@ -59,8 +59,8 @@
+ /* Use our own assert to guarantee no glib allocations */
+ #ifndef ASSERT
+ #ifdef G_DISABLE_ASSERT
+-#define ASSERT(x)
+-#else
++#define ASSERT(x)
++#else
+ #define ASSERT(x) assert(x)
+ #endif
+ #endif
+@@ -74,18 +74,18 @@
+ static int show_warning = 1;
+ int egg_secure_warnings = 1;
+
+-/*
+- * We allocate all memory in units of sizeof(void*). This
++/*
++ * We allocate all memory in units of sizeof(void*). This
+ * is our definition of 'word'.
+ */
+ typedef void* word_t;
+
+-/* The amount of extra words we can allocate */
++/* The amount of extra words we can allocate */
+ #define WASTE 4
+
+-/*
+- * Track allocated memory or a free block. This structure is not stored
+- * in the secure memory area. It is allocated from a pool of other
++/*
++ * Track allocated memory or a free block. This structure is not stored
++ * in the secure memory area. It is allocated from a pool of other
+ * memory. See meta_pool_xxx ().
+ */
+ typedef struct _Cell {
+@@ -97,7 +97,7 @@ typedef struct _Cell {
+ struct _Cell *prev; /* Previous in memory ring */
+ } Cell;
+
+-/*
++/*
+ * A block of secure memory. This structure is the header in that block.
+ */
+ typedef struct _Block {
+@@ -130,20 +130,20 @@ unused_pop (void **stack)
+ ptr = *stack;
+ *stack = *(void**)ptr;
+ return ptr;
+-
++
+ }
+
+ static inline void*
+ unused_peek (void **stack)
+ {
+ ASSERT (stack);
+- return *stack;
++ return *stack;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * POOL META DATA ALLOCATION
+- *
+- * A pool for memory meta data. We allocate fixed size blocks. There are actually
++ *
++ * A pool for memory meta data. We allocate fixed size blocks. There are actually
+ * two different structures stored in this pool: Cell and Block. Cell is allocated
+ * way more often, and is bigger so we just allocate that size for both.
+ */
+@@ -185,7 +185,7 @@ pool_alloc (void)
+ if (unused_peek (&pool->unused))
+ break;
+ }
+-
++
+ /* Create a new pool */
+ if (pool == NULL) {
+ len = getpagesize () * 2;
+@@ -205,7 +205,7 @@ pool_alloc (void)
+ pool->n_items = (len - sizeof (Pool)) / sizeof (Item);
+ for (i = 0; i < pool->n_items; ++i)
+ unused_push (&pool->unused, pool->items + i);
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_CREATE_MEMPOOL(pool, 0, 0);
+ #endif
+@@ -227,9 +227,9 @@ pool_free (void* item)
+ {
+ Pool *pool, **at;
+ char *ptr, *beg, *end;
+-
++
+ ptr = item;
+-
++
+ /* Find which block this one belongs to */
+ for (at = (Pool **)&EGG_SECURE_GLOBALS.pool_data, pool = *at;
+ pool != NULL; at = &pool->next, pool = *at) {
+@@ -275,17 +275,17 @@ pool_valid (void* item)
+ {
+ Pool *pool;
+ char *ptr, *beg, *end;
+-
++
+ ptr = item;
+-
++
+ /* Find which block this one belongs to */
+ 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)
++ if (ptr >= beg && ptr <= end)
+ return (pool->used && (ptr - beg) % sizeof (Item) == 0);
+ }
+-
++
+ return 0;
+ }
+
+@@ -293,9 +293,9 @@ pool_valid (void* item)
+
+ /* -----------------------------------------------------------------------------
+ * SEC ALLOCATION
+- *
++ *
+ * Each memory cell begins and ends with a pointer to its metadata. These are also
+- * used as guards or red zones. Since they're treated as redzones by valgrind we
++ * used as guards or red zones. Since they're treated as redzones by valgrind we
+ * have to jump through a few hoops before reading and/or writing them.
+ */
+
+@@ -315,11 +315,11 @@ sec_write_guards (Cell *cell)
+
+ ((void**)cell->words)[0] = (void*)cell;
+ ((void**)cell->words)[cell->n_words - 1] = (void*)cell;
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS (cell->words, sizeof (word_t));
+ VALGRIND_MAKE_MEM_NOACCESS (cell->words + cell->n_words - 1, sizeof (word_t));
+-#endif
++#endif
+ }
+
+ static inline void
+@@ -327,16 +327,16 @@ sec_check_guards (Cell *cell)
+ {
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (cell->words, sizeof (word_t));
+- VALGRIND_MAKE_MEM_DEFINED (cell->words + cell->n_words - 1, sizeof (word_t));
+-#endif
+-
++ VALGRIND_MAKE_MEM_DEFINED (cell->words + cell->n_words - 1, sizeof (word_t));
++#endif
++
+ ASSERT(((void**)cell->words)[0] == (void*)cell);
+ ASSERT(((void**)cell->words)[cell->n_words - 1] == (void*)cell);
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS (cell->words, sizeof (word_t));
+ VALGRIND_MAKE_MEM_NOACCESS (cell->words + cell->n_words - 1, sizeof (word_t));
+-#endif
++#endif
+ }
+
+ static void
+@@ -347,9 +347,9 @@ sec_insert_cell_ring (Cell **ring, Cell *cell)
+ ASSERT (cell != *ring);
+ ASSERT (cell->next == NULL);
+ ASSERT (cell->prev == NULL);
+-
+- /* Insert back into the mix of available memory */
+- if (*ring) {
++
++ /* Insert back into the mix of available memory */
++ if (*ring) {
+ cell->next = (*ring)->next;
+ cell->prev = *ring;
+ cell->next->prev = cell;
+@@ -358,7 +358,7 @@ sec_insert_cell_ring (Cell **ring, Cell *cell)
+ cell->next = cell;
+ cell->prev = cell;
+ }
+-
++
+ *ring = cell;
+ ASSERT (cell->next->prev == cell);
+ ASSERT (cell->prev->next == cell);
+@@ -391,7 +391,7 @@ sec_remove_cell_ring (Cell **ring, Cell *cell)
+ cell->next->prev = cell->prev;
+ cell->prev->next = cell->next;
+ cell->next = cell->prev = NULL;
+-
++
+ ASSERT (*ring != cell);
+ }
+
+@@ -440,10 +440,10 @@ static Cell*
+ sec_neighbor_before (Block *block, Cell *cell)
+ {
+ word_t *word;
+-
++
+ ASSERT (cell);
+ ASSERT (block);
+-
++
+ word = cell->words - 1;
+ if (!sec_is_valid_word (block, word))
+ return NULL;
+@@ -451,7 +451,7 @@ sec_neighbor_before (Block *block, Cell *cell)
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (word, sizeof (word_t));
+ #endif
+-
++
+ cell = *word;
+ sec_check_guards (cell);
+
+@@ -462,14 +462,14 @@ sec_neighbor_before (Block *block, Cell *cell)
+ return cell;
+ }
+
+-static Cell*
++static Cell*
+ sec_neighbor_after (Block *block, Cell *cell)
+ {
+ word_t *word;
+-
++
+ ASSERT (cell);
+ ASSERT (block);
+-
++
+ word = cell->words + cell->n_words;
+ if (!sec_is_valid_word (block, word))
+ return NULL;
+@@ -480,7 +480,7 @@ sec_neighbor_after (Block *block, Cell *cell)
+
+ cell = *word;
+ sec_check_guards (cell);
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS (word, sizeof (word_t));
+ #endif
+@@ -496,7 +496,7 @@ sec_alloc (Block *block,
+ Cell *cell, *other;
+ size_t n_words;
+ void *memory;
+-
++
+ ASSERT (block);
+ ASSERT (length);
+ ASSERT (tag);
+@@ -504,16 +504,16 @@ sec_alloc (Block *block,
+ if (!block->unused_cells)
+ return NULL;
+
+- /*
+- * Each memory allocation is aligned to a pointer size, and
++ /*
++ * Each memory allocation is aligned to a pointer size, and
+ * then, sandwidched between two pointers to its meta data.
+ * These pointers also act as guards.
+ *
+- * We allocate memory in units of sizeof (void*)
++ * We allocate memory in units of sizeof (void*)
+ */
+-
++
+ n_words = sec_size_to_words (length) + 2;
+-
++
+ /* Look for a cell of at least our required size */
+ cell = block->unused_cells;
+ while (cell->n_words < n_words) {
+@@ -523,7 +523,7 @@ sec_alloc (Block *block,
+ break;
+ }
+ }
+-
++
+ if (!cell)
+ return NULL;
+
+@@ -532,7 +532,7 @@ sec_alloc (Block *block,
+ ASSERT (cell->prev);
+ ASSERT (cell->words);
+ sec_check_guards (cell);
+-
++
+ /* Steal from the cell if it's too long */
+ if (cell->n_words > n_words + WASTE) {
+ other = pool_alloc ();
+@@ -542,13 +542,13 @@ sec_alloc (Block *block,
+ other->words = cell->words;
+ cell->n_words -= n_words;
+ cell->words += n_words;
+-
++
+ sec_write_guards (other);
+ sec_write_guards (cell);
+-
++
+ cell = other;
+ }
+-
++
+ if (cell->next)
+ sec_remove_cell_ring (&block->unused_cells, cell);
+
+@@ -557,11 +557,11 @@ sec_alloc (Block *block,
+ cell->requested = length;
+ sec_insert_cell_ring (&block->used_cells, cell);
+ memory = sec_cell_to_memory (cell);
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_UNDEFINED (memory, length);
+ #endif
+-
++
+ return memset (memory, 0, length);
+ }
+
+@@ -570,13 +570,13 @@ sec_free (Block *block, void *memory)
+ {
+ Cell *cell, *other;
+ word_t *word;
+-
++
+ ASSERT (block);
+ ASSERT (memory);
+-
++
+ word = memory;
+ --word;
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (word, sizeof (word_t));
+ #endif
+@@ -600,39 +600,39 @@ sec_free (Block *block, void *memory)
+ /* Remove from the used cell ring */
+ sec_remove_cell_ring (&block->used_cells, cell);
+
+- /* Find previous unallocated neighbor, and merge if possible */
+- other = sec_neighbor_before (block, cell);
+- if (other && other->requested == 0) {
+- ASSERT (other->tag == NULL);
+- ASSERT (other->next && other->prev);
+- other->n_words += cell->n_words;
+- sec_write_guards (other);
+- pool_free (cell);
+- cell = other;
+- }
+-
+- /* Find next unallocated neighbor, and merge if possible */
+- other = sec_neighbor_after (block, cell);
+- if (other && other->requested == 0) {
+- ASSERT (other->tag == NULL);
+- ASSERT (other->next && other->prev);
+- other->n_words += cell->n_words;
+- other->words = cell->words;
+- if (cell->next)
+- sec_remove_cell_ring (&block->unused_cells, cell);
+- sec_write_guards (other);
+- pool_free (cell);
+- cell = other;
+- }
++ /* Find previous unallocated neighbor, and merge if possible */
++ other = sec_neighbor_before (block, cell);
++ if (other && other->requested == 0) {
++ ASSERT (other->tag == NULL);
++ ASSERT (other->next && other->prev);
++ other->n_words += cell->n_words;
++ sec_write_guards (other);
++ pool_free (cell);
++ cell = other;
++ }
+
+- /* Add to the unused list if not already there */
+- if (!cell->next)
+- sec_insert_cell_ring (&block->unused_cells, cell);
++ /* Find next unallocated neighbor, and merge if possible */
++ other = sec_neighbor_after (block, cell);
++ if (other && other->requested == 0) {
++ ASSERT (other->tag == NULL);
++ ASSERT (other->next && other->prev);
++ other->n_words += cell->n_words;
++ other->words = cell->words;
++ if (cell->next)
++ sec_remove_cell_ring (&block->unused_cells, cell);
++ sec_write_guards (other);
++ pool_free (cell);
++ cell = other;
++ }
+
+- cell->tag = NULL;
+- cell->requested = 0;
+- --block->n_used;
+- return NULL;
++ /* Add to the unused list if not already there */
++ if (!cell->next)
++ sec_insert_cell_ring (&block->unused_cells, cell);
++
++ cell->tag = NULL;
++ cell->requested = 0;
++ --block->n_used;
++ return NULL;
+ }
+
+ static void
+@@ -683,7 +683,7 @@ sec_realloc (Block *block,
+ /* Dig out where the meta should be */
+ word = memory;
+ --word;
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (word, sizeof (word_t));
+ #endif
+@@ -691,7 +691,7 @@ sec_realloc (Block *block,
+ ASSERT (sec_is_valid_word (block, word));
+ ASSERT (pool_valid (*word));
+ cell = *word;
+-
++
+ /* Validate that it's actually for real */
+ sec_check_guards (cell);
+ ASSERT (cell->requested > 0);
+@@ -710,17 +710,17 @@ sec_realloc (Block *block,
+ cell->requested = length;
+ alloc = sec_cell_to_memory (cell);
+
+- /*
++ /*
+ * Even though we may be reusing the same cell, that doesn't
+ * mean that the allocation is shrinking. It could have shrunk
+- * and is now expanding back some.
+- */
++ * and is now expanding back some.
++ */
+ if (length < valid)
+ sec_clear_undefined (alloc, length, valid);
+
+ return alloc;
+ }
+-
++
+ /* Need braaaaaiiiiiinsss... */
+ while (cell->n_words < n_words) {
+
+@@ -728,7 +728,7 @@ sec_realloc (Block *block,
+ other = sec_neighbor_after (block, cell);
+ if (!other || other->requested != 0)
+ break;
+-
++
+ /* Eat the whole neighbor if not too big */
+ if (n_words - cell->n_words + WASTE >= other->n_words) {
+ cell->n_words += other->n_words;
+@@ -745,7 +745,7 @@ sec_realloc (Block *block,
+ sec_write_guards (cell);
+ }
+ }
+-
++
+ if (cell->n_words >= n_words) {
+ cell->requested = length;
+ cell->tag = tag;
+@@ -760,7 +760,7 @@ sec_realloc (Block *block,
+ memcpy_with_vbits (alloc, memory, valid);
+ sec_free (block, memory);
+ }
+-
++
+ return alloc;
+ }
+
+@@ -770,7 +770,7 @@ sec_allocated (Block *block, void *memory)
+ {
+ Cell *cell;
+ word_t *word;
+-
++
+ ASSERT (block);
+ ASSERT (memory);
+
+@@ -780,12 +780,12 @@ sec_allocated (Block *block, void *memory)
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (word, sizeof (word_t));
+ #endif
+-
++
+ /* Lookup the meta for this memory block (using guard pointer) */
+ ASSERT (sec_is_valid_word (block, word));
+ ASSERT (pool_valid (*word));
+ cell = *word;
+-
++
+ sec_check_guards (cell);
+ ASSERT (cell->requested > 0);
+ ASSERT (cell->tag != NULL);
+@@ -817,10 +817,10 @@ sec_validate (Block *block)
+ ASSERT (sec_is_valid_word (block, word));
+ ASSERT (pool_valid (*word));
+ cell = *word;
+-
++
+ /* Validate that it's actually for real */
+ sec_check_guards (cell);
+-
++
+ /* Is it an allocated block? */
+ if (cell->requested > 0) {
+ ASSERT (cell->tag != NULL);
+@@ -829,7 +829,7 @@ sec_validate (Block *block)
+ ASSERT (cell->next->prev == cell);
+ ASSERT (cell->prev->next == cell);
+ ASSERT (cell->requested <= (cell->n_words - 2) * sizeof (word_t));
+-
++
+ /* An unused block */
+ } else {
+ ASSERT (cell->tag == NULL);
+@@ -838,7 +838,7 @@ sec_validate (Block *block)
+ ASSERT (cell->next->prev == cell);
+ ASSERT (cell->prev->next == cell);
+ }
+-
++
+ word += cell->n_words;
+ if (word == last)
+ break;
+@@ -855,7 +855,7 @@ sec_acquire_pages (size_t *sz,
+ {
+ void *pages;
+ unsigned long pgsize;
+-
++
+ ASSERT (sz);
+ ASSERT (*sz);
+ ASSERT (during_tag);
+@@ -863,7 +863,7 @@ sec_acquire_pages (size_t *sz,
+ /* Make sure sz is a multiple of the page size */
+ pgsize = getpagesize ();
+ *sz = (*sz + pgsize -1) & ~(pgsize - 1);
+-
++
+ #if defined(HAVE_MLOCK)
+ pages = mmap (0, *sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (pages == MAP_FAILED) {
+@@ -873,7 +873,7 @@ sec_acquire_pages (size_t *sz,
+ show_warning = 0;
+ return NULL;
+ }
+-
++
+ if (mlock (pages, *sz) < 0) {
+ if (show_warning && egg_secure_warnings && errno != EPERM) {
+ fprintf (stderr, "couldn't lock %lu bytes of memory (%s): %s\n",
+@@ -883,12 +883,12 @@ sec_acquire_pages (size_t *sz,
+ munmap (pages, *sz);
+ return NULL;
+ }
+-
++
+ DEBUG_ALLOC ("gkr-secure-memory: new block ", *sz);
+-
++
+ show_warning = 1;
+ return pages;
+-
++
+ #else
+ if (show_warning && egg_secure_warnings)
+ fprintf (stderr, "your system does not support private memory");
+@@ -898,21 +898,21 @@ sec_acquire_pages (size_t *sz,
+
+ }
+
+-static void
++static void
+ sec_release_pages (void *pages, size_t sz)
+ {
+ ASSERT (pages);
+ ASSERT (sz % getpagesize () == 0);
+-
++
+ #if defined(HAVE_MLOCK)
+ if (munlock (pages, sz) < 0 && egg_secure_warnings)
+ fprintf (stderr, "couldn't unlock private memory: %s\n", strerror (errno));
+-
++
+ if (munmap (pages, sz) < 0 && egg_secure_warnings)
+ fprintf (stderr, "couldn't unmap private anonymous memory: %s\n", strerror (errno));
+-
++
+ DEBUG_ALLOC ("gkr-secure-memory: freed block ", sz);
+-
++
+ #else
+ ASSERT (FALSE);
+ #endif
+@@ -924,7 +924,7 @@ sec_release_pages (void *pages, size_t sz)
+
+ static Block *all_blocks = NULL;
+
+-static Block*
++static Block*
+ sec_block_create (size_t size,
+ const char *during_tag)
+ {
+@@ -950,7 +950,7 @@ sec_block_create (size_t size,
+ /* The size above is a minimum, we're free to go bigger */
+ if (size < DEFAULT_BLOCK_SIZE)
+ size = DEFAULT_BLOCK_SIZE;
+-
++
+ block->words = sec_acquire_pages (&size, during_tag);
+ block->n_words = size / sizeof (word_t);
+ if (!block->words) {
+@@ -958,11 +958,11 @@ sec_block_create (size_t size,
+ pool_free (cell);
+ return NULL;
+ }
+-
++
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_DEFINED (block->words, size);
+ #endif
+-
++
+ /* The first cell to allocate from */
+ cell->words = block->words;
+ cell->n_words = block->n_words;
+@@ -972,7 +972,7 @@ sec_block_create (size_t size,
+
+ block->next = all_blocks;
+ all_blocks = block;
+-
++
+ return block;
+ }
+
+@@ -985,7 +985,7 @@ sec_block_destroy (Block *block)
+ ASSERT (block);
+ ASSERT (block->words);
+ ASSERT (block->n_used == 0);
+-
++
+ /* Remove from the list */
+ for (at = &all_blocks, bl = *at; bl; at = &bl->next, bl = *at) {
+ if (bl == block) {
+@@ -993,7 +993,7 @@ sec_block_destroy (Block *block)
+ break;
+ }
+ }
+-
++
+ /* Must have been found */
+ ASSERT (bl == block);
+ ASSERT (block->used_cells == NULL);
+@@ -1004,7 +1004,7 @@ sec_block_destroy (Block *block)
+ sec_remove_cell_ring (&block->unused_cells, cell);
+ pool_free (cell);
+ }
+-
++
+ /* Release all pages of secure memory */
+ sec_release_pages (block->words, block->n_words * sizeof (word_t));
+
+@@ -1028,35 +1028,35 @@ egg_secure_alloc_full (const char *tag,
+
+ if (length > 0xFFFFFFFF / 2) {
+ if (egg_secure_warnings)
+- fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
+- (unsigned long)length);
++ fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
++ (unsigned long)length);
+ return NULL;
+ }
+
+ /* Can't allocate zero bytes */
+ if (length == 0)
+ return NULL;
+-
++
+ DO_LOCK ();
+-
++
+ for (block = all_blocks; block; block = block->next) {
+ memory = sec_alloc (block, tag, length);
+ if (memory)
+- break;
++ break;
+ }
+-
++
+ /* None of the current blocks have space, allocate new */
+ if (!memory) {
+ block = sec_block_create (length, tag);
+ if (block)
+ memory = sec_alloc (block, tag, length);
+ }
+-
++
+ #ifdef WITH_VALGRIND
+ if (memory != NULL)
+ VALGRIND_MALLOCLIKE_BLOCK (memory, length, sizeof (void*), 1);
+ #endif
+-
++
+ DO_UNLOCK ();
+
+ if (!memory && (flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback != NULL) {
+@@ -1064,10 +1064,10 @@ egg_secure_alloc_full (const char *tag,
+ if (memory) /* Our returned memory is always zeroed */
+ memset (memory, 0, length);
+ }
+-
++
+ if (!memory)
+ errno = ENOMEM;
+-
++
+ return memory;
+ }
+
+@@ -1087,20 +1087,20 @@ egg_secure_realloc_full (const char *tag,
+
+ if (length > 0xFFFFFFFF / 2) {
+ if (egg_secure_warnings)
+- fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
++ fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
+ (unsigned long)length);
+ return NULL;
+ }
+-
++
+ if (memory == NULL)
+ return egg_secure_alloc_full (tag, length, flags);
+ if (!length) {
+ egg_secure_free_full (memory, flags);
+ return NULL;
+ }
+-
++
+ DO_LOCK ();
+-
++
+ /* Find out where it belongs to */
+ for (block = all_blocks; block; block = block->next) {
+ if (sec_is_valid_word (block, memory)) {
+@@ -1115,10 +1115,10 @@ egg_secure_realloc_full (const char *tag,
+
+ #ifdef WITH_VALGRIND
+ /* Now tell valgrind about either the new block or old one */
+- VALGRIND_MALLOCLIKE_BLOCK (alloc ? alloc : memory,
+- alloc ? length : previous,
++ VALGRIND_MALLOCLIKE_BLOCK (alloc ? alloc : memory,
++ alloc ? length : previous,
+ sizeof (word_t), 1);
+-#endif
++#endif
+ break;
+ }
+ }
+@@ -1129,13 +1129,13 @@ egg_secure_realloc_full (const char *tag,
+
+ if (block && block->n_used == 0)
+ sec_block_destroy (block);
+-
+- DO_UNLOCK ();
+-
++
++ DO_UNLOCK ();
++
+ if (!block) {
+ if ((flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback) {
+- /*
+- * In this case we can't zero the returned memory,
++ /*
++ * In this case we can't zero the returned memory,
+ * because we don't know what the block size was.
+ */
+ return EGG_SECURE_GLOBALS.fallback (memory, length);
+@@ -1155,7 +1155,7 @@ egg_secure_realloc_full (const char *tag,
+ egg_secure_free_full (memory, flags);
+ }
+ }
+-
++
+ if (!alloc)
+ errno = ENOMEM;
+
+@@ -1172,12 +1172,12 @@ void
+ egg_secure_free_full (void *memory, int flags)
+ {
+ Block *block = NULL;
+-
++
+ if (memory == NULL)
+ return;
+-
++
+ DO_LOCK ();
+-
++
+ /* Find out where it belongs to */
+ for (block = all_blocks; block; block = block->next) {
+ if (sec_is_valid_word (block, memory))
+@@ -1195,9 +1195,9 @@ egg_secure_free_full (void *memory, int flags)
+ if (block->n_used == 0)
+ sec_block_destroy (block);
+ }
+-
++
+ DO_UNLOCK ();
+-
++
+ if (!block) {
+ if ((flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback) {
+ EGG_SECURE_GLOBALS.fallback (memory, 0);
+@@ -1208,36 +1208,36 @@ egg_secure_free_full (void *memory, int flags)
+ ASSERT (0 && "memory does does not belong to secure memory pool");
+ }
+ }
+-}
++}
+
+-int
++int
+ egg_secure_check (const void *memory)
+ {
+ Block *block = NULL;
+
+ DO_LOCK ();
+-
++
+ /* Find out where it belongs to */
+ for (block = all_blocks; block; block = block->next) {
+ if (sec_is_valid_word (block, (word_t*)memory))
+ break;
+ }
+-
++
+ DO_UNLOCK ();
+-
++
+ return block == NULL ? 0 : 1;
+-}
++}
+
+ void
+ egg_secure_validate (void)
+ {
+ Block *block = NULL;
+-
++
+ DO_LOCK ();
+-
++
+ for (block = all_blocks; block; block = block->next)
+ sec_validate (block);
+-
++
+ DO_UNLOCK ();
+ }
+
+@@ -1320,20 +1320,42 @@ egg_secure_strdup_full (const char *tag,
+ if (!str)
+ return NULL;
+
+- len = strlen (str) + 1;
++ len = strlen (str) + 1;
+ res = (char *)egg_secure_alloc_full (tag, len, options);
+ strcpy (res, str);
+ return res;
+ }
+
++char *
++egg_secure_strndup_full (const char *tag,
++ const char *str,
++ size_t length,
++ int options)
++{
++ size_t len;
++ char *res;
++ const char *end;
++
++ if (!str)
++ return NULL;
++
++ end = memchr (str, '\0', length);
++ if (end != NULL)
++ length = (end - str);
++ len = length + 1;
++ res = (char *)egg_secure_alloc_full (tag, len, options);
++ memcpy (res, str, len);
++ return res;
++}
++
+ void
+ egg_secure_clear (void *p, size_t length)
+ {
+ volatile char *vp;
+-
++
+ if (p == NULL)
+ return;
+-
++
+ vp = (volatile char*)p;
+ while (length) {
+ *vp = 0xAA;
+@@ -1355,10 +1377,10 @@ egg_secure_strfree (char *str)
+ {
+ /*
+ * If we're using unpageable 'secure' memory, then the free call
+- * should zero out the memory, but because on certain platforms
++ * should zero out the memory, but because on certain platforms
+ * we may be using normal memory, zero it out here just in case.
+ */
+-
++
+ egg_secure_strclear (str);
+ egg_secure_free_full (str, EGG_SECURE_USE_FALLBACK);
+ }
diff --git a/security/gnome-keyring3/files/patch-egg_egg-secure-memory.h b/security/gnome-keyring3/files/patch-egg_egg-secure-memory.h
new file mode 100644
index 000000000..6e9b5ca3e
--- /dev/null
+++ b/security/gnome-keyring3/files/patch-egg_egg-secure-memory.h
@@ -0,0 +1,75 @@
+--- egg/egg-secure-memory.h.orig Wed Sep 26 10:28:35 2012
++++ egg/egg-secure-memory.h Sat Oct 27 14:46:28 2012
+@@ -27,16 +27,16 @@
+ #include <stdlib.h>
+
+ /* -------------------------------------------------------------------
+- * Low Level Secure Memory
+- *
+- * IMPORTANT: This is pure vanila standard C, no glib. We need this
+- * because certain consumers of this protocol need to be built
++ * Low Level Secure Memory
++ *
++ * IMPORTANT: This is pure vanila standard C, no glib. We need this
++ * because certain consumers of this protocol need to be built
+ * without linking in any special libraries. ie: the PKCS#11 module.
+- *
++ *
+ * Thread locking
+- *
++ *
+ * In order to use these functions in a module the following functions
+- * must be defined somewhere, and provide appropriate locking for
++ * must be defined somewhere, and provide appropriate locking for
+ * secure memory between threads:
+ */
+
+@@ -66,12 +66,12 @@ typedef struct {
+
+ extern egg_secure_glob EGG_SECURE_GLOBALS;
+
+-/*
++/*
+ * Main functionality
+- *
++ *
+ * Allocations return NULL on failure.
+- */
+-
++ */
++
+ #define EGG_SECURE_USE_FALLBACK 0x0001
+
+ #define EGG_SECURE_DECLARE(tag) \
+@@ -83,23 +83,28 @@ extern egg_secure_glob EGG_SECURE_GLOBALS;
+ } \
+ static inline void* egg_secure_strdup (const char *str) { \
+ return egg_secure_strdup_full (G_STRINGIFY (tag), str, EGG_SECURE_USE_FALLBACK); \
++ } \
++ static inline void* egg_secure_strndup (const char *str, size_t length) { \
++ return egg_secure_strndup_full (G_STRINGIFY (tag), str, length, EGG_SECURE_USE_FALLBACK); \
+ }
+
+ void* egg_secure_alloc_full (const char *tag, size_t length, int options);
+
+ void* egg_secure_realloc_full (const char *tag, void *p, size_t length, int options);
+
+-void egg_secure_free (void* p);
++void egg_secure_free (void* p);
+
+-void egg_secure_free_full (void* p, int fallback);
++void egg_secure_free_full (void* p, int fallback);
+
+ void egg_secure_clear (void *p, size_t length);
+
+-int egg_secure_check (const void* p);
++int egg_secure_check (const void* p);
+
+ void egg_secure_validate (void);
+
+ char* egg_secure_strdup_full (const char *tag, const char *str, int options);
++
++char* egg_secure_strndup_full (const char *tag, const char *str, size_t length, int options);
+
+ void egg_secure_strclear (char *str);
+
diff --git a/security/gnome-keyring3/files/patch-egg_tests_test-secmem.c b/security/gnome-keyring3/files/patch-egg_tests_test-secmem.c
new file mode 100644
index 000000000..6aa1d599c
--- /dev/null
+++ b/security/gnome-keyring3/files/patch-egg_tests_test-secmem.c
@@ -0,0 +1,66 @@
+--- egg/tests/test-secmem.c.orig Wed Sep 26 10:28:35 2012
++++ egg/tests/test-secmem.c Sat Oct 27 14:46:28 2012
+@@ -39,7 +39,7 @@ extern int egg_secure_warnings;
+
+ EGG_SECURE_DECLARE (tests);
+
+-/*
++/*
+ * Each test looks like (on one line):
+ * void unit_test_xxxxx (CuTest* cu)
+ *
+@@ -93,10 +93,12 @@ test_realloc_across (void)
+ g_assert (p != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (p, 1088));
+
+- /* Reallocate to a large one, will have to have changed blocks */
++ /* Reallocate to a large one, will have to have changed blocks */
+ p2 = egg_secure_realloc_full ("tests", p, 16200, 0);
+ g_assert (p2 != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (p2, 16200));
++
++ egg_secure_free (p2);
+ }
+
+ static void
+@@ -180,26 +182,25 @@ test_multialloc (void)
+ case 0: /* Allocate some memory */
+ size = g_random_int_range (1, 16384);
+ data = egg_secure_alloc (size);
+- g_assert (data);
++ g_assert (data != NULL);
+ memset (data, 0xCAFEBABE, size);
+ g_ptr_array_add (memory, data);
+ break;
+ case 1: /* Reallocate some memory */
+ index = g_random_int_range (0, memory->len);
+ data = g_ptr_array_index (memory, index);
+- g_assert (data);
++ g_assert (data != NULL);
+ size = g_random_int_range (1, 16384);
+ data = egg_secure_realloc (data, size);
+- g_assert (data);
++ g_assert (data != NULL);
+ memset (data, 0xCAFEBABE, size);
+ g_ptr_array_index (memory, index) = data;
+ break;
+ case 2: /* Free some memory */
+ index = g_random_int_range (0, memory->len);
+- data = g_ptr_array_index (memory, index);
+- g_assert (data);
++ data = g_ptr_array_remove_index_fast (memory, index);
++ g_assert (data != NULL);
+ egg_secure_free (data);
+- g_ptr_array_remove_index_fast (memory, index);
+ break;
+ default:
+ g_assert_not_reached ();
+@@ -212,6 +213,8 @@ test_multialloc (void)
+ }
+
+ g_assert (memory->len == 0);
++ for (i = 0; i < memory->len; i++)
++ egg_secure_free (memory->pdata[i]);
+ g_ptr_array_free (memory, TRUE);
+
+ egg_secure_warnings = 1;
diff --git a/security/libgnome-keyring/files/patch-egg_egg-dh.c b/security/libgnome-keyring/files/patch-egg_egg-dh.c
new file mode 100644
index 000000000..bf91221a1
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-egg_egg-dh.c
@@ -0,0 +1,11 @@
+--- egg/egg-dh.c.orig Wed Aug 8 21:00:54 2012
++++ egg/egg-dh.c Sat Oct 27 14:36:16 2012
+@@ -27,6 +27,8 @@
+ /* Enabling this is a complete security compromise */
+ #define DEBUG_DH_SECRET 0
+
++EGG_SECURE_DECLARE (dh);
++
+ typedef struct _DHGroup {
+ const gchar *name;
+ guint bits;
diff --git a/security/libgnome-keyring/files/patch-egg_egg-libgcrypt.c b/security/libgnome-keyring/files/patch-egg_egg-libgcrypt.c
new file mode 100644
index 000000000..a96d73005
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-egg_egg-libgcrypt.c
@@ -0,0 +1,11 @@
+--- egg/egg-libgcrypt.c.orig Wed Aug 8 21:00:54 2012
++++ egg/egg-libgcrypt.c Sat Oct 27 14:36:16 2012
+@@ -28,6 +28,8 @@
+
+ #include <gcrypt.h>
+
++EGG_SECURE_DECLARE (libgcrypt);
++
+ static void
+ log_handler (gpointer unused, int unknown, const gchar *msg, va_list va)
+ {
diff --git a/security/libgnome-keyring/files/patch-egg_egg-secure-memory.c b/security/libgnome-keyring/files/patch-egg_egg-secure-memory.c
new file mode 100644
index 000000000..ba78bfc76
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-egg_egg-secure-memory.c
@@ -0,0 +1,966 @@
+--- egg/egg-secure-memory.c.orig Wed Jun 8 10:00:06 2011
++++ egg/egg-secure-memory.c Sat Oct 27 14:36:16 2012
+@@ -46,12 +46,6 @@
+ #include <valgrind/memcheck.h>
+ #endif
+
+-/*
+- * Use this to force all memory through malloc
+- * for use with valgrind and the like
+- */
+-#define FORCE_FALLBACK_MEMORY 0
+-
+ #define DEBUG_SECURE_MEMORY 0
+
+ #if DEBUG_SECURE_MEMORY
+@@ -72,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;
+
+ /*
+@@ -97,20 +91,22 @@ typedef void* word_t;
+ typedef struct _Cell {
+ word_t *words; /* Pointer to secure memory */
+ size_t n_words; /* Amount of secure memory in words */
+- size_t allocated; /* Amount actually requested by app, in bytes, 0 if unused */
+- struct _Cell *next; /* Next in unused memory ring, or NULL if used */
+- struct _Cell *prev; /* Previous in unused memory ring, or NULL if used */
++ size_t requested; /* Amount actually requested by app, in bytes, 0 if unused */
++ const char *tag; /* Tag which describes the allocation */
++ struct _Cell *next; /* Next in memory ring */
++ struct _Cell *prev; /* Previous in memory ring */
+ } Cell;
+
+ /*
+ * A block of secure memory. This structure is the header in that block.
+ */
+ typedef struct _Block {
+- word_t *words; /* Actual memory hangs off here */
+- size_t n_words; /* Number of words in block */
+- size_t used; /* Number of used allocations */
+- struct _Cell* unused; /* Ring of unused allocations */
+- struct _Block *next; /* Next block in list */
++ word_t *words; /* Actual memory hangs off here */
++ size_t n_words; /* Number of words in block */
++ size_t n_used; /* Number of used allocations */
++ struct _Cell* used_cells; /* Ring of used allocations */
++ struct _Cell* unused_cells; /* Ring of unused allocations */
++ struct _Block *next; /* Next block in list */
+ } Block;
+
+ /* -----------------------------------------------------------------------------
+@@ -167,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;
+ }
+@@ -191,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;
+@@ -227,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) {
+@@ -263,6 +268,8 @@ pool_free (void* item)
+ unused_push (&pool->unused, item);
+ }
+
++#ifndef G_DISABLE_ASSERT
++
+ static int
+ pool_valid (void* item)
+ {
+@@ -272,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)
+@@ -282,6 +289,8 @@ pool_valid (void* item)
+ return 0;
+ }
+
++#endif /* G_DISABLE_ASSERT */
++
+ /* -----------------------------------------------------------------------------
+ * SEC ALLOCATION
+ *
+@@ -398,13 +407,34 @@ sec_is_valid_word (Block *block, word_t *word)
+ return (word >= block->words && word < block->words + block->n_words);
+ }
+
+-static inline void*
+-sec_clear_memory (void *memory, size_t from, size_t to)
++static inline void
++sec_clear_undefined (void *memory,
++ size_t from,
++ size_t to)
+ {
++ char *ptr = memory;
+ ASSERT (from <= to);
+- memset ((char*)memory + from, 0, to - from);
+- return memory;
++#ifdef WITH_VALGRIND
++ VALGRIND_MAKE_MEM_UNDEFINED (ptr + from, to - from);
++#endif
++ memset (ptr + from, 0, to - from);
++#ifdef WITH_VALGRIND
++ VALGRIND_MAKE_MEM_UNDEFINED (ptr + from, to - from);
++#endif
+ }
++static inline void
++sec_clear_noaccess (void *memory, size_t from, size_t to)
++{
++ char *ptr = memory;
++ ASSERT (from <= to);
++#ifdef WITH_VALGRIND
++ VALGRIND_MAKE_MEM_UNDEFINED (ptr + from, to - from);
++#endif
++ memset (ptr + from, 0, to - from);
++#ifdef WITH_VALGRIND
++ VALGRIND_MAKE_MEM_NOACCESS (ptr + from, to - from);
++#endif
++}
+
+ static Cell*
+ sec_neighbor_before (Block *block, Cell *cell)
+@@ -459,7 +489,9 @@ sec_neighbor_after (Block *block, Cell *cell)
+ }
+
+ static void*
+-sec_alloc (Block *block, size_t length)
++sec_alloc (Block *block,
++ const char *tag,
++ size_t length)
+ {
+ Cell *cell, *other;
+ size_t n_words;
+@@ -467,8 +499,9 @@ sec_alloc (Block *block, size_t length)
+
+ ASSERT (block);
+ ASSERT (length);
++ ASSERT (tag);
+
+- if (!block->unused)
++ if (!block->unused_cells)
+ return NULL;
+
+ /*
+@@ -482,10 +515,10 @@ sec_alloc (Block *block, size_t length)
+ n_words = sec_size_to_words (length) + 2;
+
+ /* Look for a cell of at least our required size */
+- cell = block->unused;
++ cell = block->unused_cells;
+ while (cell->n_words < n_words) {
+ cell = cell->next;
+- if (cell == block->unused) {
++ if (cell == block->unused_cells) {
+ cell = NULL;
+ break;
+ }
+@@ -494,7 +527,8 @@ sec_alloc (Block *block, size_t length)
+ if (!cell)
+ return NULL;
+
+- ASSERT (cell->allocated == 0);
++ ASSERT (cell->tag == NULL);
++ ASSERT (cell->requested == 0);
+ ASSERT (cell->prev);
+ ASSERT (cell->words);
+ sec_check_guards (cell);
+@@ -516,10 +550,12 @@ sec_alloc (Block *block, size_t length)
+ }
+
+ if (cell->next)
+- sec_remove_cell_ring (&block->unused, cell);
++ sec_remove_cell_ring (&block->unused_cells, cell);
+
+- ++block->used;
+- cell->allocated = length;
++ ++block->n_used;
++ cell->tag = tag;
++ cell->requested = length;
++ sec_insert_cell_ring (&block->used_cells, cell);
+ memory = sec_cell_to_memory (cell);
+
+ #ifdef WITH_VALGRIND
+@@ -555,47 +591,83 @@ sec_free (Block *block, void *memory)
+ #endif
+
+ sec_check_guards (cell);
+- sec_clear_memory (memory, 0, cell->allocated);
++ sec_clear_noaccess (memory, 0, cell->requested);
+
+ sec_check_guards (cell);
+- ASSERT (cell->next == NULL);
+- ASSERT (cell->prev == NULL);
+- ASSERT (cell->allocated > 0);
++ ASSERT (cell->requested > 0);
++ ASSERT (cell->tag != NULL);
+
+- /* Find previous unallocated neighbor, and merge if possible */
+- other = sec_neighbor_before (block, cell);
+- if (other && other->allocated == 0) {
+- ASSERT (other->next && other->prev);
+- other->n_words += cell->n_words;
+- sec_write_guards (other);
+- pool_free (cell);
+- cell = other;
+- }
++ /* Remove from the used cell ring */
++ sec_remove_cell_ring (&block->used_cells, cell);
+
+- /* Find next unallocated neighbor, and merge if possible */
+- other = sec_neighbor_after (block, cell);
+- if (other && other->allocated == 0) {
+- ASSERT (other->next && other->prev);
+- other->n_words += cell->n_words;
+- other->words = cell->words;
+- if (cell->next)
+- sec_remove_cell_ring (&block->unused, cell);
+- sec_write_guards (other);
+- pool_free (cell);
+- cell = other;
+- }
++ /* Find previous unallocated neighbor, and merge if possible */
++ other = sec_neighbor_before (block, cell);
++ if (other && other->requested == 0) {
++ ASSERT (other->tag == NULL);
++ ASSERT (other->next && other->prev);
++ other->n_words += cell->n_words;
++ sec_write_guards (other);
++ pool_free (cell);
++ cell = other;
++ }
+
+- /* Add to the unused list if not already there */
+- if (!cell->next)
+- sec_insert_cell_ring (&block->unused, cell);
++ /* Find next unallocated neighbor, and merge if possible */
++ other = sec_neighbor_after (block, cell);
++ if (other && other->requested == 0) {
++ ASSERT (other->tag == NULL);
++ ASSERT (other->next && other->prev);
++ other->n_words += cell->n_words;
++ other->words = cell->words;
++ if (cell->next)
++ sec_remove_cell_ring (&block->unused_cells, cell);
++ sec_write_guards (other);
++ pool_free (cell);
++ cell = other;
++ }
+
+- cell->allocated = 0;
+- --block->used;
+- return NULL;
++ /* Add to the unused list if not already there */
++ if (!cell->next)
++ sec_insert_cell_ring (&block->unused_cells, cell);
++
++ cell->tag = NULL;
++ cell->requested = 0;
++ --block->n_used;
++ return NULL;
+ }
+
++static void
++memcpy_with_vbits (void *dest,
++ void *src,
++ size_t length)
++{
++#ifdef WITH_VALGRIND
++ int vbits_setup = 0;
++ void *vbits = NULL;
++
++ if (RUNNING_ON_VALGRIND) {
++ vbits = malloc (length);
++ if (vbits != NULL)
++ vbits_setup = VALGRIND_GET_VBITS (src, vbits, length);
++ VALGRIND_MAKE_MEM_DEFINED (src, length);
++ }
++#endif
++
++ memcpy (dest, src, length);
++
++#ifdef WITH_VALGRIND
++ if (vbits_setup == 1) {
++ VALGRIND_SET_VBITS (dest, vbits, length);
++ VALGRIND_SET_VBITS (src, vbits, length);
++ }
++ free (vbits);
++#endif
++}
++
+ static void*
+-sec_realloc (Block *block, void *memory, size_t length)
++sec_realloc (Block *block,
++ const char *tag,
++ void *memory,
++ size_t length)
+ {
+ Cell *cell, *other;
+ word_t *word;
+@@ -606,6 +678,7 @@ sec_realloc (Block *block, void *memory, size_t length
+ /* Standard realloc behavior, should have been handled elsewhere */
+ ASSERT (memory != NULL);
+ ASSERT (length > 0);
++ ASSERT (tag != NULL);
+
+ /* Dig out where the meta should be */
+ word = memory;
+@@ -621,12 +694,11 @@ sec_realloc (Block *block, void *memory, size_t length
+
+ /* Validate that it's actually for real */
+ sec_check_guards (cell);
+- ASSERT (cell->allocated > 0);
+- ASSERT (cell->next == NULL);
+- ASSERT (cell->prev == NULL);
++ ASSERT (cell->requested > 0);
++ ASSERT (cell->tag != NULL);
+
+ /* The amount of valid data */
+- valid = cell->allocated;
++ valid = cell->requested;
+
+ /* How many words we actually want */
+ n_words = sec_size_to_words (length) + 2;
+@@ -635,22 +707,18 @@ sec_realloc (Block *block, void *memory, size_t length
+ if (n_words <= cell->n_words) {
+
+ /* TODO: No shrinking behavior yet */
+- cell->allocated = length;
++ cell->requested = length;
+ alloc = sec_cell_to_memory (cell);
+
+-#ifdef WITH_VALGRIND
+- VALGRIND_MAKE_MEM_DEFINED (alloc, length);
+-#endif
+-
+ /*
+ * Even though we may be reusing the same cell, that doesn't
+ * mean that the allocation is shrinking. It could have shrunk
+ * and is now expanding back some.
+ */
+ if (length < valid)
+- return sec_clear_memory (alloc, length, valid);
+- else
+- return alloc;
++ sec_clear_undefined (alloc, length, valid);
++
++ return alloc;
+ }
+
+ /* Need braaaaaiiiiiinsss... */
+@@ -658,14 +726,14 @@ sec_realloc (Block *block, void *memory, size_t length
+
+ /* See if we have a neighbor who can give us some memory */
+ other = sec_neighbor_after (block, cell);
+- if (!other || other->allocated != 0)
++ if (!other || other->requested != 0)
+ break;
+
+ /* Eat the whole neighbor if not too big */
+ if (n_words - cell->n_words + WASTE >= other->n_words) {
+ cell->n_words += other->n_words;
+ sec_write_guards (cell);
+- sec_remove_cell_ring (&block->unused, other);
++ sec_remove_cell_ring (&block->unused_cells, other);
+ pool_free (other);
+
+ /* Steal from the neighbor */
+@@ -679,20 +747,17 @@ sec_realloc (Block *block, void *memory, size_t length
+ }
+
+ if (cell->n_words >= n_words) {
+- cell->allocated = length;
++ cell->requested = length;
++ cell->tag = tag;
+ alloc = sec_cell_to_memory (cell);
+-
+-#ifdef WITH_VALGRIND
+- VALGRIND_MAKE_MEM_DEFINED (alloc, length);
+-#endif
+-
+- return sec_clear_memory (alloc, valid, length);
++ sec_clear_undefined (alloc, valid, length);
++ return alloc;
+ }
+
+ /* That didn't work, try alloc/free */
+- alloc = sec_alloc (block, length);
++ alloc = sec_alloc (block, tag, length);
+ if (alloc) {
+- memcpy (alloc, memory, valid);
++ memcpy_with_vbits (alloc, memory, valid);
+ sec_free (block, memory);
+ }
+
+@@ -722,15 +787,14 @@ sec_allocated (Block *block, void *memory)
+ cell = *word;
+
+ sec_check_guards (cell);
+- ASSERT (cell->next == NULL);
+- ASSERT (cell->prev == NULL);
+- ASSERT (cell->allocated > 0);
++ ASSERT (cell->requested > 0);
++ ASSERT (cell->tag != NULL);
+
+ #ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS (word, sizeof (word_t));
+ #endif
+
+- return cell->allocated;
++ return cell->requested;
+ }
+
+ static void
+@@ -739,6 +803,11 @@ sec_validate (Block *block)
+ Cell *cell;
+ word_t *word, *last;
+
++#ifdef WITH_VALGRIND
++ if (RUNNING_ON_VALGRIND)
++ return;
++#endif
++
+ word = block->words;
+ last = word + block->n_words;
+
+@@ -753,15 +822,19 @@ sec_validate (Block *block)
+ sec_check_guards (cell);
+
+ /* Is it an allocated block? */
+- if (cell->allocated > 0) {
+- ASSERT (cell->next == NULL);
+- ASSERT (cell->prev == NULL);
+- ASSERT (cell->allocated <= (cell->n_words - 2) * sizeof (word_t));
++ if (cell->requested > 0) {
++ ASSERT (cell->tag != NULL);
++ ASSERT (cell->next != NULL);
++ ASSERT (cell->prev != NULL);
++ ASSERT (cell->next->prev == cell);
++ ASSERT (cell->prev->next == cell);
++ ASSERT (cell->requested <= (cell->n_words - 2) * sizeof (word_t));
+
+- /* An unused block */
++ /* An unused block */
+ } else {
+- ASSERT (cell->next);
+- ASSERT (cell->prev);
++ ASSERT (cell->tag == NULL);
++ ASSERT (cell->next != NULL);
++ ASSERT (cell->prev != NULL);
+ ASSERT (cell->next->prev == cell);
+ ASSERT (cell->prev->next == cell);
+ }
+@@ -777,13 +850,15 @@ sec_validate (Block *block)
+ */
+
+ static void*
+-sec_acquire_pages (size_t *sz)
++sec_acquire_pages (size_t *sz,
++ const char *during_tag)
+ {
+ void *pages;
+ unsigned long pgsize;
+
+ ASSERT (sz);
+ ASSERT (*sz);
++ ASSERT (during_tag);
+
+ /* Make sure sz is a multiple of the page size */
+ pgsize = getpagesize ();
+@@ -792,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)
+- fprintf (stderr, "couldn't map %lu bytes of private memory: %s\n",
+- (unsigned long)*sz, strerror (errno));
+- lock_warning = 0;
++ 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));
++ show_warning = 0;
+ return NULL;
+ }
+
+ if (mlock (pages, *sz) < 0) {
+- if (lock_warning && egg_secure_warnings && errno != EPERM) {
+- fprintf (stderr, "couldn't lock %lu bytes of private memory: %s\n",
+- (unsigned long)*sz, strerror (errno));
+- lock_warning = 0;
++ 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));
++ show_warning = 0;
+ }
+ munmap (pages, *sz);
+ return NULL;
+@@ -811,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
+
+@@ -850,15 +925,17 @@ sec_release_pages (void *pages, size_t sz)
+ static Block *all_blocks = NULL;
+
+ static Block*
+-sec_block_create (size_t size)
++sec_block_create (size_t size,
++ const char *during_tag)
+ {
+ Block *block;
+ Cell *cell;
+
+-#if FORCE_FALLBACK_MEMORY
++ ASSERT (during_tag);
++
+ /* We can force all all memory to be malloced */
+- return NULL;
+-#endif
++ if (getenv ("SECMEM_FORCE_FALLBACK"))
++ return NULL;
+
+ block = pool_alloc ();
+ if (!block)
+@@ -874,7 +951,7 @@ sec_block_create (size_t size)
+ if (size < DEFAULT_BLOCK_SIZE)
+ size = DEFAULT_BLOCK_SIZE;
+
+- block->words = sec_acquire_pages (&size);
++ block->words = sec_acquire_pages (&size, during_tag);
+ block->n_words = size / sizeof (word_t);
+ if (!block->words) {
+ pool_free (block);
+@@ -889,9 +966,9 @@ sec_block_create (size_t size)
+ /* The first cell to allocate from */
+ cell->words = block->words;
+ cell->n_words = block->n_words;
+- cell->allocated = 0;
++ cell->requested = 0;
+ sec_write_guards (cell);
+- sec_insert_cell_ring (&block->unused, cell);
++ sec_insert_cell_ring (&block->unused_cells, cell);
+
+ block->next = all_blocks;
+ all_blocks = block;
+@@ -907,7 +984,7 @@ sec_block_destroy (Block *block)
+
+ ASSERT (block);
+ ASSERT (block->words);
+- ASSERT (block->used == 0);
++ ASSERT (block->n_used == 0);
+
+ /* Remove from the list */
+ for (at = &all_blocks, bl = *at; bl; at = &bl->next, bl = *at) {
+@@ -919,11 +996,12 @@ sec_block_destroy (Block *block)
+
+ /* Must have been found */
+ ASSERT (bl == block);
++ ASSERT (block->used_cells == NULL);
+
+ /* Release all the meta data cells */
+- while (block->unused) {
+- cell = block->unused;
+- sec_remove_cell_ring (&block->unused, cell);
++ while (block->unused_cells) {
++ cell = block->unused_cells;
++ sec_remove_cell_ring (&block->unused_cells, cell);
+ pool_free (cell);
+ }
+
+@@ -938,17 +1016,16 @@ sec_block_destroy (Block *block)
+ */
+
+ void*
+-egg_secure_alloc (size_t length)
++egg_secure_alloc_full (const char *tag,
++ size_t length,
++ int flags)
+ {
+- return egg_secure_alloc_full (length, GKR_SECURE_USE_FALLBACK);
+-}
+-
+-void*
+-egg_secure_alloc_full (size_t length, int flags)
+-{
+ Block *block;
+ void *memory = NULL;
+
++ if (tag == NULL)
++ tag = "?";
++
+ if (length > 0xFFFFFFFF / 2) {
+ if (egg_secure_warnings)
+ fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
+@@ -963,16 +1040,16 @@ egg_secure_alloc_full (size_t length, int flags)
+ DO_LOCK ();
+
+ for (block = all_blocks; block; block = block->next) {
+- memory = sec_alloc (block, length);
++ memory = sec_alloc (block, tag, length);
+ if (memory)
+ break;
+ }
+
+ /* None of the current blocks have space, allocate new */
+ if (!memory) {
+- block = sec_block_create (length);
++ block = sec_block_create (length, tag);
+ if (block)
+- memory = sec_alloc (block, length);
++ memory = sec_alloc (block, tag, length);
+ }
+
+ #ifdef WITH_VALGRIND
+@@ -982,8 +1059,8 @@ egg_secure_alloc_full (size_t length, int flags)
+
+ DO_UNLOCK ();
+
+- if (!memory && (flags & GKR_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);
+ }
+@@ -995,19 +1072,19 @@ egg_secure_alloc_full (size_t length, int flags)
+ }
+
+ void*
+-egg_secure_realloc (void *memory, size_t length)
++egg_secure_realloc_full (const char *tag,
++ void *memory,
++ size_t length,
++ int flags)
+ {
+- return egg_secure_realloc_full (memory, length, GKR_SECURE_USE_FALLBACK);
+-}
+-
+-void*
+-egg_secure_realloc_full (void *memory, size_t length, int flags)
+-{
+ Block *block = NULL;
+ size_t previous = 0;
+ int donew = 0;
+ void *alloc = NULL;
+
++ if (tag == NULL)
++ tag = "?";
++
+ if (length > 0xFFFFFFFF / 2) {
+ if (egg_secure_warnings)
+ fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
+@@ -1016,7 +1093,7 @@ egg_secure_realloc_full (void *memory, size_t length,
+ }
+
+ if (memory == NULL)
+- return egg_secure_alloc_full (length, flags);
++ return egg_secure_alloc_full (tag, length, flags);
+ if (!length) {
+ egg_secure_free_full (memory, flags);
+ return NULL;
+@@ -1034,7 +1111,7 @@ egg_secure_realloc_full (void *memory, size_t length,
+ VALGRIND_FREELIKE_BLOCK (memory, sizeof (word_t));
+ #endif
+
+- alloc = sec_realloc (block, memory, length);
++ alloc = sec_realloc (block, tag, memory, length);
+
+ #ifdef WITH_VALGRIND
+ /* Now tell valgrind about either the new block or old one */
+@@ -1050,31 +1127,31 @@ egg_secure_realloc_full (void *memory, size_t length,
+ if (block && !alloc)
+ donew = 1;
+
+- if (block && block->used == 0)
++ if (block && block->n_used == 0)
+ sec_block_destroy (block);
+
+ DO_UNLOCK ();
+
+ if (!block) {
+- if ((flags & GKR_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;
+ }
+ }
+
+ if (donew) {
+- alloc = egg_secure_alloc_full (length, flags);
++ alloc = egg_secure_alloc_full (tag, length, flags);
+ if (alloc) {
+- memcpy (alloc, memory, previous);
++ memcpy_with_vbits (alloc, memory, previous);
+ egg_secure_free_full (memory, flags);
+ }
+ }
+@@ -1088,7 +1165,7 @@ egg_secure_realloc_full (void *memory, size_t length,
+ void
+ egg_secure_free (void *memory)
+ {
+- egg_secure_free_full (memory, GKR_SECURE_USE_FALLBACK);
++ egg_secure_free_full (memory, EGG_SECURE_USE_FALLBACK);
+ }
+
+ void
+@@ -1109,26 +1186,26 @@ egg_secure_free_full (void *memory, int flags)
+
+ #ifdef WITH_VALGRIND
+ /* We like valgrind's warnings, so give it a first whack at checking for errors */
+- if (block != NULL || !(flags & GKR_SECURE_USE_FALLBACK))
++ if (block != NULL || !(flags & EGG_SECURE_USE_FALLBACK))
+ VALGRIND_FREELIKE_BLOCK (memory, sizeof (word_t));
+ #endif
+
+ if (block != NULL) {
+ sec_free (block, memory);
+- if (block->used == 0)
++ if (block->n_used == 0)
+ sec_block_destroy (block);
+ }
+
+ DO_UNLOCK ();
+
+ if (!block) {
+- if ((flags & GKR_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");
+ }
+ }
+ }
+@@ -1164,26 +1241,78 @@ egg_secure_validate (void)
+ DO_UNLOCK ();
+ }
+
+-void
+-egg_secure_dump_blocks (void)
++
++static egg_secure_rec *
++records_for_ring (Cell *cell_ring,
++ egg_secure_rec *records,
++ unsigned int *count,
++ unsigned int *total)
+ {
++ egg_secure_rec *new_rec;
++ unsigned int allocated = *count;
++ Cell *cell;
++
++ cell = cell_ring;
++ do {
++ if (*count >= allocated) {
++ new_rec = realloc (records, sizeof (egg_secure_rec) * (allocated + 32));
++ if (new_rec == NULL) {
++ *count = 0;
++ free (records);
++ return NULL;
++ } else {
++ records = new_rec;
++ allocated += 32;
++ }
++ }
++
++ if (cell != NULL) {
++ records[*count].request_length = cell->requested;
++ records[*count].block_length = cell->n_words * sizeof (word_t);
++ records[*count].tag = cell->tag;
++ (*count)++;
++ (*total) += cell->n_words;
++ cell = cell->next;
++ }
++ } while (cell != NULL && cell != cell_ring);
++
++ return records;
++}
++
++egg_secure_rec *
++egg_secure_records (unsigned int *count)
++{
++ egg_secure_rec *records = NULL;
+ Block *block = NULL;
++ unsigned int total;
+
++ *count = 0;
++
+ DO_LOCK ();
+
+- /* Find out where it belongs to */
+- for (block = all_blocks; block; block = block->next) {
+- fprintf (stderr, "----------------------------------------------------\n");
+- fprintf (stderr, " BLOCK at: 0x%08lx len: %lu\n", (unsigned long)block,
+- (unsigned long)block->n_words * sizeof (word_t));
+- fprintf (stderr, "\n");
++ for (block = all_blocks; block != NULL; block = block->next) {
++ total = 0;
++
++ records = records_for_ring (block->unused_cells, records, count, &total);
++ if (records == NULL)
++ break;
++ records = records_for_ring (block->used_cells, records, count, &total);
++ if (records == NULL)
++ break;
++
++ /* Make sure this actualy accounts for all memory */
++ ASSERT (total == block->n_words);
+ }
+
+ DO_UNLOCK ();
++
++ return records;
+ }
+
+ char*
+-egg_secure_strdup (const char *str)
++egg_secure_strdup_full (const char *tag,
++ const char *str,
++ int options)
+ {
+ size_t len;
+ char *res;
+@@ -1192,11 +1321,33 @@ egg_secure_strdup (const char *str)
+ return NULL;
+
+ len = strlen (str) + 1;
+- res = (char*)egg_secure_alloc (len);
++ res = (char *)egg_secure_alloc_full (tag, len, options);
+ strcpy (res, str);
+ return res;
+ }
+
++char *
++egg_secure_strndup_full (const char *tag,
++ const char *str,
++ size_t length,
++ int options)
++{
++ size_t len;
++ char *res;
++ const char *end;
++
++ if (!str)
++ return NULL;
++
++ end = memchr (str, '\0', length);
++ if (end != NULL)
++ length = (end - str);
++ len = length + 1;
++ res = (char *)egg_secure_alloc_full (tag, len, options);
++ memcpy (res, str, len);
++ return res;
++}
++
+ void
+ egg_secure_clear (void *p, size_t length)
+ {
+@@ -1205,11 +1356,11 @@ egg_secure_clear (void *p, size_t length)
+ if (p == NULL)
+ return;
+
+- vp = (volatile char*)p;
+- while (length) {
+- *vp = 0xAA;
+- vp++;
+- length--;
++ vp = (volatile char*)p;
++ while (length) {
++ *vp = 0xAA;
++ vp++;
++ length--;
+ }
+ }
+
+@@ -1231,5 +1382,5 @@ egg_secure_strfree (char *str)
+ */
+
+ egg_secure_strclear (str);
+- egg_secure_free_full (str, GKR_SECURE_USE_FALLBACK);
++ egg_secure_free_full (str, EGG_SECURE_USE_FALLBACK);
+ }
diff --git a/security/libgnome-keyring/files/patch-egg_egg-secure-memory.h b/security/libgnome-keyring/files/patch-egg_egg-secure-memory.h
new file mode 100644
index 000000000..89df7cdc7
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-egg_egg-secure-memory.h
@@ -0,0 +1,107 @@
+--- egg/egg-secure-memory.h.orig Wed Jun 8 10:00:06 2011
++++ egg/egg-secure-memory.h Sat Oct 27 14:36:16 2012
+@@ -40,46 +40,58 @@
+ * secure memory between threads:
+ */
+
+-extern void egg_memory_lock (void);
++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;
+
+-extern void egg_memory_unlock (void);
++#define EGG_SECURE_POOL_VER_STR "1.0"
++#define EGG_SECURE_GLOBALS SECMEM_pool_data_v1_0
+
+-/*
+- * 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_DEFINE_GLOBALS(lock, unlock, fallback) \
++ egg_secure_glob EGG_SECURE_GLOBALS = { \
++ lock, unlock, fallback, NULL, EGG_SECURE_POOL_VER_STR };
+
+-#define EGG_SECURE_GLIB_DEFINITIONS() \
++#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
+ *
+ * Allocations return NULL on failure.
+ */
+
+-#define GKR_SECURE_USE_FALLBACK 0x0001
++#define EGG_SECURE_USE_FALLBACK 0x0001
+
+-void* egg_secure_alloc (size_t length);
++#define EGG_SECURE_DECLARE(tag) \
++ static inline void* egg_secure_alloc (size_t length) { \
++ return egg_secure_alloc_full (G_STRINGIFY (tag), length, EGG_SECURE_USE_FALLBACK); \
++ } \
++ static inline void* egg_secure_realloc (void *p, size_t length) { \
++ return egg_secure_realloc_full (G_STRINGIFY (tag), p, length, EGG_SECURE_USE_FALLBACK); \
++ } \
++ static inline void* egg_secure_strdup (const char *str) { \
++ return egg_secure_strdup_full (G_STRINGIFY (tag), str, EGG_SECURE_USE_FALLBACK); \
++ } \
++ static inline void* egg_secure_strndup (const char *str, size_t length) { \
++ return egg_secure_strndup_full (G_STRINGIFY (tag), str, length, EGG_SECURE_USE_FALLBACK); \
++ }
+
+-void* egg_secure_alloc_full (size_t length, int flags);
++void* egg_secure_alloc_full (const char *tag, size_t length, int options);
+
+-void* egg_secure_realloc (void *p, size_t length);
++void* egg_secure_realloc_full (const char *tag, void *p, size_t length, int options);
+
+-void* egg_secure_realloc_full (void *p, size_t length, int fallback);
+-
+ void egg_secure_free (void* p);
+
+ void egg_secure_free_full (void* p, int fallback);
+@@ -90,12 +102,20 @@ int egg_secure_check (const void* p);
+
+ void egg_secure_validate (void);
+
+-void egg_secure_dump_blocks (void);
++char* egg_secure_strdup_full (const char *tag, const char *str, int options);
+
+-char* egg_secure_strdup (const char *str);
++char* egg_secure_strndup_full (const char *tag, const char *str, size_t length, int options);
+
+ void egg_secure_strclear (char *str);
+
+ void egg_secure_strfree (char *str);
++
++typedef struct {
++ const char *tag;
++ size_t request_length;
++ size_t block_length;
++} egg_secure_rec;
++
++egg_secure_rec * egg_secure_records (unsigned int *count);
+
+ #endif /* EGG_SECURE_MEMORY_H */
diff --git a/security/libgnome-keyring/files/patch-egg_tests_Makefile.in b/security/libgnome-keyring/files/patch-egg_tests_Makefile.in
new file mode 100644
index 000000000..6d770f34c
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-egg_tests_Makefile.in
@@ -0,0 +1,10 @@
+--- egg/tests/Makefile.in.orig Sat Oct 27 14:39:25 2012
++++ egg/tests/Makefile.in Sat Oct 27 14:39:52 2012
+@@ -313,6 +313,7 @@ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ INCLUDES = \
++ -I$(top_srcdir) \
+ -I$(top_srcdir)/egg \
+ $(LIBRARY_CFLAGS)
+
diff --git a/security/libgnome-keyring/files/patch-egg_tests_test-dh.c b/security/libgnome-keyring/files/patch-egg_tests_test-dh.c
new file mode 100644
index 000000000..c3347d7bc
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-egg_tests_test-dh.c
@@ -0,0 +1,11 @@
+--- egg/tests/test-dh.c.orig Mon Sep 5 07:16:09 2011
++++ egg/tests/test-dh.c Sat Oct 27 14:36:16 2012
+@@ -35,7 +35,7 @@
+ #include <stdio.h>
+ #include <string.h>
+
+-EGG_SECURE_GLIB_DEFINITIONS ();
++EGG_SECURE_DEFINE_GLIB_GLOBALS ();
+
+ static void
+ test_dh_perform (void)
diff --git a/security/libgnome-keyring/files/patch-egg_tests_test-hkdf.c b/security/libgnome-keyring/files/patch-egg_tests_test-hkdf.c
new file mode 100644
index 000000000..5656083be
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-egg_tests_test-hkdf.c
@@ -0,0 +1,11 @@
+--- egg/tests/test-hkdf.c.orig Mon Sep 5 07:16:09 2011
++++ egg/tests/test-hkdf.c Sat Oct 27 14:36:16 2012
+@@ -33,7 +33,7 @@
+
+ #include <gcrypt.h>
+
+-EGG_SECURE_GLIB_DEFINITIONS ();
++EGG_SECURE_DEFINE_GLIB_GLOBALS ();
+
+ static void
+ test_hkdf_test_case_1 (void)
diff --git a/security/libgnome-keyring/files/patch-egg_tests_test-secmem.c b/security/libgnome-keyring/files/patch-egg_tests_test-secmem.c
new file mode 100644
index 000000000..1781524d2
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-egg_tests_test-secmem.c
@@ -0,0 +1,167 @@
+--- egg/tests/test-secmem.c.orig Mon Sep 5 07:16:09 2011
++++ egg/tests/test-secmem.c Sat Oct 27 14:36:16 2012
+@@ -23,7 +23,7 @@
+
+ #include "config.h"
+
+-#include "egg-secure-memory.h"
++#include "egg/egg-secure-memory.h"
+
+ #include <glib.h>
+
+@@ -31,11 +31,14 @@
+ #include <stdio.h>
+ #include <string.h>
+
+-EGG_SECURE_GLIB_DEFINITIONS ();
+
++EGG_SECURE_DEFINE_GLIB_GLOBALS ();
++
+ /* Declared in egg-secure-memory.c */
+ extern int egg_secure_warnings;
+
++EGG_SECURE_DECLARE (tests);
++
+ /*
+ * Each test looks like (on one line):
+ * void unit_test_xxxxx (CuTest* cu)
+@@ -68,7 +71,7 @@ test_alloc_free (void)
+ gpointer p;
+ gboolean ret;
+
+- p = egg_secure_alloc_full (512, 0);
++ p = egg_secure_alloc_full ("tests", 512, 0);
+ g_assert (p != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (p, 512));
+
+@@ -86,14 +89,16 @@ test_realloc_across (void)
+ gpointer p, p2;
+
+ /* Tiny allocation */
+- p = egg_secure_realloc_full (NULL, 1088, 0);
++ p = egg_secure_realloc_full ("tests", NULL, 1088, 0);
+ g_assert (p != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (p, 1088));
+
+ /* Reallocate to a large one, will have to have changed blocks */
+- p2 = egg_secure_realloc_full (p, 16200, 0);
++ p2 = egg_secure_realloc_full ("tests", p, 16200, 0);
+ g_assert (p2 != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (p2, 16200));
++
++ egg_secure_free (p2);
+ }
+
+ static void
+@@ -102,13 +107,13 @@ test_alloc_two (void)
+ gpointer p, p2;
+ gboolean ret;
+
+- p2 = egg_secure_alloc_full (4, 0);
++ p2 = egg_secure_alloc_full ("tests", 4, 0);
+ g_assert (p2 != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (p2, 4));
+
+ memset (p2, 0x67, 4);
+
+- p = egg_secure_alloc_full (16200, 0);
++ p = egg_secure_alloc_full ("tests", 16200, 0);
+ g_assert (p != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (p, 16200));
+
+@@ -130,19 +135,19 @@ test_realloc (void)
+
+ len = strlen (str) + 1;
+
+- p = egg_secure_realloc_full (NULL, len, 0);
++ p = egg_secure_realloc_full ("tests", NULL, len, 0);
+ g_assert (p != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (p, len));
+
+ strcpy ((gchar*)p, str);
+
+- p2 = egg_secure_realloc_full (p, 512, 0);
++ p2 = egg_secure_realloc_full ("tests", p, 512, 0);
+ g_assert (p2 != NULL);
+ g_assert_cmpint (G_MAXSIZE, ==, find_non_zero (((gchar*)p2) + len, 512 - len));
+
+ g_assert (strcmp (p2, str) == 0);
+
+- p = egg_secure_realloc_full (p2, 0, 0);
++ p = egg_secure_realloc_full ("tests", p2, 0, 0);
+ g_assert (p == NULL);
+ }
+
+@@ -154,9 +159,6 @@ test_multialloc (void)
+ gsize size;
+ int i, action, index;
+
+- if (g_test_quick ())
+- return;
+-
+ /* A predetermined seed to get a predetermined pattern */
+ g_random_set_seed (15);
+ memory = g_ptr_array_new ();
+@@ -180,26 +182,25 @@ test_multialloc (void)
+ case 0: /* Allocate some memory */
+ size = g_random_int_range (1, 16384);
+ data = egg_secure_alloc (size);
+- g_assert (data);
++ g_assert (data != NULL);
+ memset (data, 0xCAFEBABE, size);
+ g_ptr_array_add (memory, data);
+ break;
+ case 1: /* Reallocate some memory */
+ index = g_random_int_range (0, memory->len);
+ data = g_ptr_array_index (memory, index);
+- g_assert (data);
++ g_assert (data != NULL);
+ size = g_random_int_range (1, 16384);
+ data = egg_secure_realloc (data, size);
+- g_assert (data);
++ g_assert (data != NULL);
+ memset (data, 0xCAFEBABE, size);
+ g_ptr_array_index (memory, index) = data;
+ break;
+ case 2: /* Free some memory */
+ index = g_random_int_range (0, memory->len);
+- data = g_ptr_array_index (memory, index);
+- g_assert (data);
++ data = g_ptr_array_remove_index_fast (memory, index);
++ g_assert (data != NULL);
+ egg_secure_free (data);
+- g_ptr_array_remove_index_fast (memory, index);
+ break;
+ default:
+ g_assert_not_reached ();
+@@ -212,6 +213,8 @@ test_multialloc (void)
+ }
+
+ g_assert (memory->len == 0);
++ for (i = 0; i < memory->len; i++)
++ egg_secure_free (memory->pdata[i]);
+ g_ptr_array_free (memory, TRUE);
+
+ egg_secure_warnings = 1;
+@@ -222,7 +225,7 @@ test_clear (void)
+ {
+ gpointer p;
+
+- p = egg_secure_alloc_full (188, 0);
++ p = egg_secure_alloc_full ("tests", 188, 0);
+ g_assert (p != NULL);
+ memset (p, 0x89, 188);
+ g_assert (memchr (p, 0x89, 188) == p);
+@@ -255,9 +258,9 @@ main (int argc, char **argv)
+ {
+ g_test_init (&argc, &argv, NULL);
+
+- g_test_add_func ("/secmem/alloc-free", test_alloc_free);
+- g_test_add_func ("/secmem/realloc-across", test_realloc_across);
+- g_test_add_func ("/secmem/alloc-two", test_alloc_two);
++ g_test_add_func ("/secmem/alloc_free", test_alloc_free);
++ g_test_add_func ("/secmem/realloc_across", test_realloc_across);
++ g_test_add_func ("/secmem/alloc_two", test_alloc_two);
+ g_test_add_func ("/secmem/realloc", test_realloc);
+ g_test_add_func ("/secmem/multialloc", test_multialloc);
+ g_test_add_func ("/secmem/clear", test_clear);
diff --git a/security/libgnome-keyring/files/patch-library_Makefile.in b/security/libgnome-keyring/files/patch-library_Makefile.in
new file mode 100644
index 000000000..e3bc76614
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-library_Makefile.in
@@ -0,0 +1,11 @@
+--- library/Makefile.in.orig Sat Oct 27 14:40:01 2012
++++ library/Makefile.in Sat Oct 27 14:40:29 2012
+@@ -435,7 +435,7 @@ libgnome_keyring_la_LIBADD = \
+
+ libgnome_keyring_la_LDFLAGS = \
+ -version-info $(LIB_GNOME_KEYRING_LT_VERSION) \
+- -no-undefined -export-symbols-regex 'gnome_keyring_|GNOME_KEYRING_'
++ -no-undefined -export-symbols-regex '^gnome_keyring_|^GNOME_KEYRING_|^SECMEM_.*'
+
+ noinst_LTLIBRARIES = libgnome-keyring-testable.la
+ libgnome_keyring_testable_la_SOURCES =
diff --git a/security/libgnome-keyring/files/patch-library_gkr-session.c b/security/libgnome-keyring/files/patch-library_gkr-session.c
new file mode 100644
index 000000000..9ab5f8ee1
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-library_gkr-session.c
@@ -0,0 +1,11 @@
+--- library/gkr-session.c.orig Sat Mar 31 14:59:37 2012
++++ library/gkr-session.c Sat Oct 27 14:36:16 2012
+@@ -44,6 +44,8 @@ struct _GkrSession {
+ G_LOCK_DEFINE_STATIC (session_globals);
+ static GkrSession *the_session;
+
++EGG_SECURE_DECLARE (session);
++
+ static guchar*
+ pkcs7_pad_string_in_secure_memory (const gchar *string, gsize *n_padded)
+ {
diff --git a/security/libgnome-keyring/files/patch-library_gnome-keyring-memory.c b/security/libgnome-keyring/files/patch-library_gnome-keyring-memory.c
new file mode 100644
index 000000000..f7dd924a2
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-library_gnome-keyring-memory.c
@@ -0,0 +1,81 @@
+--- library/gnome-keyring-memory.c.orig Sat Mar 31 14:59:37 2012
++++ library/gnome-keyring-memory.c Sat Oct 27 14:36:16 2012
+@@ -62,19 +62,19 @@ static GStaticMutex memory_mutex = G_STATIC_MUTEX_INIT
+ * locking for memory between threads
+ */
+
+-void
++static void
+ egg_memory_lock (void)
+ {
+ g_static_mutex_lock (&memory_mutex);
+ }
+
+-void
++static void
+ egg_memory_unlock (void)
+ {
+ g_static_mutex_unlock (&memory_mutex);
+ }
+
+-void*
++static void *
+ egg_memory_fallback (void *p, size_t sz)
+ {
+ const gchar *env;
+@@ -107,6 +107,10 @@ egg_memory_fallback (void *p, size_t sz)
+ return g_realloc (p, sz);
+ }
+
++EGG_SECURE_DEFINE_GLOBALS (egg_memory_lock, egg_memory_unlock, egg_memory_fallback);
++
++EGG_SECURE_DECLARE (libgnome_keyring_memory);
++
+ /* -----------------------------------------------------------------------------
+ * PUBLIC FUNCTIONS
+ */
+@@ -129,7 +133,7 @@ gnome_keyring_memory_alloc (gulong sz)
+ gpointer p;
+
+ /* Try to allocate secure memory */
+- p = egg_secure_alloc_full (sz, GKR_SECURE_USE_FALLBACK);
++ p = egg_secure_alloc (sz);
+
+ /* Our fallback will always allocate */
+ g_assert (p);
+@@ -151,7 +155,7 @@ gnome_keyring_memory_alloc (gulong sz)
+ gpointer
+ gnome_keyring_memory_try_alloc (gulong sz)
+ {
+- return egg_secure_alloc_full (sz, 0);
++ return egg_secure_alloc_full ("libgnome_keyring_memory", sz, 0);
+ }
+
+ /**
+@@ -187,7 +191,7 @@ gnome_keyring_memory_realloc (gpointer p, gulong sz)
+ }
+
+ /* First try and ask secure memory to reallocate */
+- n = egg_secure_realloc_full (p, sz, GKR_SECURE_USE_FALLBACK);
++ n = egg_secure_realloc (p, sz);
+
+ g_assert (n);
+
+@@ -226,7 +230,7 @@ gnome_keyring_memory_try_realloc (gpointer p, gulong s
+ }
+
+ /* First try and ask secure memory to reallocate */
+- n = egg_secure_realloc_full (p, sz, 0);
++ n = egg_secure_realloc_full ("libgnome_keyring_memory", p, sz, 0);
+
+ g_assert (n);
+
+@@ -247,7 +251,7 @@ gnome_keyring_memory_free (gpointer p)
+ {
+ if (!p)
+ return;
+- egg_secure_free_full (p, GKR_SECURE_USE_FALLBACK);
++ egg_secure_free (p);
+ }
+
+ /**
diff --git a/security/libgnome-keyring/files/patch-library_gnome-keyring-utils.c b/security/libgnome-keyring/files/patch-library_gnome-keyring-utils.c
new file mode 100644
index 000000000..320b6ae33
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-library_gnome-keyring-utils.c
@@ -0,0 +1,11 @@
+--- library/gnome-keyring-utils.c.orig Fri Aug 17 12:15:17 2012
++++ library/gnome-keyring-utils.c Sat Oct 27 14:36:16 2012
+@@ -32,6 +32,8 @@
+
+ #include "egg/egg-secure-memory.h"
+
++EGG_SECURE_DECLARE (libgnome_keyring_utils);
++
+ /**
+ * SECTION:gnome-keyring-result
+ * @title: Result Codes
diff --git a/security/libgnome-keyring/files/patch-library_gnome-keyring.c b/security/libgnome-keyring/files/patch-library_gnome-keyring.c
new file mode 100644
index 000000000..da2d9c046
--- /dev/null
+++ b/security/libgnome-keyring/files/patch-library_gnome-keyring.c
@@ -0,0 +1,11 @@
+--- library/gnome-keyring.c.orig Fri Aug 17 12:15:17 2012
++++ library/gnome-keyring.c Sat Oct 27 14:36:16 2012
+@@ -51,6 +51,8 @@
+ #include <sys/uio.h>
+ #include <stdarg.h>
+
++EGG_SECURE_DECLARE (libgnome_keyring);
++
+ typedef gboolean (*DecodeCallback) (DBusMessageIter *, gpointer);
+
+ typedef gboolean (*DecodeDictCallback) (const gchar *, DBusMessageIter *, gpointer);