You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2026/10/26 15:02:05 UTC
(mynewt-core) 02/07: libc/baselibc: Fix realloc failure handling
This is an automated email from the ASF dual-hosted git repository.
sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 0b2fa5ecb0e6c2e9620c73a007a07ee927b88829
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Sun Oct 25 23:23:27 2026 +0100
libc/baselibc: Fix realloc failure handling
When memory for a larger block could not be allocated, realloc
returned the original pointer instead of NULL, so the caller assumed
the block was enlarged and could write past it. For too large sizes
realloc freed the original block, while it must be left untouched on
failure.
Return NULL in both cases leaving the original block untouched. When
shrinking, the original block is still returned if allocation of new
block fails, as it is large enough.
Assisted-by: Claude:claude-opus-5-5
---
libc/baselibc/src/realloc.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/libc/baselibc/src/realloc.c b/libc/baselibc/src/realloc.c
index 52e983b0c..e78f4f03e 100644
--- a/libc/baselibc/src/realloc.c
+++ b/libc/baselibc/src/realloc.c
@@ -18,11 +18,16 @@ void *realloc(void *ptr, size_t size)
if (!ptr)
return malloc(size);
- if (size == 0 || size > (SIZE_MAX - 2 * sizeof(struct arena_header))) {
+ if (size == 0) {
free(ptr);
return NULL;
}
+ /* Make sure that adding arena header and rounding up does not wrap,
+ original block is left untouched on failure */
+ if (size > (SIZE_MAX - 2 * sizeof(struct arena_header)))
+ return NULL;
+
/* Add the obligatory arena header, and round up */
size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
@@ -40,12 +45,13 @@ void *realloc(void *ptr, size_t size)
oldsize = ah->a.size - sizeof(struct arena_header);
newptr = malloc(size);
- if (newptr) {
- memcpy(newptr, ptr, (size < oldsize) ? size : oldsize);
- free(ptr);
- } else {
- newptr = ptr;
- }
+ if (newptr) {
+ memcpy(newptr, ptr, (size < oldsize) ? size : oldsize);
+ free(ptr);
+ } else if (ah->a.size >= size) {
+ /* Shrinking, current block is still large enough */
+ newptr = ptr;
+ }
return newptr;
}
}