From 84ceba4a41c1a87b239bd9d75acf77e637bcb66f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 15 Apr 2024 10:36:47 +0200 Subject: [PATCH] Issue #876: Fix integer overflow on slice_count If the slice count doesn't fit into uint32_t, consider that the memory allocation failed. On Linux s390x, allocating around 8,589,934,592 GiB with mmap() works thanks to overcommit on a machine with 8 GiB of memory: mmap(NULL, 0x8000000000400000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0) --- src/segment.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/segment.c b/src/segment.c index e9032896..3d623976 100644 --- a/src/segment.c +++ b/src/segment.c @@ -820,6 +820,9 @@ static mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment const size_t extra = align_offset - info_size; // recalculate due to potential guard pages *psegment_slices = mi_segment_calculate_slices(required + extra, ppre_size, pinfo_slices); + + // gh-876: mi_page_t.slice_count type is uint32_t + if (*psegment_slices > (size_t)UINT32_MAX) return NULL; } const size_t segment_size = (*psegment_slices) * MI_SEGMENT_SLICE_SIZE; @@ -870,6 +873,9 @@ static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi size_t pre_size; size_t segment_slices = mi_segment_calculate_slices(required, &pre_size, &info_slices); + // gh-876: mi_page_t.slice_count type is uint32_t + if (segment_slices > (size_t)UINT32_MAX) return NULL; + // Commit eagerly only if not the first N lazy segments (to reduce impact of many threads that allocate just a little) const bool eager_delay = (// !_mi_os_has_overcommit() && // never delay on overcommit systems _mi_current_thread_count() > 1 && // do not delay for the first N threads