Skip to content

mprotect last page of CodeBuffer#4540

Merged
Sonicadvance1 merged 1 commit intoFEX-Emu:mainfrom
pmatos:MProtectLastPage
Apr 27, 2025
Merged

mprotect last page of CodeBuffer#4540
Sonicadvance1 merged 1 commit intoFEX-Emu:mainfrom
pmatos:MProtectLastPage

Conversation

@pmatos
Copy link
Copy Markdown
Collaborator

@pmatos pmatos commented Apr 25, 2025

protects last page of codebuffer. This should cause a SIGSEGV if we try to access it. Until now it was possible to go over and access out of bounds.

In addition, there a couple of clang-tidy fixes which should be NFC.

@pmatos pmatos force-pushed the MProtectLastPage branch from 124f3f5 to 0622184 Compare April 25, 2025 13:34

// Protect the last page of the allocated buffer to trigger SIGSEGV on write access
#ifndef _WIN32
const long pageSize = sysconf(_SC_PAGESIZE);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FEXCore::Utils::FEX_PAGE_MASK can be used here instead. We already hardcode the assumption of 4K pages in other places.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL - thanks


// Resize the code buffer and reallocate our code size
CurrentCodeBuffer->Size *= 1.5;
CurrentCodeBuffer->Size = (CurrentCodeBuffer->Size >> 1) * 3; // * 1.5
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of replacing readable code with less obvious bit-shifting tricks just to save hypothetical CPU cycles. #4479 changes this to a flat 2.0 anyway, so could we drop this for now?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

me neither and you're right. I made this less readable to silence a clang-tidy warning about multiplying an integer by a float.

uintptr_t lastPageAddr = reinterpret_cast<uintptr_t>(Buffer.Ptr) + Buffer.Size - pageSize;
lastPageAddr = lastPageAddr & ~(pageSize - 1);

if (mprotect(reinterpret_cast<void*>(lastPageAddr), pageSize, PROT_NONE) != 0) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use VirtualProtect here which is generic - and you'll probably want to adjust the CodeSize check to trigger a resize a page earlier

const long pageSize = sysconf(_SC_PAGESIZE);
if (pageSize > 0 && Buffer.Size >= (size_t)pageSize) {
uintptr_t lastPageAddr = reinterpret_cast<uintptr_t>(Buffer.Ptr) + Buffer.Size - pageSize;
lastPageAddr = lastPageAddr & ~(pageSize - 1);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AlignDown(reinterpret_cast<uintptr_t>(Buffer.Ptr) + Buffer.Size - 1, FEXCore::Utils::FEX_PAGE_SIZE)
Might be cleaner

@pmatos pmatos force-pushed the MProtectLastPage branch from 0622184 to 39e2a83 Compare April 25, 2025 15:53
Copy link
Copy Markdown
Collaborator

@bylaws bylaws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if ((GetCursorOffset() + BufferRange) > CurrentCodeBuffer->Size) {
will need to be updated

protects last page of codebuffer. This should cause a
SIGSEGV if we try to access it. Until now it was possible to go over
and access out of bounds.

In addition, there a couple of clang-tidy fixes which should be NFC.
@pmatos pmatos force-pushed the MProtectLastPage branch from 39e2a83 to 791502a Compare April 25, 2025 18:41
@pmatos
Copy link
Copy Markdown
Collaborator Author

pmatos commented Apr 25, 2025

if ((GetCursorOffset() + BufferRange) > CurrentCodeBuffer->Size) {

will need to be updated

Done.

@Sonicadvance1 Sonicadvance1 merged commit e1d032b into FEX-Emu:main Apr 27, 2025
12 checks passed
@pmatos pmatos deleted the MProtectLastPage branch April 28, 2025 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants