python / python/cpython

Windows version from `sys.getwindowsversion()` is wrong in binaries that do not declare Windows 10 support

Ouverte
#146,299 7 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

interpreter-core OS-windows type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

Bug report

Bug description:

Repro:

  1. Install Python for Windows (ideally create a new installation, since you'll need to patch it).
  2. 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.
  3. Run ...\python.exe -c "import sys; print(sys.getwindowsversion())"
  4. 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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez dans Python/sysmodule.c, au niveau de l’implémentation de sys.getwindowsversion(), et reproduisez le résultat signalé avec un binaire Windows patché ou dépourvu de manifeste. Consultez le point d’entrée documenté RtlGetVersion et comparez son comportement avec la recherche de version actuelle. Le travail est terminé lorsque les binaires intégrés sans prise en charge de Windows 10 signalent la version réelle de Windows plutôt que la valeur modifiée par le shim de compatibilité.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
c, python
Domaine
operating-systems
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Calme
Clarté
Plutôt claire
Accessibilité débutants
55/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.