Skip to content

Commit

Permalink
Avoid signed overflow in DBG_FlushInstructionCache (#105918)
Browse files Browse the repository at this point in the history
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 <andrei.lalaev@anton-paar.com>
Co-authored-by: Andrei Lalaev <andrei.lalaev@anton-paar.com>
  • Loading branch information
AndreyLalaev and andrei-lalaev-AP authored Aug 21, 2024
1 parent d8b910b commit cfa8da5
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/coreclr/pal/src/thread/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit cfa8da5

Please sign in to comment.