Repository navigation
fix: turn off the .NET startup hooks an environment variable can name - #3228
Merged
Merged
Conversation
The .NET runtime loads every assembly a DOTNET_STARTUP_HOOKS variable names and runs it before Main, and any program running as the user can set that variable for the programs the user starts later, also one started as administrator. A single-file exe published the way the release is ran such a hook, and with StartupHookSupport off it ignored the variable. SysManager uses no startup hook, so they are off now. SECURITY.md lists running a startup hook among the things the app never does, and says what the runtime still reads from the environment: a profiler named in CORECLR_ or DOTNET_ variables, which nothing inside an app can turn off, since the runtime loads it before the app's code runs. SecurityPromiseTests.TheRuntime_RunsNoStartupHook reads the runtime configuration the build wrote, which the single-file bundle carries, and fails when it leaves startup hooks on. The release's smoke check starts the published exe with a hook named that does not exist, which an exe with hooks on refuses to start past.
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.
The .NET runtime loads every assembly a
DOTNET_STARTUP_HOOKSvariable names and runs itsStartupHook.InitializebeforeMain. Any program running as you can set that variable for the programs you start later, also one you start as administrator, so an elevated SysManager would run code another program chose. SysManager uses no startup hook, soStartupHookSupportis now off and the runtime ignores the variable.What changes
SysManager.csprojsetsStartupHookSupportto false, in every configuration, so a test run in Debug reads the same runtime configuration the release ships. The SDK writes it asSystem.StartupHookProvider.IsSupported: false, and the runtime stops before it looks at the hooks the variable names.SECURITY.mdlists running a startup hook under "By design — forbidden", and a new "Things to be aware of" entry says what the runtime still reads from the environment: a profiler named inCORECLR_orDOTNET_variables, which nothing inside an app can turn off, since the runtime loads it before the app's code runs. The runtime reads those settings only from the environment, not from the runtime configuration.DOTNET_STARTUP_HOOKSnaming a hook that does not exist, set for that launch only, since pwsh is a .NET program too. An exe with hooks on refuses to start past a hook it cannot load, so a build that turned them back on fails the gate before anything is published.How it was checked
StartupHookSupportoff ignored both and started normally. The smoke check's lines, run throughStart-Processagainst both, gave the same two outcomes, and left the variable unset afterwards."System.StartupHookProvider.IsSupported": falsein the runtime configuration inside the exe.SecurityPromiseTests.TheRuntime_RunsNoStartupHookfailed onmain's project, which sets nothing, and with the property set to true, and passes with it false.