mirror of
https://abf.rosa.ru/djam/glibc40.git
synced 2025-02-23 15:52:52 +00:00
86 lines
3.3 KiB
Diff
86 lines
3.3 KiB
Diff
From 8e448310d74b283c5cd02b9ed7fb997b47bf9b22 Mon Sep 17 00:00:00 2001
|
|
From: Arjun Shankar <arjun.is@lostca.se>
|
|
Date: Thu, 18 Jan 2018 16:47:06 +0000
|
|
Subject: [PATCH] Fix integer overflows in internal memalign and malloc
|
|
functions [BZ #22343]
|
|
|
|
When posix_memalign is called with an alignment less than MALLOC_ALIGNMENT
|
|
and a requested size close to SIZE_MAX, it falls back to malloc code
|
|
(because the alignment of a block returned by malloc is sufficient to
|
|
satisfy the call). In this case, an integer overflow in _int_malloc leads
|
|
to posix_memalign incorrectly returning successfully.
|
|
|
|
Upon fixing this and writing a somewhat thorough regression test, it was
|
|
discovered that when posix_memalign is called with an alignment larger than
|
|
MALLOC_ALIGNMENT (so it uses _int_memalign instead) and a requested size
|
|
close to SIZE_MAX, a different integer overflow in _int_memalign leads to
|
|
posix_memalign incorrectly returning successfully.
|
|
|
|
Both integer overflows affect other memory allocation functions that use
|
|
_int_malloc (one affected malloc in x86) or _int_memalign as well.
|
|
|
|
This commit fixes both integer overflows. In addition to this, it adds a
|
|
regression test to guard against false successful allocations by the
|
|
following memory allocation functions when called with too-large allocation
|
|
sizes and, where relevant, various valid alignments:
|
|
malloc, realloc, calloc, reallocarray, memalign, posix_memalign,
|
|
aligned_alloc, valloc, and pvalloc.
|
|
---
|
|
ChangeLog | 10 ++
|
|
malloc/Makefile | 1 +
|
|
malloc/malloc.c | 30 +++--
|
|
malloc/tst-malloc-too-large.c | 253 ++++++++++++++++++++++++++++++++++++++++++
|
|
4 files changed, 286 insertions(+), 8 deletions(-)
|
|
create mode 100644 malloc/tst-malloc-too-large.c
|
|
|
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
|
index f5aafd2..7889fb1 100644
|
|
--- a/malloc/malloc.c
|
|
+++ b/malloc/malloc.c
|
|
@@ -1224,14 +1224,21 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
MINSIZE : \
|
|
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
|
|
|
|
-/* Same, except also perform argument check */
|
|
-
|
|
-#define checked_request2size(req, sz) \
|
|
- if (REQUEST_OUT_OF_RANGE (req)) { \
|
|
- __set_errno (ENOMEM); \
|
|
- return 0; \
|
|
- } \
|
|
- (sz) = request2size (req);
|
|
+/* Same, except also perform an argument and result check. First, we check
|
|
+ that the padding done by request2size didn't result in an integer
|
|
+ overflow. Then we check (using REQUEST_OUT_OF_RANGE) that the resulting
|
|
+ size isn't so large that a later alignment would lead to another integer
|
|
+ overflow. */
|
|
+#define checked_request2size(req, sz) \
|
|
+({ \
|
|
+ (sz) = request2size (req); \
|
|
+ if (((sz) < (req)) \
|
|
+ || REQUEST_OUT_OF_RANGE (sz)) \
|
|
+ { \
|
|
+ __set_errno (ENOMEM); \
|
|
+ return 0; \
|
|
+ } \
|
|
+})
|
|
|
|
/*
|
|
--------------- Physical chunk operations ---------------
|
|
@@ -4678,6 +4685,13 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
|
|
*/
|
|
|
|
|
|
+ /* Check for overflow. */
|
|
+ if (nb > SIZE_MAX - alignment - MINSIZE)
|
|
+ {
|
|
+ __set_errno (ENOMEM);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
/* Call malloc with worst case padding to hit alignment. */
|
|
|
|
m = (char *) (_int_malloc (av, nb + alignment + MINSIZE));
|
|
--
|
|
2.9.3
|
|
|