diff options
author | gusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059> | 2013-11-11 03:19:22 +0800 |
---|---|---|
committer | gusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059> | 2013-11-11 03:19:22 +0800 |
commit | dafa386080bf73269d65a238868235dddef47c63 (patch) | |
tree | 3317a5cd1b9959b4285d9f376f9cd9168a5b9f51 /security | |
parent | f45a3e8bcb9a8d79f1d6b9f786f7b86b5cf38f2f (diff) | |
download | marcuscom-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
Diffstat (limited to 'security')
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); |