PowerShell: 7.3.0 x86 crashes on startup on Windows 11 22H2
Prerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest released version
- Search the existing issues.
- Refer to the FAQ.
- Refer to Differences between Windows PowerShell 5.1 and PowerShell.
Steps to reproduce
- Install PowerShell 7.3.0 x86 on a Windows x64 system.
- Start
pwsh.exe
.
No previous version of PowerShell 7 behaved in this way.
Expected behavior
PowerShell 7.3.0
PS C:\Users\Me>
Actual behavior
PowerShell 7.3.0
Fatal error. 0xC0000005
at System.Management.Automation.Security.SystemPolicy+WldpNativeMethods.WldpCanExecuteFile(System.Guid, WLDP_EXECUTION_EVALUATION_OPTIONS, IntPtr, System.String, WLDP_EXECUTION_POLICY ByRef)
at System.Management.Automation.Security.SystemPolicy.GetFilePolicyEnforcement(System.String, System.IO.FileStream)
at System.Management.Automation.ExternalScriptInfo.ReadScriptContents()
at System.Management.Automation.ExternalScriptInfo.get_ScriptBlock()
at Microsoft.PowerShell.Commands.ModuleCmdletBase.LoadModuleManifestData(System.Management.Automation.ExternalScriptInfo, System.String[], ManifestProcessingFlags, Boolean ByRef)
at Microsoft.PowerShell.Commands.ModuleCmdletBase.LoadModuleManifestData(System.Management.Automation.ExternalScriptInfo, ManifestProcessingFlags, System.Collections.Hashtable ByRef, System.Collections.Hashtable ByRef, Boolean ByRef)
at Microsoft.PowerShell.Commands.ModuleCmdletBase.LoadModule(System.Management.Automation.PSModuleInfo, System.String, System.String, System.String, System.Management.Automation.SessionState, System.Object, ImportModuleOptions ByRef, ManifestProcessingFlags, Boolean ByRef, Boolean ByRef)
at Microsoft.PowerShell.Commands.ModuleCmdletBase.LoadUsingExtensions(System.Management.Automation.PSModuleInfo, System.String, System.String, System.String, System.String, System.String, System.Management.Automation.SessionState, ImportModuleOptions, ManifestProcessingFlags, Boolean ByRef, Boolean ByRef)
at Microsoft.PowerShell.Commands.ModuleCmdletBase.LoadUsingModulePath(System.Management.Automation.PSModuleInfo, System.Collections.Generic.IEnumerable`1<System.String>, System.String, System.Management.Automation.SessionState, ImportModuleOptions, ManifestProcessingFlags, System.Management.Automation.PSModuleInfo ByRef)
at Microsoft.PowerShell.Commands.ImportModuleCommand.ImportModule_LocallyViaName(ImportModuleOptions, System.String)
at Microsoft.PowerShell.Commands.ImportModuleCommand.ImportModule_LocallyViaName_WithTelemetry(ImportModuleOptions, System.String)
at Microsoft.PowerShell.Commands.ImportModuleCommand.ProcessRecord()
at System.Management.Automation.Cmdlet.DoProcessRecord()
at System.Management.Automation.CommandProcessor.ProcessRecord()
at System.Management.Automation.CommandProcessorBase.DoExecute()
at System.Management.Automation.Internal.PipelineProcessor.Inject(System.Object, Boolean)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(System.Object)
at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper()
at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc()
at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProcImpersonate()
at System.Management.Automation.Runspaces.PipelineThread.WorkerProc()
at System.Threading.Thread+StartHelper.Callback(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.Thread.StartCallback()
Error details
No response
Environment data
Not available because PowerShell crashes on startup.
Visuals
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 20 (11 by maintainers)
Commits related to this issue
- Fix native access violation (#18545) The error occurs only when running x86 pwsh on x64 Windows 11 22H2, the first Windows version that has WldpCanExecuteFile(). — committed to chrullrich/PowerShell by tradlux-chul 2 years ago
- Fix native access violation (#18545) (#18547) The error occurs only when running x86 pwsh on x64 Windows 11 22H2, the first Windows version that has WldpCanExecuteFile(). Co-authored-by: Christia... — committed to PowerShell/PowerShell by chrullrich 2 years ago
- Fix native access violation (#18545) The error occurs only when running x86 pwsh on x64 Windows 11 22H2, the first Windows version that has WldpCanExecuteFile(). — committed to PowerShell/PowerShell by tradlux-chul 2 years ago
- Fix native access violation (#18545) (#18547) The error occurs only when running x86 pwsh on x64 Windows 11 22H2, the first Windows version that has WldpCanExecuteFile(). Co-authored-by: Christia... — committed to gregsdennis/PowerShell by chrullrich 2 years ago
Calling conventions.
Per
wldp.h
the first argument is aREFGUID
, also known as aGUID*
. The Windows x64 calling convention says that values larger than 64 bits (that is, larger than a register) are passed by address (i.e. as pointers). This means that in C# terms,Guid
andref Guid
look the same to the called native function (but I think in the non-ref
case the Guid is probably copied somewhere in case the native function changes it).The x86 calling conventions, in this case
__stdcall
, are more complicated. Here, structures (such as Guid) are passed on the stack, that is, the compiler copies the structure to the stack instead of just pushing a pointer to it. This also means that the function will mistake the last four bytes of the GUID as a pointer to one, dereference it, and … boom. I tried it from C, and this is exactly what happens.My fix tells .NET to pass the Guid as a pointer to a structure, and the fact that this changes the behavior at all is the best proof that it is correct: If it works when passing a pointer, then it must not have been passing one before, and that is definitely wrong because we know the function expects a
REFGUID
.Also note that a few lines down in the file, the declaration of
SHGetKnownFolderPath()
already uses the attribute, and that function’s first argument is aREFKNOWNFOLDERID
, another alternative spelling ofGUID*
.Now that I have convinced myself of that (and you, I hope), my next problem is how to create a PR for the fix if I cannot get
master
to build for testing.For illustration, this is a call to
WldpCanExecuteFile(REFGUID, int, int, int, int)
(the exact types don’t matter):This is
WldpCanExecuteFile(GUID, 0, 0, 0, 0)
:Sometimes I’m too impatient when writing bug reports.
Reproduction:
cd
to the directory just extracted.pwsh.exe
.The crash happens both with my regular cluttered PATH and with
PATH=C:\windows\system32;C:\windows
, and when starting it from another directory with an absolute path on the command line. It also happens with the MSI installed the same way you describe (same path, same no options), both from command prompt and start menu. Installing the MSI had no effect on the behavior of the copy I unzipped earlier. It also happens when run from an elevated “real” command prompt window.I noticed that the delay, both before the first line of output and between the last line of the stack trace and the return of the prompt, is much shorter with the MSI (<< 1 s start, 1.5 s finish) than with the Zip (~2.5 s start, ~6 s finish).
Hope that’s better 😃