[Swan-dev] pfree checks
Andrew Cagney
andrew.cagney at gmail.com
Sat Oct 7 17:29:26 UTC 2017
I'm considering a commit containing some of the below additional checks:
- try to spot a double free (I think this check should go in)
- try to spot a use-after-free, not so sure about this
- and there is also the possibility of a check for heap overflow
but these start to stray into checks that free() is doing anyway :-/
thoughts,
Andrew
diff --git a/lib/libswan/alloc.c b/lib/libswan/alloc.c
index ab6f3194b..c1f9824e7 100644
--- a/lib/libswan/alloc.c
+++ b/lib/libswan/alloc.c
@@ -61,6 +61,20 @@ void set_alloc_exit_log_func(exit_log_func_t func)
/* this magic number is 3671129837 decimal (623837458 complemented) */
#define LEAK_MAGIC 0xDAD0FEEDul
+#define INVALID_MAGIC 0xFE
+#if __SIZEOF_POINTER__ == 4
+#define INVALID_POINTER ((void*)0xFEFEFEFEul)
+#endif
+#if __SIZEOF_POINTER__ == 8
+#define INVALID_POINTER ((void*)0xFEFEFEFEFEFEFEFEull)
+#endif
+#ifndef INVALID_POINTER
+/* suppresses check */
+#define INVALID_POINTER NULL
+#endif
+
+static bool check_invalid_pointer = true;
+
union mhdr {
struct {
const char *name;
@@ -116,6 +130,9 @@ static void *alloc_bytes_raw(size_t size, const char
*name)
allocs = p;
pthread_mutex_unlock(&leak_detective_mutex);
}
+ if (p + 1 == INVALID_POINTER) {
+ check_invalid_pointer = false; /* sigh! */
+ }
return p + 1;
} else {
return p;
@@ -128,8 +145,20 @@ void pfree(void *ptr)
union mhdr *p;
passert(ptr != NULL);
+ if (check_invalid_pointer) {
+ if (ptr == INVALID_POINTER) {
+ PASSERT_FAIL("pointer %p invalid (likely from use after
free)", p);
+ }
+ }
+
p = ((union mhdr *)ptr) - 1;
- passert(p->i.magic == LEAK_MAGIC);
+
+ if (p->i.magic == ~LEAK_MAGIC) {
+ PASSERT_FAIL("pointer %p invalid (likely from double free)",
ptr);
+ } else if (p->i.magic != LEAK_MAGIC) {
+ PASSERT_FAIL("pointer %p invalid (likely from heap
corruption)", ptr);
+ }
+
{
pthread_mutex_lock(&leak_detective_mutex);
if (p->i.older != NULL) {
@@ -146,7 +175,7 @@ void pfree(void *ptr)
pthread_mutex_unlock(&leak_detective_mutex);
}
/* stomp on memory! Is another byte value better? */
- memset(p, 0xEF, sizeof(union mhdr) + p->i.size);
+ memset(p, INVALID_MAGIC, sizeof(union mhdr) + p->i.size);
p->i.magic = ~LEAK_MAGIC;
free(p);
} else {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.libreswan.org/pipermail/swan-dev/attachments/20171007/601498fa/attachment.html>
More information about the Swan-dev
mailing list