From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 74CC43858002; Tue, 17 Nov 2020 19:57:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 74CC43858002 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org, newlib-cvs@sourceware.org Subject: [newlib-cygwin] malloc/nano-malloc: correctly check for out-of-bounds allocation reqs X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/master X-Git-Oldrev: 14a1e7ce4288b8d3fde1359c73cb8805bcdf78a6 X-Git-Newrev: aa106b29a6a8a1b0df9e334704292cbc32f2d44e Message-Id: <20201117195756.74CC43858002@sourceware.org> Date: Tue, 17 Nov 2020 19:57:56 +0000 (GMT) X-BeenThere: newlib-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Newlib GIT logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Nov 2020 19:57:56 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=aa106b29a6a8a1b0df9e334704292cbc32f2d44e commit aa106b29a6a8a1b0df9e334704292cbc32f2d44e Author: Corinna Vinschen Date: Tue Nov 17 10:50:57 2020 +0100 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 Diff: --- newlib/libc/stdlib/mallocr.c | 7 ++++++- newlib/libc/stdlib/nano-mallocr.c | 22 +++++++++++++++++++++- winsup/cygwin/malloc.cc | 4 ++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/newlib/libc/stdlib/mallocr.c b/newlib/libc/stdlib/mallocr.c index 9ad720ada..13d014cc8 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 6dbfba84b..1e0703948 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 */ diff --git a/winsup/cygwin/malloc.cc b/winsup/cygwin/malloc.cc index 23c354074..8a1fc257e 100644 --- a/winsup/cygwin/malloc.cc +++ b/winsup/cygwin/malloc.cc @@ -5298,6 +5298,10 @@ void* dlpvalloc(size_t bytes) { size_t pagesz; ensure_initialization(); pagesz = mparams.page_size; + if (bytes > MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + return NULL; + } return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); }