aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2023-05-13 21:31:36 +1000
committerReza Arbab <arbab@linux.ibm.com>2023-06-06 13:32:12 -0500
commit1e7dd419df98a948506c918d66007a05a7aebce0 (patch)
treea00299d411c6e1bd55ba22c8dcea00ec6d40c7cf /core
parentd54c698de79f3a4c6bb04d8d744e0aca054629df (diff)
downloadskiboot-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.c24
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);