Fix memory corruption and support WinPE#841
Fix memory corruption and support WinPE#841eransha-salvador wants to merge 4 commits intoPowerShell:latestw_allfrom
Conversation
- Prefer VS 2017/2019/2022 over newer installs (e.g. VS 2026) when vswhere reports both, so a host with a newer VS installed alongside VS 2022 still builds with v143. Without this the downstream Select-String version checks miss and the VS 2015 fallback dereferences a null VS140COMNTOOLS. - Pin vcpkg's CMake with VCPKG_VISUAL_STUDIO_PATH and VCPKG_PLATFORM_TOOLSET=v143 so it uses the same toolset as the .vcxproj files, avoiding MSB8040 (Spectre-libs missing for v145) when vcpkg would otherwise pick up a newer VS. - Fall back to the repo root for OpenSSH-build.ps1 -destination when \$env:WORKSPACE is unset. CI still has its WORKSPACE value, and no longer invokes this script directly anyway. - Document Windows build prerequisites in README.txt: VS 2022 Desktop C++ workload, v143 Spectre-mitigated libs, Git, the one-time vcpkg bootstrap/integrate step, and the need to run from an elevated PowerShell.
|
@eransha-salvador please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
|
If it's only a transitive reference, does removing the dependency on the DLL from sshd-auth, instead of delay loading, work? |
|
@tgauth it won't work.
|
The .vcxproj files pin PlatformToolset v143, which ships with VS 2022. VS 2017 (v141) and VS 2019 (v142) would need v143 build tools sideloaded to build this, which is a non-default setup — so they shouldn't be treated as equals to VS 2022 in the preference order.
2887388 to
f98e834
Compare
The debug3 on LoadUserProfileW failure had format "%s %S %d" (three specifiers) but only two arguments. %S consumed GetLastError()'s DWORD as a wide-string pointer and wcsnlen dereferenced it, crashing sshd-session post-auth. Only visible where LoadUserProfileW actually fails (e.g. WinPE, which has no user-profile service), so regular Windows was unaffected.
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.
f98e834 to
a650ee0
Compare
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Summary
load_user_profile(%s %S %dwith two args) that corrupts memory and crashes sshd-session post-auth whenLoadUserProfileWfails.user32.dllin sshd-auth so it survives restricted window stations (e.g. WinPE) whereuser32'sDllMainfails withSTATUS_DLL_INIT_FAILED. The only transitive user32 references (ShowWindow / GetWindowPlacement via ConRestoreViewRect_NoPtyHack) are unreachable in sshd-auth, so the DLL is never loaded in practice.Stacked on #840 — please merge that first. Until #840 lands, this PR's diff view also shows its commit; after #840 merges, this PR will rebase down to just the two commits above.
Fixes PowerShell/Win32-OpenSSH#2435
Test plan