Skip to content

Commit 2887388

Browse files
Delay-load user32 in sshd-auth to survive restricted window stations
sshd-auth runs as a privsep helper under a different user with no desktop/window-station access. user32's DllMain binds to the process window station and fails with STATUS_DLL_INIT_FAILED in restricted environments like WinPE, crashing the helper before auth can run. Add delayimp.lib and /DELAYLOAD:user32.dll so user32 is only loaded when one of its APIs is actually called. sshd-auth's only transitive user32 references come from console.c's ConRestoreViewRect_NoPtyHack (ShowWindow / GetWindowPlacement), which sshd-auth never executes, so in practice user32 is never loaded at all. The ItemDefinitionGroup carrying /DELAYLOAD is placed after Microsoft.Cpp.props, where the Link item type becomes defined. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4a2ccb8 commit 2887388

1 file changed

Lines changed: 19 additions & 0 deletions

File tree

contrib/win32/openssh/sshd-auth.vcxproj

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="paths.targets" />
4+
<!-- sshd-auth is a privsep helper spawned by sshd as a different user and has
5+
no desktop/window-station access. user32's DllMain binds to the process
6+
window station and fails with STATUS_DLL_INIT_FAILED in restricted
7+
environments (e.g. WinPE). Two mitigations: (1) add delayimp.lib and
8+
delay-load user32 so its DLL is only loaded when a user32 API is
9+
actually called, and (2) keep user32.lib (needed for the delay-load
10+
thunks). sshd-auth only transitively references ShowWindow /
11+
GetWindowPlacement from console.c's ConRestoreViewRect_NoPtyHack
12+
helper, which sshd-auth does not execute, so in practice user32 is
13+
never loaded. The ItemDefinitionGroup with /DELAYLOAD is placed after
14+
Microsoft.Cpp.props (where the Link item type becomes defined). -->
15+
<PropertyGroup>
16+
<AdditionalDependentLibs>bcrypt.lib;Userenv.lib;Crypt32.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;kernel32.lib;user32.lib;delayimp.lib;advapi32.lib;Netapi32.lib;Rpcrt4.lib;ntdll.lib</AdditionalDependentLibs>
17+
</PropertyGroup>
418
<ItemGroup Label="ProjectConfigurations">
519
<ProjectConfiguration Include="Debug|ARM">
620
<Configuration>Debug</Configuration>
@@ -112,6 +126,11 @@
112126
<VcpkgEnableManifest>true</VcpkgEnableManifest>
113127
</PropertyGroup>
114128
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
129+
<ItemDefinitionGroup>
130+
<Link>
131+
<AdditionalOptions>/DELAYLOAD:user32.dll %(AdditionalOptions)</AdditionalOptions>
132+
</Link>
133+
</ItemDefinitionGroup>
115134
<ImportGroup Label="ExtensionSettings">
116135
</ImportGroup>
117136
<ImportGroup Label="Shared">

0 commit comments

Comments
 (0)