Disable read-only GS cookie protection on Apple platforms (fixes coreclr_initialize under stock LLDB) - #132925
Open
steveisok wants to merge 1 commit into
Open
Disable read-only GS cookie protection on Apple platforms (fixes coreclr_initialize under stock LLDB)#132925steveisok wants to merge 1 commit into
steveisok wants to merge 1 commit into
Conversation
InitGSCookie() places s_gsCookie in Apple's __DATA_CONST,__const segment (via READONLY_ATTR/const) and then temporarily calls ClrVirtualProtect(PAGE_READWRITE) to initialize it. Apple marks the whole __DATA_CONST segment immutable at load, so that mprotect call fails with ERROR_INVALID_ACCESS, and coreclr_initialize returns HRESULT 0x8007000C. This is most visible when hosting CoreCLR inside Apple's stock LLDB with PAL_MachExceptionMode set to avoid Apple's guarded Mach exception ports. NativeAOT hit the same issue and fixed it in dotnet#99173 by disabling FEATURE_READONLY_GS_COOKIE on Apple (src/coreclr/nativeaot/Runtime). Mirror that fix for CoreCLR: keep s_gsCookie in ordinary writable data and skip the now-unnecessary protection transitions in InitGSCookie() on TARGET_APPLE, while keeping the existing read-only placement and randomized initialization on all other platforms. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @agocke |
Contributor
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
Review tier: Lite
Findings: 1
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
src/coreclr/vm/vars.hpp — The comment describing why const/volatile are used is now inaccurate on Apple builds: when… |
What changed in this PR
This PR adjusts CoreCLR’s GS cookie storage and initialization to avoid relying on temporarily changing page protections on Apple platforms, where that pattern can fail at runtime. It does so by disabling the “read-only GS cookie” protection on TARGET_APPLE while preserving the existing behavior on non-Apple platforms.
Changes:
- Introduces
FEATURE_READONLY_GS_COOKIE, defined for all targets exceptTARGET_APPLE. - Makes
s_gsCookieread-only (const+READONLY_ATTR) only when the feature is enabled; otherwise it is normal writable data. - Guards
InitGSCookie()’sClrVirtualProtectcalls so they only run when the feature is enabled.
| File | Description |
|---|---|
| src/coreclr/vm/vars.hpp | Adds FEATURE_READONLY_GS_COOKIE definition (disabled on Apple) and makes s_gsCookie declaration conditional on the feature. |
| src/coreclr/vm/vars.cpp | Makes the s_gsCookie definition conditional (const vs writable) to match the updated declaration. |
| src/coreclr/vm/ceemain.cpp | Guards the ClrVirtualProtect transitions around GS cookie initialization behind FEATURE_READONLY_GS_COOKIE. |
Comment on lines
603
to
606
| // const is so that it gets placed in the .text section (which is read-only) | ||
| // volatile is so that accesses to it do not get optimized away because of the const | ||
| // | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Fixes #99977
Hosting CoreCLR inside Apple's stock
/usr/bin/lldbon macOS arm64 fails:coreclr_initializereturns
HRESULT 0x8007000C.InitGSCookie()temporarily callsClrVirtualProtect(PAGE_READWRITE)on
s_gsCookie, which lives in Apple's__DATA_CONSTsegment (viaconst/READONLY_ATTR).Apple marks that segment immutable once a Mach exception port owns the process — which happens
when CoreCLR is hosted inside LLDB with
PAL_MachExceptionModeset to avoid Apple's guarded Machexception-port operations — so the underlying
mprotectcall fails.NativeAOT hit and fixed the identical problem in #99173 by disabling
FEATURE_READONLY_GS_COOKIEon Apple. This PR mirrors that fix for CoreCLR:
FEATURE_READONLY_GS_COOKIE, defined everywhere exceptTARGET_APPLE.vars.hpp/vars.cpp:s_gsCookiekeeps its read-onlyconst/READONLY_ATTRdeclarationwhen the macro is defined; otherwise it's plain writable data.
ceemain.cpp:InitGSCookie()skips bothClrVirtualProtectcalls when the macro isundefined. Cookie generation and the write itself are unchanged on every platform.
Non-Apple platforms are unaffected — the cookie remains read-only there. On Apple, this trades a
narrow defense-in-depth mitigation for a working LLDB hosting story, the same tradeoff NativeAOT
already ships for the identical failure mode.
Testing
./build.sh clr+libs+host -c Release— succeeded, 0 errors/0 warnings.dlopenslibcoreclr.dyliband calls
coreclr_initialize, run under Apple's stock LLDB withPAL_MachExceptionMode=7.Before:
0x8007000C. After:0x00000000(S_OK).dotnet/diagnostics's SOS test harness (stock LLDB +libsosplugin.dylib):ObjectInspectionTests.DumpObj_Mt_Class_Md_Chainpasses against thepatched runtime (
dumpheap,dumpobj,dumpmt,dumpclass,dumpmd), and fails with thesame
0x8007000Cagainst an unpatched one.Note
This description was drafted with the assistance of an AI coding agent (GitHub Copilot).