[PATCH] Erase memory before freeing.
Ben Kibbey
bjk at luxsci.net
Mon Aug 1 01:12:37 CEST 2016
* src/mem.h: New.
* src/assuan-support.c (mem_item_s): New.
(_gpgme_assuan_malloc_hooks): Replace to use tracking functions.
(_gpgme_assuan_malloc): New.
(_gpgme_assuan_realloc): Ditto.
(_gpgme_assuan_free): Ditto.
(free_locked): Ditto.
(find_memlist_item): Ditto.
* src/data-compat.c (gpgme_data_new_from_filepart): Wipe memory.
* src/data-identify.c (gpgme_data_identify): Ditto.
* src/data.c (_gpgme_data_release): Ditto.
Signed-off-by: Ben Kibbey <bjk at luxsci.net>
---
src/assuan-support.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++--
src/data-compat.c | 11 +++-
src/data-identify.c | 3 ++
src/data-mem.c | 6 ++-
src/data.c | 5 ++
5 files changed, 160 insertions(+), 6 deletions(-)
diff --git a/src/assuan-support.c b/src/assuan-support.c
index 745d2aa..7e27d1f 100644
--- a/src/assuan-support.c
+++ b/src/assuan-support.c
@@ -9,16 +9,151 @@
#include "assuan.h"
#include "gpgme.h"
+#include "sema.h"
#include "ath.h"
#include "priv-io.h"
+#include "mem.h"
#include "debug.h"
+DEFINE_STATIC_LOCK (memlist_lock);
+
+
+struct mem_item_s
+{
+ size_t size;
+ void *data;
+ struct mem_item_s *next;
+};
+
+static struct mem_item_s *memlist;
+
+
+static struct mem_item_s *
+find_memlist_item (void *p, int remove)
+{
+ struct mem_item_s *item, *last = NULL;
+
+ for (item = memlist; item; item = item->next)
+ {
+ if (item->data == p)
+ {
+ if (remove)
+ {
+ if (last)
+ last->next = item->next;
+ else
+ memlist = item->next;
+ }
+
+ break;
+ }
+
+ last = item;
+ }
+
+ return item;
+}
+
+
+static void
+free_locked (void *p, int locked)
+{
+ struct mem_item_s *item;
+
+ if (!locked)
+ LOCK (memlist_lock);
+
+ item = find_memlist_item (p, 1);
+ assert (item);
+
+ if (!locked)
+ UNLOCK (memlist_lock);
+
+ wipememory (item->data, item->size);
+ free (item->data);
+ free (item);
+}
+
+
+static void
+_gpgme_assuan_free (void *p)
+{
+ if (!p)
+ return;
+
+ free_locked (p, 0);
+}
+
+
+static void *
+_gpgme_assuan_malloc (size_t n)
+{
+ struct mem_item_s *item;
+ void *p;
+
+ p = malloc (n);
+ if (!p)
+ return NULL;
+
+ item = malloc (sizeof (struct mem_item_s));
+ if (!item)
+ {
+ int e = errno;
+ free (p);
+ errno = e;
+ return NULL;
+ }
+
+ item->data = p;
+ item->size = n;
+ LOCK (memlist_lock);
+ item->next = memlist;
+ memlist = item;
+ UNLOCK (memlist_lock);
+ return item->data;
+}
+
+
+static void *
+_gpgme_assuan_realloc (void *p, size_t n)
+{
+ struct mem_item_s *item;
+ struct mem_item_s *newitem;
+ void *tmp;
+
+ LOCK (memlist_lock);
+ item = find_memlist_item (p, 0);
+ if (!item)
+ {
+ UNLOCK (memlist_lock);
+ return _gpgme_assuan_malloc (n);
+ }
+
+ tmp = _gpgme_assuan_malloc (n);
+ if (tmp)
+ newitem = find_memlist_item (tmp, 0);
+ else
+ {
+ int e = errno;
+ UNLOCK (memlist_lock);
+ errno = e;
+ return NULL;
+ }
+
+ assert (newitem);
+ memcpy (newitem->data, item->data,
+ newitem->size < item->size ? newitem->size : item->size);
+ free_locked (item->data, 1);
+ UNLOCK (memlist_lock);
+ return newitem->data;
+}
+
struct assuan_malloc_hooks _gpgme_assuan_malloc_hooks =
{
- malloc,
- realloc,
- free
+ _gpgme_assuan_malloc,
+ _gpgme_assuan_realloc,
+ _gpgme_assuan_free
};
diff --git a/src/data-compat.c b/src/data-compat.c
index ec80172..44a2b94 100644
--- a/src/data-compat.c
+++ b/src/data-compat.c
@@ -33,6 +33,7 @@
#include "data.h"
#include "util.h"
+#include "mem.h"
#include "debug.h"
@@ -92,7 +93,10 @@ gpgme_data_new_from_filepart (gpgme_data_t *r_dh, const char *fname,
{
int saved_err = gpg_error_from_syserror ();
if (buf)
- free (buf);
+ {
+ wipememory (buf, length);
+ free (buf);
+ }
if (fname)
fclose (stream);
return TRACE_ERR (saved_err);
@@ -105,7 +109,10 @@ gpgme_data_new_from_filepart (gpgme_data_t *r_dh, const char *fname,
if (err)
{
if (buf)
- free (buf);
+ {
+ wipememory (buf, length);
+ free (buf);
+ }
return err;
}
diff --git a/src/data-identify.c b/src/data-identify.c
index 88a472f..8b41395 100644
--- a/src/data-identify.c
+++ b/src/data-identify.c
@@ -28,6 +28,7 @@
#include "data.h"
#include "util.h"
#include "parsetlv.h"
+#include "mem.h"
/* The size of the sample data we take for detection. */
@@ -496,12 +497,14 @@ gpgme_data_identify (gpgme_data_t dh, int reserved)
n = gpgme_data_read (dh, sample, SAMPLE_SIZE - 1);
if (n < 0)
{
+ wipememory (sample, SAMPLE_SIZE);
free (sample);
return GPGME_DATA_TYPE_INVALID; /* Ooops. */
}
sample[n] = 0; /* (Required for our string functions.) */
result = basic_detection (sample, n);
+ wipememory (sample, SAMPLE_SIZE);
free (sample);
gpgme_data_seek (dh, off, SEEK_SET);
diff --git a/src/data-mem.c b/src/data-mem.c
index a498b82..4fe871a 100644
--- a/src/data-mem.c
+++ b/src/data-mem.c
@@ -32,6 +32,7 @@
#include "data.h"
#include "util.h"
+#include "mem.h"
#include "debug.h"
@@ -151,7 +152,10 @@ static void
mem_release (gpgme_data_t dh)
{
if (dh->data.mem.buffer)
- free (dh->data.mem.buffer);
+ {
+ wipememory (dh->data.mem.buffer, dh->data.mem.size);
+ free (dh->data.mem.buffer);
+ }
}
diff --git a/src/data.c b/src/data.c
index 87b619e..1b8aacc 100644
--- a/src/data.c
+++ b/src/data.c
@@ -34,6 +34,7 @@
#include "util.h"
#include "ops.h"
#include "priv-io.h"
+#include "mem.h"
#include "debug.h"
@@ -65,6 +66,8 @@ _gpgme_data_release (gpgme_data_t dh)
if (dh->file_name)
free (dh->file_name);
+
+ wipememory (dh->pending, sizeof (dh->pending));
free (dh);
}
@@ -275,6 +278,8 @@ _gpgme_data_inbound_handler (void *opaque, int fd)
buflen -= amt;
}
while (buflen > 0);
+
+ wipememory (buffer, sizeof (buffer));
return TRACE_ERR (0);
}
--
2.8.1
More information about the Gnupg-devel
mailing list