diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2023-05-13 21:31:36 +1000 |
---|---|---|
committer | Reza Arbab <arbab@linux.ibm.com> | 2023-06-06 13:32:12 -0500 |
commit | 1e7dd419df98a948506c918d66007a05a7aebce0 (patch) | |
tree | a00299d411c6e1bd55ba22c8dcea00ec6d40c7cf /core | |
parent | d54c698de79f3a4c6bb04d8d744e0aca054629df (diff) | |
download | skiboot-1e7dd419df98a948506c918d66007a05a7aebce0.zip skiboot-1e7dd419df98a948506c918d66007a05a7aebce0.tar.gz skiboot-1e7dd419df98a948506c918d66007a05a7aebce0.tar.bz2 |
core/malloc: Make free and realloc tolerant of invalid usage
Print a message if free or realloc are called on memory outside the
skiboot heap. Freeing is skipped to give the best chance of avoiding
a crash.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/malloc.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/core/malloc.c b/core/malloc.c index 76996ff..e20eafe 100644 --- a/core/malloc.c +++ b/core/malloc.c @@ -8,6 +8,8 @@ #include <mem_region.h> #include <lock.h> +#include <skiboot.h> +#include <stack.h> #include <string.h> #include <mem_region-malloc.h> @@ -29,8 +31,27 @@ void *__malloc(size_t bytes, const char *location) return __memalign(DEFAULT_ALIGN, bytes, location); } +static bool check_heap_ptr(const void *p) +{ + struct mem_region *region = &skiboot_heap; + unsigned long ptr = (unsigned long)p; + + if (!ptr) + return true; + + if (ptr < region->start || ptr > region->start + region->len) { + prerror("Trying to free() a pointer outside heap. Possibly local_alloc().\n"); + backtrace(); + return false; + } + return true; +} + void __free(void *p, const char *location) { + if (!check_heap_ptr(p)) + return; + lock(&skiboot_heap.free_list_lock); mem_free(&skiboot_heap, p, location); unlock(&skiboot_heap.free_list_lock); @@ -40,6 +61,9 @@ void *__realloc(void *ptr, size_t size, const char *location) { void *newptr; + if (!check_heap_ptr(ptr)) + return NULL; + /* Two classic malloc corner cases. */ if (!size) { __free(ptr, location); |