From e90526faa3cb109bbc011c6fefa81b94cd36e6b6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:29:43 -0700 Subject: [PATCH] Avoid signed overflow in DBG_FlushInstructionCache (#106823) On ARM32 Linux we can have an infinite loop because of integer overflow. For example, if DBG_FlushInstructionCache is called with the following parameters & locals: dwSize = 28 pageSize = 4096 begin = lpBaseAddress = 0x7ffff000 end = begin + dwSize = 0x7ffff01c ALIGN_UP(0x7ffff000, 4096) returns 0x80000000 which is actually a negative number because INT_PTR is just int32_t (on ARM32). And here we are getting an infinite loop because "begin" will never be greater or equal than "end". So, this issue is related to all addresses between INT32_MAX - PAGE_SIZE and INT32_MAX because ALIGN_UP returns the address of the next page which will be greater or equal to INT32_MAX Signed-off-by: Andrei Lalaev Co-authored-by: Andrei Lalaev --- src/coreclr/pal/src/thread/context.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/pal/src/thread/context.cpp b/src/coreclr/pal/src/thread/context.cpp index 2abec3970f1e02..5154ee3c8800f3 100644 --- a/src/coreclr/pal/src/thread/context.cpp +++ b/src/coreclr/pal/src/thread/context.cpp @@ -2068,12 +2068,12 @@ DBG_FlushInstructionCache( // As a workaround, we call __builtin___clear_cache on each page separately. const SIZE_T pageSize = GetVirtualPageSize(); - INT_PTR begin = (INT_PTR)lpBaseAddress; - const INT_PTR end = begin + dwSize; + UINT_PTR begin = (UINT_PTR)lpBaseAddress; + const UINT_PTR end = begin + dwSize; while (begin < end) { - INT_PTR endOrNextPageBegin = ALIGN_UP(begin + 1, pageSize); + UINT_PTR endOrNextPageBegin = ALIGN_UP(begin + 1, pageSize); if (endOrNextPageBegin > end) endOrNextPageBegin = end;