diff dbmalloc.c @ 1580:7f2be495dff6 coverity

merge coverity
author Matt Johnston <matt@ucc.asn.au>
date Sun, 04 Mar 2018 15:07:09 +0800
parents c42e8ff42bd1
children 1051e4eea25a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbmalloc.c	Sun Mar 04 15:07:09 2018 +0800
@@ -0,0 +1,182 @@
+#include "dbmalloc.h"
+#include "dbutil.h"
+
+
+void * m_calloc(size_t nmemb, size_t size) {
+    if (SIZE_T_MAX / nmemb < size) {
+        dropbear_exit("m_calloc failed");
+    }
+    return m_malloc(nmemb*size);
+}
+
+void * m_strdup(const char * str) {
+    char* ret;
+    unsigned int len;
+    len = strlen(str);
+
+    ret = m_malloc(len+1);
+    if (ret == NULL) {
+        dropbear_exit("m_strdup failed");
+    }
+    memcpy(ret, str, len+1);
+    return ret;
+}
+
+#if !DROPBEAR_TRACKING_MALLOC
+
+/* Simple wrappers around malloc etc */
+void * m_malloc(size_t size) {
+
+	void* ret;
+
+	if (size == 0) {
+		dropbear_exit("m_malloc failed");
+	}
+	ret = calloc(1, size);
+	if (ret == NULL) {
+		dropbear_exit("m_malloc failed");
+	}
+	return ret;
+
+}
+
+void * m_realloc(void* ptr, size_t size) {
+
+	void *ret;
+
+	if (size == 0) {
+		dropbear_exit("m_realloc failed");
+	}
+	ret = realloc(ptr, size);
+	if (ret == NULL) {
+		dropbear_exit("m_realloc failed");
+	}
+	return ret;
+}
+
+
+#else
+
+/* For fuzzing */
+
+struct dbmalloc_header {
+    unsigned int epoch;
+    struct dbmalloc_header *prev;
+    struct dbmalloc_header *next;
+};
+
+static void put_alloc(struct dbmalloc_header *header);
+static void remove_alloc(struct dbmalloc_header *header);
+
+/* end of the linked list */
+static struct dbmalloc_header* staple;
+
+unsigned int current_epoch = 0;
+
+void m_malloc_set_epoch(unsigned int epoch) {
+    current_epoch = epoch;
+}
+
+void m_malloc_free_epoch(unsigned int epoch, int dofree) {
+    struct dbmalloc_header* header;
+    struct dbmalloc_header* nextheader = NULL;
+    struct dbmalloc_header* oldstaple = staple;
+    staple = NULL;
+    /* free allocations from this epoch, create a new staple-anchored list from
+    the remainder */
+    for (header = oldstaple; header; header = nextheader)
+    {
+        nextheader = header->next;
+        if (header->epoch == epoch) {
+            if (dofree) {
+                free(header);
+            }
+        } else {
+            header->prev = NULL;
+            header->next = NULL;
+            put_alloc(header);
+        }
+    }
+}
+
+static void put_alloc(struct dbmalloc_header *header) {
+    assert(header->next == NULL);
+    assert(header->prev == NULL);
+    if (staple) {
+        staple->prev = header;
+    }
+    header->next = staple;
+    staple = header;
+}
+
+static void remove_alloc(struct dbmalloc_header *header) {
+    if (header->prev) {
+        header->prev->next = header->next;
+    }
+    if (header->next) {
+        header->next->prev = header->prev;
+    }
+    if (staple == header) {
+        staple = header->next;
+    }
+    header->prev = NULL;
+    header->next = NULL;
+}
+
+static struct dbmalloc_header* get_header(void* ptr) {
+    char* bptr = ptr;
+    return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)];
+}
+
+void * m_malloc(size_t size) {
+    char* mem = NULL;
+    struct dbmalloc_header* header = NULL;
+
+    if (size == 0 || size > 1e9) {
+        dropbear_exit("m_malloc failed");
+    }
+
+    size = size + sizeof(struct dbmalloc_header);
+
+    mem = calloc(1, size);
+    if (mem == NULL) {
+        dropbear_exit("m_malloc failed");
+    }
+    header = (struct dbmalloc_header*)mem;
+    put_alloc(header);
+    header->epoch = current_epoch;
+    return &mem[sizeof(struct dbmalloc_header)];
+}
+
+void * m_realloc(void* ptr, size_t size) {
+    char* mem = NULL;
+    struct dbmalloc_header* header = NULL;
+    if (size == 0 || size > 1e9) {
+        dropbear_exit("m_realloc failed");
+    }
+
+    header = get_header(ptr);
+    remove_alloc(header);
+
+    size = size + sizeof(struct dbmalloc_header);
+    mem = realloc(header, size);
+    if (mem == NULL) {
+        dropbear_exit("m_realloc failed");
+    }
+
+    header = (struct dbmalloc_header*)mem;
+    put_alloc(header);
+    return &mem[sizeof(struct dbmalloc_header)];
+}
+
+void m_free_direct(void* ptr) {
+    struct dbmalloc_header* header = NULL;
+    if (!ptr) {
+        return;
+    }
+    header = get_header(ptr);
+    remove_alloc(header);
+    free(header);
+}
+
+#endif /* DROPBEAR_TRACKING_MALLOC */