https://github.com/python/cpython/commit/3ec941b364778bce4fac6c6100730e120b426849
commit: 3ec941b364778bce4fac6c6100730e120b426849
branch: main
author: Jeong, YunWon <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-12-09T12:09:07Z
summary:

gh-142282 Fix winreg.QueryValueEx() under race condition (GH-142283)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-12-05-18-26-50.gh-issue-142282.g6RQUN.rst
M Lib/test/test_winreg.py
M PC/winreg.c

diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py
index 733d30b3922d35..fc0533c6e1531f 100644
--- a/Lib/test/test_winreg.py
+++ b/Lib/test/test_winreg.py
@@ -3,6 +3,7 @@
 
 import gc
 import os, sys, errno
+import itertools
 import threading
 import unittest
 from platform import machine, win32_edition
@@ -318,6 +319,37 @@ def run(self):
             DeleteKey(HKEY_CURRENT_USER, test_key_name+'\\changing_value')
             DeleteKey(HKEY_CURRENT_USER, test_key_name)
 
+    def test_queryvalueex_race_condition(self):
+        # gh-142282: QueryValueEx could read garbage buffer under race
+        # condition when another thread changes the value size
+        done = False
+        ready = threading.Event()
+        values = [b'ham', b'spam']
+
+        class WriterThread(threading.Thread):
+            def run(self):
+                with CreateKey(HKEY_CURRENT_USER, test_key_name) as key:
+                    values_iter = itertools.cycle(values)
+                    while not done:
+                        val = next(values_iter)
+                        SetValueEx(key, 'test_value', 0, REG_BINARY, val)
+                        ready.set()
+
+        thread = WriterThread()
+        thread.start()
+        try:
+            ready.wait()
+            with CreateKey(HKEY_CURRENT_USER, test_key_name) as key:
+                for _ in range(1000):
+                    result, typ = QueryValueEx(key, 'test_value')
+                    # The result must be one of the written values,
+                    # not garbage data from uninitialized buffer
+                    self.assertIn(result, values)
+        finally:
+            done = True
+            thread.join()
+            DeleteKey(HKEY_CURRENT_USER, test_key_name)
+
     def test_long_key(self):
         # Issue2810, in 2.6 and 3.1 when the key name was exactly 256
         # characters, EnumKey raised "WindowsError: More data is
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-05-18-26-50.gh-issue-142282.g6RQUN.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-05-18-26-50.gh-issue-142282.g6RQUN.rst
new file mode 100644
index 00000000000000..d038cd40f4f57a
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-05-18-26-50.gh-issue-142282.g6RQUN.rst
@@ -0,0 +1 @@
+Fix :func:`winreg.QueryValueEx` to not accidentally read garbage buffer under 
race condition.
diff --git a/PC/winreg.c b/PC/winreg.c
index c1be920fc1d92f..bcb02b12299055 100644
--- a/PC/winreg.c
+++ b/PC/winreg.c
@@ -1651,7 +1651,7 @@ winreg_QueryValueEx_impl(PyObject *module, HKEY key, 
const wchar_t *name)
         return PyErr_SetFromWindowsErrWithFunction(rc,
                                                    "RegQueryValueEx");
     }
-    obData = Reg2Py(retBuf, bufSize, typ);
+    obData = Reg2Py(retBuf, retSize, typ);
     PyMem_Free(retBuf);
     if (obData == NULL)
         return NULL;

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to