[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