Skip to content

Check for SIG_IGN and SIG_DFL before calling previous signal handler - #132900

Open
jtschuster wants to merge 1 commit into
dotnet:mainfrom
jtschuster:runtime-repro-mac-execve-issue
Open

Check for SIG_IGN and SIG_DFL before calling previous signal handler#132900
jtschuster wants to merge 1 commit into
dotnet:mainfrom
jtschuster:runtime-repro-mac-execve-issue

Conversation

@jtschuster

Copy link
Copy Markdown
Member

macOS doesn't clear sa_flags when calling execve. When dotnet is started from a process that sets a signal handler, the handler is cleared, but not the sa_flags. When the runtime gets a signal from an external source, it sees a stale SA_SIGINGO and tries to call the previous signal handler, but the pointer is set to SIG_IGN or SIG_DFL, which causes a crash. This change checks for those values before calling the previous signal handler. Also adds a regression test for the issue.

Fixes #132581

macOS doesn't clear sa_flags when calling execve. When dotnet is started from a
process that sets a signal handler, the handler is cleared, but not the
sa_flags. When the runtime gets a signal from an external source, it sees a
stale SA_SIGINGO and tries to call the previous signal handler, but the pointer
is set to SIG_IGN or SIG_DFL, which causes a crash. This change checks for those
values before calling the previous signal handler.
Add a regression test for the issue.
@jtschuster jtschuster added this to the 11.0.0 milestone Aug 28, 2026
@jtschuster jtschuster self-assigned this Aug 28, 2026
Copilot AI lite review requested due to automatic review settings August 28, 2026 18:00
@jtschuster jtschuster added the os-mac-os-x macOS aka OSX label Aug 28, 2026
@jtschuster
jtschuster requested review from agocke and janvorli August 28, 2026 18:01
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 4 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jtschuster
jtschuster requested a review from a team August 28, 2026 18:01
@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.

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.

Pull request overview

This PR hardens CoreCLR and NativeAOT activation-signal chaining by ensuring the runtime does not attempt to call a previous signal “handler” when the saved disposition is actually SIG_DFL or SIG_IGN, even if SA_SIGINFO is set (a state observed on macOS across execve). It also adds a macOS-only regression test that reproduces the inherited SA_SIGINFO + default/ignored disposition scenario and validates the runtime remains stable when an external SIGUSR1 arrives.

Changes:

  • CoreCLR: gate chaining to the saved activation signal disposition behind IsSigDfl/IsSigIgn checks before calling either sa_sigaction or sa_handler.
  • NativeAOT: apply the same SIG_DFL / SIG_IGN guard to activation handler chaining when SA_SIGINFO is set.
  • Tests: add a macOS-only regression test that installs an SA_SIGINFO handler, execvs into the .NET process, then triggers an external SIGUSR1 to exercise the chaining path.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/coreclr/pal/src/exception/signal.cpp Prevents calling the previous activation handler when it’s SIG_DFL/SIG_IGN, regardless of stale SA_SIGINFO.
src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp Mirrors the same SIG_DFL/SIG_IGN guard for NativeAOT’s activation handler chaining.
src/tests/Regressions/coreclr/GitHub_132581/test132581.csproj Adds a macOS-only, process-isolated regression test project with a native CMake dependency.
src/tests/Regressions/coreclr/GitHub_132581/test132581.cs Managed test that execvs after installing the signal handler and then triggers an external SIGUSR1.
src/tests/Regressions/coreclr/GitHub_132581/nativetest132581.cpp Native helper to install the SA_SIGINFO handler + execv, and to send SIGUSR1 from a forked child.
src/tests/Regressions/coreclr/GitHub_132581/CMakeLists.txt Builds/installs the native helper library on macOS only.

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Needed for CLRTestTargetUnsupported and CMakeProjectReference -->

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.

Suggested change
<!-- Needed for CLRTestTargetUnsupported and CMakeProjectReference -->
<!-- Installs a custom signal handler. -->

This test actually has a reason outside of infra limitations for why it is marked RPI. Let's put that here so later tooling doesn't try to force this in-proc with other tests.

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 find the regression tests by issue number a lot harder to understand if I need to go back to them. Thoughts on naming by the scenario - something like ActivationSignalChaining class and Exec_InheritedFlags method?

<!-- Needed for CLRTestTargetUnsupported and CMakeProjectReference -->
<RequiresProcessIsolation>true</RequiresProcessIsolation>
<CLRTestTargetUnsupported Condition="'$(TargetsOSX)' != 'true'">true</CLRTestTargetUnsupported>
<CLRTestPriority>1</CLRTestPriority>

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.

Since this is pri 1, do we want to kick of an explicit outerloop run (or whatever will run this in coreclr and native AOT)?

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

Labels

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

macOS: activation signal handler calls through a NULL pointer when SIGUSR1 is inherited with SA_SIGINFO + SIG_DFL

4 participants