summaryrefslogtreecommitdiff
path: root/egg
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-11-17 15:26:55 +0100
committerStef Walter <stefw@collabora.co.uk>2011-11-21 10:28:27 +0100
commitf3b9d46c75675e9b4b451164dd32ed9b1af0dfb1 (patch)
tree5b66cf37d54e3b447e3087cc27b03eeb7ae332f7 /egg
parent97cd79171dfbba24394f070f3946b20c2d518d2d (diff)
downloadgcr-f3b9d46c75675e9b4b451164dd32ed9b1af0dfb1.tar.gz
Add valgrind memory checking and fix up errors
* This is especially necessary after migrating to EggBytes since it's reference counted and an easy sourc of memory leaks * Remove threading from testing framework, as gcr isn't threadsafe in all parts. * Fix bugs discovered in memory checking. * Fix up some of the testing stuff.
Diffstat (limited to 'egg')
-rw-r--r--egg/Makefile.am7
-rw-r--r--egg/egg-asn1x.c25
-rw-r--r--egg/egg-bytes.c1
-rw-r--r--egg/egg-decimal.c2
-rw-r--r--egg/egg-dh.c2
-rw-r--r--egg/egg-dn.c5
-rw-r--r--egg/egg-hkdf.c1
-rw-r--r--egg/egg-openssl.c1
-rw-r--r--egg/egg-secure-memory.c393
-rw-r--r--egg/egg-secure-memory.h38
-rw-r--r--egg/egg-symkey.c1
-rw-r--r--egg/egg-testing.c131
-rw-r--r--egg/egg-testing.h17
-rw-r--r--egg/tests/Makefile.am3
-rw-r--r--egg/tests/test-asn1.c8
-rw-r--r--egg/tests/test-hex.c6
-rw-r--r--egg/tests/test-openssl.c4
-rw-r--r--egg/tests/test-padding.c2
-rw-r--r--egg/tests/test-secmem.c15
-rw-r--r--egg/tests/test-symkey.c7
20 files changed, 451 insertions, 218 deletions
diff --git a/egg/Makefile.am b/egg/Makefile.am
index 259d522..f00258c 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -11,7 +11,9 @@ BUILT_SOURCES = \
INCLUDES = \
-I$(top_srcdir) \
- -I$(top_builddir)
+ -I$(top_builddir) \
+ -I$(top_srcdir)/build \
+ -DWITH_VALGRIND
libegg_la_CFLAGS = \
$(GLIB_CFLAGS)
@@ -90,3 +92,6 @@ libegg_test_la_LIBS = \
# -------------------------------------------------------------------
SUBDIRS = . tests
+
+check-memory:
+ make -C tests check-memory
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index ab862e0..2f481d2 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -3164,7 +3164,7 @@ egg_asn1x_take_bits_as_raw (GNode *node,
length += 1;
ab = g_slice_new0 (Abits);
- ab->bits = egg_bytes_ref (value);
+ ab->bits = value;
ab->n_bits = n_bits;
anode_encode_tlv_and_enc (node, length + 1, anode_encoder_bit_string, ab, abits_destroy);
@@ -4027,6 +4027,27 @@ match_oid_in_definitions (const ASN1_ARRAY_TYPE *defs, const gchar *match)
return result;
}
+static gboolean
+is_oid_number (const gchar *p)
+{
+ gboolean must = TRUE;
+ gint i;
+
+ for (i = 0; p[i] != '\0'; i++) {
+ if (g_ascii_isdigit (p[i])) {
+ must = FALSE;
+ } else if (must) {
+ return FALSE;
+ } else {
+ if (p[i] != '.')
+ return FALSE;
+ must = TRUE;
+ }
+ }
+
+ return !must;
+}
+
GNode*
egg_asn1x_create (const ASN1_ARRAY_TYPE *defs, const gchar *type)
{
@@ -4038,7 +4059,7 @@ egg_asn1x_create (const ASN1_ARRAY_TYPE *defs, const gchar *type)
g_return_val_if_fail (type, NULL);
/* An OID */
- if (strspn (type, "0123456789.") == strlen (type)) {
+ if (is_oid_number (type)) {
def = match_oid_in_definitions (defs, type);
/* An Identifier */
diff --git a/egg/egg-bytes.c b/egg/egg-bytes.c
index 22bac5e..8f58da2 100644
--- a/egg/egg-bytes.c
+++ b/egg/egg-bytes.c
@@ -245,6 +245,7 @@ egg_bytes_unref (gpointer bytes)
{
if (bytes_->free_func != NULL)
bytes_->free_func (bytes_->user_data);
+ g_slice_free (EggBytes, bytes);
}
}
diff --git a/egg/egg-decimal.c b/egg/egg-decimal.c
index 6f3921d..422ec0c 100644
--- a/egg/egg-decimal.c
+++ b/egg/egg-decimal.c
@@ -97,5 +97,7 @@ egg_decimal_decode (const gchar *data,
memmove (usg, at_byte, length);
if (n_decoded)
*n_decoded = length;
+
+ g_free (digits);
return usg;
}
diff --git a/egg/egg-dh.c b/egg/egg-dh.c
index 85dec77..0a3ed5b 100644
--- a/egg/egg-dh.c
+++ b/egg/egg-dh.c
@@ -337,9 +337,9 @@ egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
#if DEBUG_DH_SECRET
g_printerr ("DH SECRET: ");
gcry_mpi_dump (k);
- gcry_mpi_release (k);
#endif
+ gcry_mpi_release (k);
*bytes = n_value;
#if DEBUG_DH_SECRET
diff --git a/egg/egg-dn.c b/egg/egg-dn.c
index 1edcd59..1452261 100644
--- a/egg/egg-dn.c
+++ b/egg/egg-dn.c
@@ -205,6 +205,7 @@ egg_dn_read_part (GNode *asn, const gchar *match)
GNode *node;
GQuark oid;
gint i, j;
+ gchar *result;
g_return_val_if_fail (asn, NULL);
g_return_val_if_fail (match, NULL);
@@ -236,7 +237,9 @@ egg_dn_read_part (GNode *asn, const gchar *match)
value = egg_asn1x_get_raw_element (node);
g_return_val_if_fail (value, NULL);
- return dn_print_oid_value (oid, egg_oid_get_flags (oid), value);
+ result = dn_print_oid_value (oid, egg_oid_get_flags (oid), value);
+ egg_bytes_unref (value);
+ return result;
}
}
diff --git a/egg/egg-hkdf.c b/egg/egg-hkdf.c
index a55ee5d..8cce3af 100644
--- a/egg/egg-hkdf.c
+++ b/egg/egg-hkdf.c
@@ -105,5 +105,6 @@ egg_hkdf_perform (const gchar *hash_algo, gconstpointer input, gsize n_input,
g_free (alloc);
gcry_free (buffer);
+ gcry_md_close (md2);
return TRUE;
}
diff --git a/egg/egg-openssl.c b/egg/egg-openssl.c
index dc38e2b..2433f07 100644
--- a/egg/egg-openssl.c
+++ b/egg/egg-openssl.c
@@ -375,6 +375,7 @@ egg_openssl_prep_dekinfo (GHashTable *headers)
g_return_val_if_fail (hex, NULL);
dekinfo = g_strdup_printf ("DES-EDE3-CBC,%s", hex);
g_free (hex);
+ g_free (iv);
g_hash_table_insert (headers, g_strdup ("DEK-Info"), (void*)dekinfo);
g_hash_table_insert (headers, g_strdup ("Proc-Type"), g_strdup ("4,ENCRYPTED"));
diff --git a/egg/egg-secure-memory.c b/egg/egg-secure-memory.c
index b190573..dca9bac 100644
--- a/egg/egg-secure-memory.c
+++ b/egg/egg-secure-memory.c
@@ -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.
*/
@@ -46,16 +46,10 @@
#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
-#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
@@ -65,33 +59,33 @@
/* 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
#define DO_LOCK() \
- egg_memory_lock ();
-
+ egg_memory_lock ();
+
#define DO_UNLOCK() \
egg_memory_unlock ();
static int lock_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 {
@@ -103,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 {
@@ -136,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.
*/
@@ -177,13 +171,13 @@ pool_alloc (void)
Pool *pool;
void *pages, *item;
size_t len, i;
-
+
/* A pool with an available item */
for (pool = all_pools; pool; pool = pool->next) {
if (unused_peek (&pool->unused))
break;
}
-
+
/* Create a new pool */
if (pool == NULL) {
len = getpagesize () * 2;
@@ -203,7 +197,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
@@ -225,9 +219,9 @@ pool_free (void* item)
{
Pool *pool, **at;
char *ptr, *beg, *end;
-
+
ptr = item;
-
+
/* Find which block this one belongs to */
for (at = &all_pools, pool = *at; pool; at = &pool->next, pool = *at) {
beg = (char*)pool->items;
@@ -272,17 +266,17 @@ pool_valid (void* item)
{
Pool *pool;
char *ptr, *beg, *end;
-
+
ptr = item;
-
+
/* Find which block this one belongs to */
for (pool = all_pools; 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;
}
@@ -290,9 +284,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.
*/
@@ -312,11 +306,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
@@ -324,16 +318,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
@@ -344,9 +338,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;
@@ -355,7 +349,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);
@@ -388,7 +382,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);
}
@@ -404,22 +398,43 @@ 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)
{
word_t *word;
-
+
ASSERT (cell);
ASSERT (block);
-
+
word = cell->words - 1;
if (!sec_is_valid_word (block, word))
return NULL;
@@ -427,7 +442,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);
@@ -438,14 +453,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;
@@ -456,7 +471,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
@@ -472,7 +487,7 @@ sec_alloc (Block *block,
Cell *cell, *other;
size_t n_words;
void *memory;
-
+
ASSERT (block);
ASSERT (length);
ASSERT (tag);
@@ -480,16 +495,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) {
@@ -499,7 +514,7 @@ sec_alloc (Block *block,
break;
}
}
-
+
if (!cell)
return NULL;
@@ -508,7 +523,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 ();
@@ -518,13 +533,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);
@@ -533,11 +548,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);
}
@@ -546,13 +561,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
@@ -567,7 +582,7 @@ sec_free (Block *block, void *memory)
#endif
sec_check_guards (cell);
- sec_clear_memory (memory, 0, cell->requested);
+ sec_clear_noaccess (memory, 0, cell->requested);
sec_check_guards (cell);
ASSERT (cell->requested > 0);
@@ -585,8 +600,8 @@ sec_free (Block *block, void *memory)
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) {
@@ -611,6 +626,34 @@ sec_free (Block *block, void *memory)
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,
const char *tag,
@@ -631,7 +674,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
@@ -639,7 +682,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);
@@ -658,21 +701,17 @@ sec_realloc (Block *block,
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.
- */
+ * 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... */
while (cell->n_words < n_words) {
@@ -680,7 +719,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;
@@ -697,26 +736,22 @@ sec_realloc (Block *block,
sec_write_guards (cell);
}
}
-
+
if (cell->n_words >= n_words) {
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, tag, length);
if (alloc) {
- memcpy (alloc, memory, valid);
+ memcpy_with_vbits (alloc, memory, valid);
sec_free (block, memory);
}
-
+
return alloc;
}
@@ -726,7 +761,7 @@ sec_allocated (Block *block, void *memory)
{
Cell *cell;
word_t *word;
-
+
ASSERT (block);
ASSERT (memory);
@@ -736,12 +771,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);
@@ -759,6 +794,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;
@@ -768,10 +808,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);
@@ -780,8 +820,8 @@ 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 */
+
+ /* An unused block */
} else {
ASSERT (cell->tag == NULL);
ASSERT (cell->next != NULL);
@@ -789,7 +829,7 @@ sec_validate (Block *block)
ASSERT (cell->next->prev == cell);
ASSERT (cell->prev->next == cell);
}
-
+
word += cell->n_words;
if (word == last)
break;
@@ -806,7 +846,7 @@ sec_acquire_pages (size_t *sz,
{
void *pages;
unsigned long pgsize;
-
+
ASSERT (sz);
ASSERT (*sz);
ASSERT (during_tag);
@@ -814,7 +854,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) {
@@ -824,7 +864,7 @@ sec_acquire_pages (size_t *sz,
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 memory (%s): %s\n",
@@ -834,12 +874,12 @@ sec_acquire_pages (size_t *sz,
munmap (pages, *sz);
return NULL;
}
-
+
DEBUG_ALLOC ("gkr-secure-memory: new block ", *sz);
-
+
lock_warning = 1;
return pages;
-
+
#else
if (lock_warning && egg_secure_warnings)
fprintf (stderr, "your system does not support private memory");
@@ -849,21 +889,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
@@ -875,7 +915,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)
{
@@ -884,10 +924,9 @@ sec_block_create (size_t size,
ASSERT (during_tag);
-#if FORCE_FALLBACK_MEMORY
/* We can force all all memory to be malloced */
- return NULL;
-#endif
+ if (getenv ("SECMEM_FORCE_FALLBACK"))
+ return NULL;
block = pool_alloc ();
if (!block)
@@ -902,7 +941,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) {
@@ -910,11 +949,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;
@@ -924,7 +963,7 @@ sec_block_create (size_t size,
block->next = all_blocks;
all_blocks = block;
-
+
return block;
}
@@ -937,7 +976,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) {
@@ -945,7 +984,7 @@ sec_block_destroy (Block *block)
break;
}
}
-
+
/* Must have been found */
ASSERT (bl == block);
ASSERT (block->used_cells == NULL);
@@ -956,7 +995,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));
@@ -980,35 +1019,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)) {
@@ -1016,10 +1055,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;
}
@@ -1039,20 +1078,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)) {
@@ -1067,10 +1106,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;
}
}
@@ -1081,19 +1120,19 @@ 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)) {
- /*
- * 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_memory_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 gnome-keyring: 0x%08lx\n",
(unsigned long)memory);
ASSERT (0 && "memory does does not belong to gnome-keyring");
return NULL;
@@ -1103,11 +1142,11 @@ egg_secure_realloc_full (const char *tag,
if (donew) {
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);
}
}
-
+
if (!alloc)
errno = ENOMEM;
@@ -1124,12 +1163,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))
@@ -1138,7 +1177,7 @@ 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
@@ -1147,49 +1186,49 @@ 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_memory_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 gnome-keyring: 0x%08lx\n",
(unsigned long)memory);
ASSERT (0 && "memory does does not belong to gnome-keyring");
}
}
-}
+}
-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 ();
}
@@ -1272,7 +1311,7 @@ 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;
@@ -1282,10 +1321,10 @@ void
egg_secure_clear (void *p, size_t length)
{
volatile char *vp;
-
+
if (p == NULL)
return;
-
+
vp = (volatile char*)p;
while (length) {
*vp = 0xAA;
@@ -1307,10 +1346,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/egg/egg-secure-memory.h b/egg/egg-secure-memory.h
index a2d7f04..682811d 100644
--- a/egg/egg-secure-memory.h
+++ b/egg/egg-secure-memory.h
@@ -27,31 +27,31 @@
#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:
*/
-
+
extern void egg_memory_lock (void);
extern void egg_memory_unlock (void);
/*
* Allocation Fallbacks
- *
+ *
* If we cannot allocate secure memory, then this function
- * (defined elsewhere) will be called which has a chance to
+ * (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
+ *
+ * Same call semantics as realloc with regard to NULL and zeros
*/
extern void* egg_memory_fallback (void *p, size_t length);
@@ -64,12 +64,12 @@ extern void* egg_memory_fallback (void *p, size_t length);
void* egg_memory_fallback (void *p, size_t sz) \
{ return g_realloc (p, sz); } \
-/*
+/*
* Main functionality
- *
+ *
* Allocations return NULL on failure.
- */
-
+ */
+
#define EGG_SECURE_USE_FALLBACK 0x0001
#define EGG_SECURE_DECLARE(tag) \
@@ -87,13 +87,13 @@ 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);
diff --git a/egg/egg-symkey.c b/egg/egg-symkey.c
index 835d4a3..71c1573 100644
--- a/egg/egg-symkey.c
+++ b/egg/egg-symkey.c
@@ -1196,6 +1196,5 @@ egg_symkey_read_mac (GQuark oid_scheme,
if (ret == FALSE)
g_message ("unsupported or invalid mac: %s", g_quark_to_string (oid_scheme));
- egg_bytes_unref (data);
return ret;
}
diff --git a/egg/egg-testing.c b/egg/egg-testing.c
index cd7f5c2..9f30ec6 100644
--- a/egg/egg-testing.c
+++ b/egg/egg-testing.c
@@ -30,21 +30,39 @@
#include <errno.h>
#include <unistd.h>
+#ifdef WITH_VALGRIND
+#include <valgrind/valgrind.h>
+#endif
+
+#if 0
static GCond *wait_condition = NULL;
static GCond *wait_start = NULL;
static GMutex *wait_mutex = NULL;
static gboolean wait_waiting = FALSE;
+#endif
+
+gboolean
+egg_testing_on_valgrind (void)
+{
+#ifdef WITH_VALGRIND
+ return RUNNING_ON_VALGRIND;
+#else
+ return FALSE
+#endif
+}
+
static const char HEXC[] = "0123456789ABCDEF";
-static gchar*
-hex_dump (const guchar *data, gsize n_data)
+gchar *
+egg_test_escape_data (const guchar *data,
+ gsize n_data)
{
GString *result;
gsize i;
guchar j;
- g_assert (data);
+ g_assert (data != NULL);
result = g_string_sized_new (n_data * 2 + 1);
for (i = 0; i < n_data; ++i) {
@@ -72,8 +90,8 @@ egg_assertion_message_cmpmem (const char *domain,
gsize n_arg2)
{
char *a1, *a2, *s;
- a1 = arg1 ? hex_dump (arg1, n_arg1) : g_strdup ("NULL");
- a2 = arg2 ? hex_dump (arg2, n_arg2) : g_strdup ("NULL");
+ a1 = arg1 ? egg_test_escape_data (arg1, n_arg1) : g_strdup ("NULL");
+ a2 = arg2 ? egg_test_escape_data (arg2, n_arg2) : g_strdup ("NULL");
s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
g_free (a1);
g_free (a2);
@@ -82,6 +100,29 @@ egg_assertion_message_cmpmem (const char *domain,
}
void
+egg_assertion_not_object (const char *domain,
+ const char *file,
+ int line,
+ const char *func,
+ const char *expr,
+ gpointer was_object)
+{
+ gchar *s;
+
+#ifdef WITH_VALGRIND
+ if (RUNNING_ON_VALGRIND)
+ return;
+#endif
+
+ if (G_IS_OBJECT (was_object)) {
+ s = g_strdup_printf ("assertion failed: %s is still referenced", expr);
+ g_assertion_message (domain, file, line, func, s);
+ g_free (s);
+ }
+}
+
+#if 0
+void
egg_test_wait_stop (void)
{
GTimeVal tv;
@@ -132,7 +173,7 @@ testing_thread (gpointer loop)
}
gint
-egg_tests_run_in_thread_with_loop (void)
+egg_tests_run_with_loop (void)
{
GThread *thread;
GMainLoop *loop;
@@ -153,7 +194,85 @@ egg_tests_run_in_thread_with_loop (void)
g_main_loop_unref (loop);
g_cond_free (wait_condition);
+ g_cond_free (wait_start);
g_mutex_free (wait_mutex);
return GPOINTER_TO_INT (ret);
}
+#endif
+
+
+static void (*wait_stop_impl) (void);
+static gboolean (*wait_until_impl) (int timeout);
+
+void
+egg_test_wait_stop (void)
+{
+ g_assert (wait_stop_impl != NULL);
+ (wait_stop_impl) ();
+}
+
+gboolean
+egg_test_wait_until (int timeout)
+{
+ g_assert (wait_until_impl != NULL);
+ return (wait_until_impl) (timeout);
+}
+
+static GMainLoop *wait_loop = NULL;
+
+static void
+loop_wait_stop (void)
+{
+ g_assert (wait_loop != NULL);
+ g_main_loop_quit (wait_loop);
+}
+
+static gboolean
+on_loop_wait_timeout (gpointer data)
+{
+ gboolean *timed_out = data;
+ *timed_out = TRUE;
+
+ g_assert (wait_loop != NULL);
+ g_main_loop_quit (wait_loop);
+
+ return TRUE; /* we remove this source later */
+}
+
+static gboolean
+loop_wait_until (int timeout)
+{
+ gboolean timed_out = FALSE;
+ guint source;
+
+ g_assert (wait_loop == NULL);
+ wait_loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
+
+ source = g_timeout_add (timeout, on_loop_wait_timeout, &timed_out);
+
+ g_main_loop_run (wait_loop);
+
+ g_source_remove (source);
+ g_main_loop_unref (wait_loop);
+ wait_loop = NULL;
+ return !timed_out;
+}
+
+gint
+egg_tests_run_with_loop (void)
+{
+ gint ret;
+
+ wait_stop_impl = loop_wait_stop;
+ wait_until_impl = loop_wait_until;
+
+ ret = g_test_run ();
+
+ wait_stop_impl = NULL;
+ wait_until_impl = NULL;
+
+ while (g_main_context_iteration (NULL, FALSE));
+
+ return ret;
+}
diff --git a/egg/egg-testing.h b/egg/egg-testing.h
index f6b7a0e..529443f 100644
--- a/egg/egg-testing.h
+++ b/egg/egg-testing.h
@@ -43,10 +43,25 @@ void egg_assertion_message_cmpmem (const char *domain, const char *
gsize n_arg1, const char *cmp,
gconstpointer arg2, gsize n_arg2);
+#define egg_assert_not_object(p) \
+ (egg_assertion_not_object (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, #p, (p)))
+
+void egg_assertion_not_object (const char *domain,
+ const char *file,
+ int line,
+ const char *func,
+ const char *expr,
+ gpointer was_object);
+
+gboolean egg_testing_on_valgrind (void);
+
+gchar * egg_test_escape_data (const guchar *data,
+ gsize size);
+
void egg_test_wait_stop (void);
gboolean egg_test_wait_until (int timeout);
-gint egg_tests_run_in_thread_with_loop (void);
+gint egg_tests_run_with_loop (void);
#endif /* EGG_DH_H_ */
diff --git a/egg/tests/Makefile.am b/egg/tests/Makefile.am
index 7ea9d25..536958d 100644
--- a/egg/tests/Makefile.am
+++ b/egg/tests/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_srcdir)/Makefile.decl
asn1-def-test.c: test.asn
$(ASN1PARSER) -o asn1-def-test.c $(srcdir)/test.asn
@@ -38,6 +39,8 @@ test: $(TEST_PROGS)
check-local: test
+check-memory: perform-memcheck
+
all-local: $(check_PROGRAMS)
EXTRA_DIST = \
diff --git a/egg/tests/test-asn1.c b/egg/tests/test-asn1.c
index 2ab9f52..222042b 100644
--- a/egg/tests/test-asn1.c
+++ b/egg/tests/test-asn1.c
@@ -405,7 +405,7 @@ test_bit_string_encode_decode (void)
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
- egg_asn1x_set_bits_as_raw (asn, egg_bytes_new (bits, 3), n_bits);
+ egg_asn1x_take_bits_as_raw (asn, egg_bytes_new (bits, 3), n_bits);
data = egg_asn1x_encode (asn, NULL);
g_assert (data);
@@ -467,7 +467,7 @@ test_bit_string_encode_decode_zero (void)
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
- egg_asn1x_set_bits_as_raw (asn, egg_bytes_new_static ("", 0), 0);
+ egg_asn1x_take_bits_as_raw (asn, egg_bytes_new_static ("", 0), 0);
data = egg_asn1x_encode (asn, NULL);
g_assert (data);
@@ -911,6 +911,7 @@ test_asn1_integers (Test* test, gconstpointer unused)
g_assert ("couldn't read integer from asn1" && ret);
g_assert_cmpuint (val, ==, 209384022);
+ egg_asn1x_destroy (asn);
egg_bytes_unref (data);
}
@@ -1047,11 +1048,12 @@ test_read_element (Test* test, gconstpointer unused)
data = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "data", NULL));
g_assert (data != NULL);
g_assert_cmpint (egg_bytes_get_size (data), ==, 11);
+ egg_bytes_unref (data);
data = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "data", NULL));
g_assert (data != NULL);
-
egg_assert_equal_bytes (data, "SOME DATA", 9);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
egg_bytes_unref (buffer);
diff --git a/egg/tests/test-hex.c b/egg/tests/test-hex.c
index e2cb9f0..93ad4bf 100644
--- a/egg/tests/test-hex.c
+++ b/egg/tests/test-hex.c
@@ -41,6 +41,8 @@ test_encode (void)
hex = egg_hex_encode (TEST_DATA, sizeof (TEST_DATA));
g_assert (hex);
g_assert_cmpstr (hex, ==, TEST_HEX);
+
+ g_free (hex);
}
static void
@@ -53,10 +55,14 @@ test_encode_spaces (void)
g_assert (hex);
g_assert_cmpstr (hex, ==, TEST_HEX);
+ g_free (hex);
+
/* Encode with spaces */
hex = egg_hex_encode_full (TEST_DATA, sizeof (TEST_DATA), TRUE, ' ', 1);
g_assert (hex);
g_assert_cmpstr (hex, ==, TEST_HEX_DELIM);
+
+ g_free (hex);
}
static void
diff --git a/egg/tests/test-openssl.c b/egg/tests/test-openssl.c
index d3d672e..57b0e8e 100644
--- a/egg/tests/test-openssl.c
+++ b/egg/tests/test-openssl.c
@@ -142,6 +142,8 @@ test_write_reference (Test *test, gconstpointer unused)
g_assert ("data length doesn't match input length" && n_encrypted == test->n_refenc);
g_assert ("data doesn't match input" && memcmp (encrypted, test->refenc, n_encrypted) == 0);
+
+ g_free (encrypted);
}
static void
@@ -206,6 +208,8 @@ test_openssl_roundtrip (Test *test, gconstpointer unused)
/* Check that the remainder is all zeros */
for (i = TEST_DATA_L; i < n_decrypted; ++i)
g_assert ("non null byte in padding" && decrypted[i] == 0);
+
+ egg_secure_free (decrypted);
}
int
diff --git a/egg/tests/test-padding.c b/egg/tests/test-padding.c
index 10a6c0e..5e10304 100644
--- a/egg/tests/test-padding.c
+++ b/egg/tests/test-padding.c
@@ -115,6 +115,8 @@ test_pkcs1_two_padding (void)
g_assert (result[5] == 0x00);
g_assert (result[6] == 'T');
g_assert (result[7] == 'E');
+
+ g_free (vesult);
}
static void
diff --git a/egg/tests/test-secmem.c b/egg/tests/test-secmem.c
index f5dbb7c..3a66fc4 100644
--- a/egg/tests/test-secmem.c
+++ b/egg/tests/test-secmem.c
@@ -97,6 +97,8 @@ test_realloc_across (void)
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/egg/tests/test-symkey.c b/egg/tests/test-symkey.c
index b65ee30..409ec44 100644
--- a/egg/tests/test-symkey.c
+++ b/egg/tests/test-symkey.c
@@ -138,6 +138,8 @@ test_generate_key_simple (void)
gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
g_assert (ret && "invalid simple key generated");
+
+ egg_secure_free (key);
}
}
@@ -165,6 +167,8 @@ test_generate_key_pkcs12 (void)
gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
g_assert ("invalid pkcs12 key generated" && ret);
+
+ egg_secure_free (key);
}
}
@@ -192,6 +196,8 @@ test_generate_key_pbkdf2 (void)
gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
g_assert ("invalid pbkdf2 key generated" && ret);
+
+ egg_secure_free (key);
}
}
@@ -220,6 +226,7 @@ test_generate_key_pbe (void)
g_assert ("invalid pbe key generated" && ret);
+ egg_secure_free (key);
}
}