Skip to content

Disable read-only GS cookie protection on Apple platforms (fixes coreclr_initialize under stock LLDB) - #132925

Open
steveisok wants to merge 1 commit into
dotnet:mainfrom
steveisok:steveisok-fix-macos-gs-cookie-e28
Open

Disable read-only GS cookie protection on Apple platforms (fixes coreclr_initialize under stock LLDB)#132925
steveisok wants to merge 1 commit into
dotnet:mainfrom
steveisok:steveisok-fix-macos-gs-cookie-e28

Conversation

@steveisok

@steveisok steveisok commented Aug 29, 2026

Copy link
Copy Markdown
Member

Fixes #99977

Hosting CoreCLR inside Apple's stock /usr/bin/lldb on macOS arm64 fails: coreclr_initialize
returns HRESULT 0x8007000C. InitGSCookie() temporarily calls ClrVirtualProtect(PAGE_READWRITE)
on s_gsCookie, which lives in Apple's __DATA_CONST segment (via const/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_MachExceptionMode set to avoid Apple's guarded Mach
exception-port operations — so the underlying mprotect call fails.

NativeAOT hit and fixed the identical problem in #99173 by disabling FEATURE_READONLY_GS_COOKIE
on Apple. This PR mirrors that fix for CoreCLR:

  • Add FEATURE_READONLY_GS_COOKIE, defined everywhere except TARGET_APPLE.
  • vars.hpp/vars.cpp: s_gsCookie keeps its read-only const/READONLY_ATTR declaration
    when the macro is defined; otherwise it's plain writable data.
  • ceemain.cpp: InitGSCookie() skips both ClrVirtualProtect calls when the macro is
    undefined. 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.
  • Repro'd the failure and the fix directly: a minimal harness that dlopens libcoreclr.dylib
    and calls coreclr_initialize, run under Apple's stock LLDB with PAL_MachExceptionMode=7.
    Before: 0x8007000C. After: 0x00000000 (S_OK).
  • Validated end-to-end through dotnet/diagnostics's SOS test harness (stock LLDB +
    libsosplugin.dylib): ObjectInspectionTests.DumpObj_Mt_Class_Md_Chain passes against the
    patched runtime (dumpheap, dumpobj, dumpmt, dumpclass, dumpmd), and fails with the
    same 0x8007000C against an unpatched one.

Note

This description was drafted with the assistance of an AI coding agent (GitHub Copilot).

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>
Copilot AI lite review requested due to automatic review settings August 29, 2026 18:33
@azure-pipelines

Copy link
Copy Markdown
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.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

@steveisok
steveisok requested review from a team and jkotas August 29, 2026 18:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

Review tier: Lite
Findings: 1 Low severity

New issues introduced by this change (1)
Severity Finding
Low severity 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 except TARGET_APPLE.
  • Makes s_gsCookie read-only (const + READONLY_ATTR) only when the feature is enabled; otherwise it is normal writable data.
  • Guards InitGSCookie()’s ClrVirtualProtect calls 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 thread src/coreclr/vm/vars.hpp
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
//

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[macOS] Hosting CoreCLR inside an LLDB plugin fails to initialize the runtime

2 participants