From 7ec98efee7a3f7d78eef60299d55f912b6fc0096 Mon Sep 17 00:00:00 2001 From: Vedant Ravindra Dhoke <66007382+vedant713@users.noreply.github.com> Date: Sat, 17 May 2025 15:52:26 -0400 Subject: [PATCH] Fix: Prevent out-of-bounds read in mi_ctz_generic32 and mi_clz_generic32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch ensures that both mi_ctz_generic32 and mi_clz_generic32 perform safe indexing into the de Bruijn lookup tables by masking the computed index with `& 31`. On platforms where unsigned long is 64-bit, the result of the de Bruijn multiplication and shift could exceed the valid index range (0–31), leading to an out-of-bounds read. This change applies a bitwise AND mask to the final index: - `mi_ctz_generic32`: debruijn[(((x & -(int32_t)x) * 0x077CB531U) >> 27) & 31] - `mi_clz_generic32`: debruijn[((x * 0x07C4ACDDU) >> 27) & 31] This matches the fix applied in python/cpython#134070 to its integrated mimalloc copy. Fixes: python/cpython#134070 --- include/mimalloc/internal.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/mimalloc/internal.h b/include/mimalloc/internal.h index eae85ab6..52e83069 100644 --- a/include/mimalloc/internal.h +++ b/include/mimalloc/internal.h @@ -976,7 +976,8 @@ static inline size_t mi_ctz_generic32(uint32_t x) { 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; if (x==0) return 32; - return debruijn[(uint32_t)((x & -(int32_t)x) * (uint32_t)(0x077CB531U)) >> 27]; + return debruijn[(((x & -(int32_t)x) * 0x077CB531U) >> 27) & 31]; + } static inline size_t mi_clz_generic32(uint32_t x) { @@ -991,7 +992,8 @@ static inline size_t mi_clz_generic32(uint32_t x) { x |= x >> 4; x |= x >> 8; x |= x >> 16; - return debruijn[(uint32_t)(x * (uint32_t)(0x07C4ACDDU)) >> 27]; + return debruijn[((x * 0x07C4ACDDU) >> 27) & 31]; + } static inline size_t mi_ctz(size_t x) {