diff options
author | Corinna Vinschen <vinschen@redhat.com> | 2020-11-17 10:50:57 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2020-11-17 10:52:34 +0100 |
commit | aa106b29a6a8a1b0df9e334704292cbc32f2d44e (patch) | |
tree | e916aa9f4981dee2ed690ae40ee86091d7abb10e /newlib/libc | |
parent | 14a1e7ce4288b8d3fde1359c73cb8805bcdf78a6 (diff) | |
download | newlib-aa106b29a6a8a1b0df9e334704292cbc32f2d44e.zip newlib-aa106b29a6a8a1b0df9e334704292cbc32f2d44e.tar.gz newlib-aa106b29a6a8a1b0df9e334704292cbc32f2d44e.tar.bz2 |
malloc/nano-malloc: correctly check for out-of-bounds allocation reqs
The overflow check in mEMALIGn erroneously checks for INT_MAX,
albeit the input parameter is size_t. Fix this to check for
__SIZE_MAX__ instead. Also, it misses to check the req against
adding the alignment before calling mALLOc.
While at it, add out-of-bounds checks to pvALLOc, nano_memalign,
nano_valloc, and Cygwin's (unused) dlpvalloc.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'newlib/libc')
-rw-r--r-- | newlib/libc/stdlib/mallocr.c | 7 | ||||
-rw-r--r-- | newlib/libc/stdlib/nano-mallocr.c | 22 |
2 files changed, 27 insertions, 2 deletions
diff --git a/newlib/libc/stdlib/mallocr.c b/newlib/libc/stdlib/mallocr.c index 9ad720a..13d014c 100644 --- a/newlib/libc/stdlib/mallocr.c +++ b/newlib/libc/stdlib/mallocr.c @@ -3055,7 +3055,7 @@ Void_t* mEMALIGn(RARG alignment, bytes) RDECL size_t alignment; size_t bytes; nb = request2size(bytes); /* Check for overflow. */ - if (nb > INT_MAX || nb < bytes) + if (nb > __SIZE_MAX__ - (alignment + MINSIZE) || nb < bytes) { RERRNO = ENOMEM; return 0; @@ -3172,6 +3172,11 @@ Void_t* pvALLOc(RARG bytes) RDECL size_t bytes; #endif { size_t pagesize = malloc_getpagesize; + if (bytes > __SIZE_MAX__ - pagesize) + { + RERRNO = ENOMEM; + return 0; + } return mEMALIGn (RCALL pagesize, (bytes + pagesize - 1) & ~(pagesize - 1)); } diff --git a/newlib/libc/stdlib/nano-mallocr.c b/newlib/libc/stdlib/nano-mallocr.c index 6dbfba8..1e07039 100644 --- a/newlib/libc/stdlib/nano-mallocr.c +++ b/newlib/libc/stdlib/nano-mallocr.c @@ -580,8 +580,22 @@ void * nano_memalign(RARG size_t align, size_t s) if ((align & (align-1)) != 0) return NULL; align = MAX(align, MALLOC_ALIGN); + + /* Make sure ma_size does not overflow */ + if (s > __SIZE_MAX__ - CHUNK_ALIGN) + { + RERRNO = ENOMEM; + return NULL; + } ma_size = ALIGN_SIZE(MAX(s, MALLOC_MINSIZE), CHUNK_ALIGN); - size_with_padding = ma_size + align - MALLOC_ALIGN; + + /* Make sure size_with_padding does not overflow */ + if (ma_size > __SIZE_MAX__ - (align - MALLOC_ALIGN)) + { + RERRNO = ENOMEM; + return NULL; + } + size_with_padding = ma_size + (align - MALLOC_ALIGN); allocated = nano_malloc(RCALL size_with_padding); if (allocated == NULL) return NULL; @@ -644,6 +658,12 @@ void * nano_valloc(RARG size_t s) #ifdef DEFINE_PVALLOC void * nano_pvalloc(RARG size_t s) { + /* Make sure size given to nano_valloc does not overflow */ + if (s > __SIZE_MAX__ - MALLOC_PAGE_ALIGN) + { + RERRNO = ENOMEM; + return NULL; + } return nano_valloc(RCALL ALIGN_SIZE(s, MALLOC_PAGE_ALIGN)); } #endif /* DEFINE_PVALLOC */ |