From 8a757c2d4020548aeb866866c7f36c99d06a3a1f Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Thu, 25 Jun 2026 12:29:32 +0200 Subject: [PATCH 1/2] [mono] Fix lock-free mempool chunk under-allocation by 8 bytes lock_free_mempool_chunk_new sized each chunk by reserving sizeof(LockFreeMempoolChunk) (24 bytes on 64-bit), but chunk->mem is then aligned up to 16 bytes, so the usable region starts at offset 32 and a single-page chunk only has pagesize-32 usable bytes. A request whose length is congruent to -24 (mod pagesize) - e.g. 4072 on 4 KB pages, 16360 on 16 KB pages - produced a freshly allocated chunk whose size (pagesize-32) is smaller than the requested length, tripping g_assert (chunk->pos + size <= GINT_TO_UINT(chunk->size)); in lock_free_mempool_alloc0 and aborting the runtime. This pool is used on the async AOT unwind/exception-info decode path (mono_aot_get_unwind_info / decode_exception_debug_info with async==TRUE), which is driven by the EventPipe SampleProfiler stack walk, so the crash showed up intermittently as a SIGABRT during eventpipe tracing tests under Mono LLVM full-AOT on x64. Fix: reserve the 16-byte-aligned header size in the sizing loop so the chunk always has room for the request. --- src/mono/mono/metadata/memory-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/memory-manager.c b/src/mono/mono/metadata/memory-manager.c index e7a234661db5a3..fc38cf8374ee64 100644 --- a/src/mono/mono/metadata/memory-manager.c +++ b/src/mono/mono/metadata/memory-manager.c @@ -38,7 +38,7 @@ lock_free_mempool_chunk_new (LockFreeMempool *mp, int len) int size; size = mono_pagesize (); - while (size - sizeof (LockFreeMempoolChunk) < GINT_TO_UINT(len)) + while (size - ALIGN_TO (sizeof (LockFreeMempoolChunk), 16) < GINT_TO_UINT(len)) size += mono_pagesize (); chunk = (LockFreeMempoolChunk *)mono_valloc (0, size, MONO_MMAP_READ|MONO_MMAP_WRITE, MONO_MEM_ACCOUNT_MEM_MANAGER); g_assert (chunk); From 7ce5ae1bb505250fc58df0f6d043d4dd66ca617f Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 25 Jun 2026 16:44:26 +0200 Subject: [PATCH 2/2] fix --- src/mono/mono/metadata/memory-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/memory-manager.c b/src/mono/mono/metadata/memory-manager.c index fc38cf8374ee64..9d46995c850096 100644 --- a/src/mono/mono/metadata/memory-manager.c +++ b/src/mono/mono/metadata/memory-manager.c @@ -38,7 +38,7 @@ lock_free_mempool_chunk_new (LockFreeMempool *mp, int len) int size; size = mono_pagesize (); - while (size - ALIGN_TO (sizeof (LockFreeMempoolChunk), 16) < GINT_TO_UINT(len)) + while (size - ALIGN_TO (sizeof (LockFreeMempoolChunk), 16) < len) size += mono_pagesize (); chunk = (LockFreeMempoolChunk *)mono_valloc (0, size, MONO_MMAP_READ|MONO_MMAP_WRITE, MONO_MEM_ACCOUNT_MEM_MANAGER); g_assert (chunk);