From 10614e04929a6d109a5e90524e446b637aaf0c13 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Sat, 3 Jan 2026 02:13:08 +0800 Subject: Fix: critical malloc size calculation bug Summary: - Fixed an integer arithmetic error in malloc() where 'nunits' was initialized to 0, causing incorrect heap sizing. - This bug caused malloc to return pointers pointing to unmapped memory pages, leading to Store Page Fault (scause 15) at process boundaries. - Switched memory allocator logic to use byte-based size calculation instead of K&R style units to prevent off-by-one errors. Improvements: - Shell now starts successfully without segfaults. --- src/ulib/stdlib.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/ulib/stdlib.c') diff --git a/src/ulib/stdlib.c b/src/ulib/stdlib.c index 30aa3a9..89d5a08 100644 --- a/src/ulib/stdlib.c +++ b/src/ulib/stdlib.c @@ -134,15 +134,12 @@ static header_t *morecore(size_t nu) void *malloc(size_t size) { header_t *p, *prevp; - size_t nunits = 0; if (size == 0) return NULL; size = ALIGN(size + sizeof(header_t)); - nunits = (nunits * sizeof(header_t) + ALIGNMENT - 1) / ALIGNMENT * ALIGNMENT / sizeof(header_t); - LOCK(); if ((prevp = freep) == NULL) @@ -161,9 +158,11 @@ void *malloc(size_t size) } else { - p->size -= (nunits * sizeof(header_t)); + p->size -= size; + p = (header_t *)((char *)p + p->size); - p->size = (nunits * sizeof(header_t)); + + p->size = size; } freep = prevp; UNLOCK(); @@ -172,7 +171,7 @@ void *malloc(size_t size) if (p == freep) { - if ((p = morecore(nunits * sizeof(header_t))) == NULL) + if ((p = morecore(size)) == NULL) { UNLOCK(); errno = ENOMEM; -- cgit v1.2.3