diff options
-rw-r--r-- | dbmalloc.c | 68 | ||||
-rw-r--r-- | dbmalloc.h | 2 | ||||
-rw-r--r-- | fuzzer-preauth.c | 3 | ||||
-rw-r--r-- | fuzzer-pubkey.c | 3 |
4 files changed, 46 insertions, 30 deletions
@@ -1,14 +1,17 @@ #include "dbmalloc.h" #include "dbutil.h" -#define LIST_SIZE 1000 - struct dbmalloc_header { - unsigned int index; unsigned int epoch; + struct dbmalloc_header *prev; + struct dbmalloc_header *next; }; -static struct dbmalloc_header* dbmalloc_list[LIST_SIZE]; +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; @@ -16,39 +19,50 @@ void m_malloc_set_epoch(unsigned int epoch) { current_epoch = epoch; } -void m_malloc_free_epoch(unsigned int epoch) { - unsigned int i; - unsigned int freed = 0; - for (i = 0; i < LIST_SIZE; i++) { - if (dbmalloc_list[i] != NULL) { - assert(dbmalloc_list[i]->index == i); - if (dbmalloc_list[i]->epoch == epoch) { - free(dbmalloc_list[i]); - dbmalloc_list[i] = NULL; - freed++; +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); } } - TRACE(("free_epoch freed %d", freed)) } static void put_alloc(struct dbmalloc_header *header) { - unsigned int i; - for (i = 0; i < LIST_SIZE; i++) { - if (dbmalloc_list[i] == NULL) { - dbmalloc_list[i] = header; - header->index = i; - return; - } + assert(header->next == NULL); + assert(header->prev == NULL); + if (staple) { + staple->prev = header; } - dropbear_exit("ran out of dbmalloc entries"); + header->next = staple; + staple = header; } static void remove_alloc(struct dbmalloc_header *header) { - assert(header->index < LIST_SIZE); - assert(dbmalloc_list[header->index] == header); - assert(header->epoch == current_epoch); - dbmalloc_list[header->index] = NULL; + 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) { @@ -11,6 +11,6 @@ void m_free_direct(void* ptr); #define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0) void m_malloc_set_epoch(unsigned int epoch); -void m_malloc_free_epoch(unsigned int epoch); +void m_malloc_free_epoch(unsigned int epoch, int dofree); #endif /* DBMALLOC_H_ */ diff --git a/fuzzer-preauth.c b/fuzzer-preauth.c index 110624e..247f11b 100644 --- a/fuzzer-preauth.c +++ b/fuzzer-preauth.c @@ -42,8 +42,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { m_malloc_set_epoch(1); if (setjmp(fuzz.jmp) == 0) { svr_session(fakesock, fakesock); + m_malloc_free_epoch(1, 0); } else { - m_malloc_free_epoch(1); + m_malloc_free_epoch(1, 1); TRACE(("dropbear_exit longjmped")) // dropbear_exit jumped here } diff --git a/fuzzer-pubkey.c b/fuzzer-pubkey.c index a5ec96e..c5b0e00 100644 --- a/fuzzer-pubkey.c +++ b/fuzzer-pubkey.c @@ -33,8 +33,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { fuzz_checkpubkey_line(fuzz.input, 5, "/home/me/authorized_keys", algoname, strlen(algoname), keyblob, strlen(keyblob)); + m_malloc_free_epoch(1, 0); } else { - m_malloc_free_epoch(1); + m_malloc_free_epoch(1, 1); TRACE(("dropbear_exit longjmped")) // dropbear_exit jumped here } |