summaryrefslogtreecommitdiff
path: root/egg
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2010-10-14 19:38:39 +0000
committerStef Walter <stefw@collabora.co.uk>2011-09-10 13:30:24 +0200
commit3f60c65cc0f535362ad6eb77ec08e63c235110e2 (patch)
treeac0dac8545144b6502979892597103b322877042 /egg
parent73b1ef9914933d6748c9295d7ba3e7410c1633dc (diff)
downloadgnome-keyring-3f60c65cc0f535362ad6eb77ec08e63c235110e2.tar.gz
Secure memory tagging
* Tag all secure memory with strings, and print out diagnostic report of what's in use, upon request.
Diffstat (limited to 'egg')
-rw-r--r--egg/egg-dh.c2
-rw-r--r--egg/egg-entry-buffer.c2
-rw-r--r--egg/egg-libgcrypt.c2
-rw-r--r--egg/egg-openssl.c2
-rw-r--r--egg/egg-secure-memory.c309
-rw-r--r--egg/egg-secure-memory.h31
-rw-r--r--egg/egg-symkey.c2
-rw-r--r--egg/tests/test-secmem.c24
8 files changed, 238 insertions, 136 deletions
diff --git a/egg/egg-dh.c b/egg/egg-dh.c
index bed524e8..85dec77c 100644
--- a/egg/egg-dh.c
+++ b/egg/egg-dh.c
@@ -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/egg/egg-entry-buffer.c b/egg/egg-entry-buffer.c
index afb4093b..cac1f2d3 100644
--- a/egg/egg-entry-buffer.c
+++ b/egg/egg-entry-buffer.c
@@ -28,6 +28,8 @@
#include <string.h>
+EGG_SECURE_DECLARE (entry_buffer);
+
/* Initial size of buffer, in bytes */
#define MIN_SIZE 16
diff --git a/egg/egg-libgcrypt.c b/egg/egg-libgcrypt.c
index 8e1eb70c..e5b3f558 100644
--- a/egg/egg-libgcrypt.c
+++ b/egg/egg-libgcrypt.c
@@ -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/egg/egg-openssl.c b/egg/egg-openssl.c
index 63d92ab5..45daccb2 100644
--- a/egg/egg-openssl.c
+++ b/egg/egg-openssl.c
@@ -56,6 +56,8 @@
#define PEM_PREF_END "-----END "
#define PEM_PREF_END_L 9
+EGG_SECURE_DECLARE (openssl);
+
static void
parse_header_lines (const gchar *hbeg, const gchar *hend, GHashTable **result)
{
diff --git a/egg/egg-secure-memory.c b/egg/egg-secure-memory.c
index facc9fe0..ab63d45f 100644
--- a/egg/egg-secure-memory.c
+++ b/egg/egg-secure-memory.c
@@ -97,20 +97,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;
/* -----------------------------------------------------------------------------
@@ -463,7 +465,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;
@@ -471,8 +475,9 @@ sec_alloc (Block *block, size_t length)
ASSERT (block);
ASSERT (length);
+ ASSERT (tag);
- if (!block->unused)
+ if (!block->unused_cells)
return NULL;
/*
@@ -486,10 +491,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;
}
@@ -497,8 +502,9 @@ 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);
@@ -520,10 +526,12 @@ sec_alloc (Block *block, size_t length)
}
if (cell->next)
- sec_remove_cell_ring (&block->unused, cell);
-
- ++block->used;
- cell->allocated = length;
+ sec_remove_cell_ring (&block->unused_cells, cell);
+
+ ++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
@@ -559,16 +567,19 @@ sec_free (Block *block, void *memory)
#endif
sec_check_guards (cell);
- sec_clear_memory (memory, 0, cell->allocated);
+ sec_clear_memory (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);
+
+ /* 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->allocated == 0) {
+ if (other && other->requested == 0) {
+ ASSERT (other->tag == NULL);
ASSERT (other->next && other->prev);
other->n_words += cell->n_words;
sec_write_guards (other);
@@ -578,12 +589,13 @@ sec_free (Block *block, void *memory)
/* Find next unallocated neighbor, and merge if possible */
other = sec_neighbor_after (block, cell);
- if (other && other->allocated == 0) {
+ 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, cell);
+ sec_remove_cell_ring (&block->unused_cells, cell);
sec_write_guards (other);
pool_free (cell);
cell = other;
@@ -591,25 +603,30 @@ sec_free (Block *block, void *memory)
/* Add to the unused list if not already there */
if (!cell->next)
- sec_insert_cell_ring (&block->unused, cell);
-
- cell->allocated = 0;
- --block->used;
+ sec_insert_cell_ring (&block->unused_cells, cell);
+
+ cell->tag = NULL;
+ cell->requested = 0;
+ --block->n_used;
return NULL;
}
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;
size_t n_words;
size_t valid;
void *alloc;
-
+
/* 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;
@@ -625,13 +642,12 @@ 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;
@@ -639,7 +655,7 @@ 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
@@ -662,14 +678,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 */
@@ -683,18 +699,19 @@ 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);
}
-
+
/* That didn't work, try alloc/free */
- alloc = sec_alloc (block, length);
+ alloc = sec_alloc (block, tag, length);
if (alloc) {
memcpy (alloc, memory, valid);
sec_free (block, memory);
@@ -726,15 +743,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
@@ -757,15 +773,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 */
} 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);
}
@@ -781,13 +801,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 ();
@@ -797,16 +819,16 @@ sec_acquire_pages (size_t *sz)
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));
+ fprintf (stderr, "couldn't map %lu bytes of memory (%s): %s\n",
+ (unsigned long)*sz, during_tag, strerror (errno));
lock_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));
+ fprintf (stderr, "couldn't lock %lu bytes of memory (%s): %s\n",
+ (unsigned long)*sz, during_tag, strerror (errno));
lock_warning = 0;
}
munmap (pages, *sz);
@@ -854,11 +876,14 @@ 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;
+ ASSERT (during_tag);
+
#if FORCE_FALLBACK_MEMORY
/* We can force all all memory to be malloced */
return NULL;
@@ -878,7 +903,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);
@@ -893,10 +918,10 @@ 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;
@@ -911,7 +936,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) {
@@ -923,11 +948,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);
}
@@ -942,17 +968,16 @@ sec_block_destroy (Block *block)
*/
void*
-egg_secure_alloc (size_t length)
-{
- return egg_secure_alloc_full (length, GKR_SECURE_USE_FALLBACK);
-}
-
-void*
-egg_secure_alloc_full (size_t length, int flags)
+egg_secure_alloc_full (const char *tag,
+ 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",
@@ -967,16 +992,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
@@ -985,8 +1010,8 @@ egg_secure_alloc_full (size_t length, int flags)
#endif
DO_UNLOCK ();
-
- if (!memory && (flags & GKR_SECURE_USE_FALLBACK)) {
+
+ if (!memory && (flags & EGG_SECURE_USE_FALLBACK)) {
memory = egg_memory_fallback (NULL, length);
if (memory) /* Our returned memory is always zeroed */
memset (memory, 0, length);
@@ -999,19 +1024,19 @@ egg_secure_alloc_full (size_t length, int flags)
}
void*
-egg_secure_realloc (void *memory, size_t length)
-{
- return egg_secure_realloc_full (memory, length, GKR_SECURE_USE_FALLBACK);
-}
-
-void*
-egg_secure_realloc_full (void *memory, size_t length, int flags)
+egg_secure_realloc_full (const char *tag,
+ 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",
@@ -1020,7 +1045,7 @@ egg_secure_realloc_full (void *memory, size_t length, int flags)
}
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;
@@ -1038,8 +1063,8 @@ egg_secure_realloc_full (void *memory, size_t length, int flags)
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 */
VALGRIND_MALLOCLIKE_BLOCK (alloc ? alloc : memory,
@@ -1054,13 +1079,13 @@ egg_secure_realloc_full (void *memory, size_t length, int flags)
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)) {
/*
* In this case we can't zero the returned memory,
* because we don't know what the block size was.
@@ -1074,9 +1099,9 @@ egg_secure_realloc_full (void *memory, size_t length, int flags)
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);
egg_secure_free_full (memory, flags);
@@ -1092,7 +1117,7 @@ egg_secure_realloc_full (void *memory, size_t length, int flags)
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
@@ -1119,14 +1144,14 @@ egg_secure_free_full (void *memory, int flags)
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)) {
+ if ((flags & EGG_SECURE_USE_FALLBACK)) {
egg_memory_fallback (memory, 0);
} else {
if (egg_secure_warnings)
@@ -1168,35 +1193,87 @@ 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;
-
+
if (!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;
}
@@ -1235,5 +1312,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/egg/egg-secure-memory.h b/egg/egg-secure-memory.h
index 85ce1f69..682811d9 100644
--- a/egg/egg-secure-memory.h
+++ b/egg/egg-secure-memory.h
@@ -70,15 +70,22 @@ extern void* egg_memory_fallback (void *p, size_t length);
* 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); \
+ }
-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 (void *p, size_t length, int fallback);
+void* egg_secure_realloc_full (const char *tag, void *p, size_t length, int options);
void egg_secure_free (void* p);
@@ -90,12 +97,18 @@ int egg_secure_check (const void* p);
void egg_secure_validate (void);
-void egg_secure_dump_blocks (void);
-
-char* egg_secure_strdup (const char *str);
+char* egg_secure_strdup_full (const char *tag, const char *str, 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/egg/egg-symkey.c b/egg/egg-symkey.c
index a69100f4..04d6a915 100644
--- a/egg/egg-symkey.c
+++ b/egg/egg-symkey.c
@@ -26,6 +26,8 @@
#include "egg-secure-memory.h"
#include "egg-symkey.h"
+EGG_SECURE_DECLARE (symkey);
+
/* -----------------------------------------------------------------------------
* QUARKS
*/
diff --git a/egg/tests/test-secmem.c b/egg/tests/test-secmem.c
index b5ee4651..20beec93 100644
--- a/egg/tests/test-secmem.c
+++ b/egg/tests/test-secmem.c
@@ -37,7 +37,9 @@ EGG_SECURE_GLIB_DEFINITIONS ();
/* 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)
*
@@ -69,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));
@@ -87,12 +89,12 @@ 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);
+ /* 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));
}
@@ -103,13 +105,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));
@@ -131,19 +133,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);
}
@@ -220,7 +222,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);