mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-05 19:35:52 +03:00
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.
This commit is contained in:
committed by
Arjun Shankar
parent
80647883cf
commit
8e448310d7
@@ -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));
|
||||
|
Reference in New Issue
Block a user