Windows version from `sys.getwindowsversion()` is wrong in binaries that do not declare Windows 10 support
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
Bug report
Bug description:
Repro:
- Install Python for Windows (ideally create a new installation, since you'll need to patch it).
- Using Resource Hacker, or any other PE resource editing tool, remove the
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>line from the PE manifest, or just delete the whole manifest from the binary. Write back the patched binary. This enables compatibility shims for Windows 8 in the Win32 API when running the binary. - Run
...\python.exe -c "import sys; print(sys.getwindowsversion())" - Observe that the returned version indicates Windows 8 (major=6, minor=3) instead of the actual OS version (major=10, minor=0 for both Windows 10 and 11).
The root cause is very similar to https://issues.chromium.org/issues/494938698, see the full description there.
To retrieve the Windows version, Python reads the file version from kernel32.dll, because GetVersionEx will report old values due to backwards compatibility. However, GetFileVersionInfoW, which is used in the sysmodule.c implementation of sys.getwindowsversion() also has an internal compatibility shim where if the calling binary does not declare support for Windows 10, it will shim the actual DLL versions with a fake Windows 8 version for system libraries, resulting in sys.getwindowsversion() reporting a wrong OS version.
This is not an issue for python.exe directly, because it has a proper PE manifest that declares Windows 10 support, but it is an issue for apps that embed CPython and do not have a PE manifest, or do not declare Windows 10 support.
Proposed fix
Replace the whole implementation with a call to RtlGetVersion from ntdll, which is now officially documented, returns the correct version without shims and there's a substantial list of prominent projects relying on it already.
CPython versions tested on:
3.15
Operating systems tested on:
Windows
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in Python/sysmodule.c at the sys.getwindowsversion() implementation and reproduce the reported result with a patched or manifest-free Windows binary. Read the documented RtlGetVersion entry point and compare its behavior with the current version lookup. Done means embedded binaries without Windows 10 support report the actual Windows version rather than the compatibility-shimmed value.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, python
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100