Skip to content

Cygwin: fork: hint at Mandatory ASLR when the forked child dies - #380

Open
alirobe wants to merge 1 commit into
msys2:msys2-3.6.10from
alirobe:fork-mandatory-aslr-hint
Open

alirobe wants to merge 1 commit into
msys2:msys2-3.6.10from
alirobe:fork-mandatory-aslr-hint

Conversation

@alirobe

@alirobe alirobe commented Oct 7, 2026 •

Copy link
Copy Markdown

Please consider #381 instead. It restores the --dynamicbase link flag so this failure no longer happens; this PR is only the fallback if #381 is declined.

Under Windows' Mandatory ASLR ("Force randomization for images"), every MSYS program fails to fork with only forked process ... died unexpectedly, ... exit code 0xC0000142. This adds one line to that error, printed once per process and only when GetProcessMitigationPolicy() reports forced relocation for the current executable:

dofork: fork() cannot work while Windows' Mandatory ASLR ("Force randomization for images") is enforced for C:\msys64\usr\bin\bash.exe; exempt it under Windows Security > Exploit protection > Program settings, or turn that setting off

Tested with the CI-built DLL on Windows 11: the line appears for an unexempted executable and not for an exempted one.

Addresses #327, git-for-windows/git#1412.

Assisted by Claude Fable 5.1; reviewed, tested and signed off by the author.

Since Cygwin 3.4.0 the Cygwin DLL is linked with --dynamicbase and the
runtime can "run with full ASLR enabled" (943433b, "Cygwin: Enable
dynamicbase on the Cygwin DLL by default"). MSYS2 reverts that linker
flag ("Revert 'Cygwin: Enable dynamicbase on the Cygwin DLL by
default'") because fork() started failing inside Docker containers,
see https://cygwin.com/pipermail/cygwin/2022-December/252711.html; that
failure was never diagnosed and the revert still stands.

As a consequence, msys-2.0.dll carries no dynamicbase flag, and when
"Force randomization for images (Mandatory ASLR)" is enabled in Windows
Security's Exploit protection, Windows relocates it in every process.
The forked child then runs the DLL at a different address than its
parent, which fork emulation cannot survive. All the user gets after
the retries are exhausted is

	dofork: child -1 - forked process 50032 died unexpectedly, retry 0,
	exit code 0xC0000142, errno 11

followed by the shell's "fork: retry: Resource temporarily unavailable".
Nothing in that output points at the cause, so users keep reporting it
as a bug in the runtime or in the programs built on it (e.g. msys2#327,
git-for-windows/git#1412), and the usual answer, to exempt the
executables from the setting or to turn it off, never reaches the
people who hit it in CI logs or behind a GUI.

Windows reports the effective policy of the current process via
GetProcessMitigationPolicy(); EnableForceRelocateImages is set exactly
when the system-wide setting is on and this executable has not been
exempted. When that is the case and fork() fails, print one extra line,
once per process, naming the cause, the affected executable, and where
the exemption is configured. Processes not subject to the setting see no
change.

This is deliberately not submitted to Cygwin: upstream supports
Mandatory ASLR, so the condition only exists in the MSYS2 build. The
real fix would be to drop the dynamicbase revert once the Docker
failure is understood; until then, this is the stopgap.

Addresses: msys2#327
Assisted-by: Claude Fable 5.1
Signed-off-by: Ali Robertson <[email protected]>
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.

1 participant