Skip to content

Commit e972ee9

Browse files
youknowonemiss-islington
authored andcommitted
pythongh-142282 Fix winreg.QueryValueEx() under race condition (pythonGH-142283)
(cherry picked from commit 3ec941b) Co-authored-by: Jeong, YunWon <[email protected]>
1 parent f200776 commit e972ee9

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

Lib/test/test_winreg.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import gc
55
import os, sys, errno
6+
import itertools
67
import threading
78
import unittest
89
from platform import machine, win32_edition
@@ -291,6 +292,37 @@ def run(self):
291292
DeleteKey(HKEY_CURRENT_USER, test_key_name+'\\changing_value')
292293
DeleteKey(HKEY_CURRENT_USER, test_key_name)
293294

295+
def test_queryvalueex_race_condition(self):
296+
# gh-142282: QueryValueEx could read garbage buffer under race
297+
# condition when another thread changes the value size
298+
done = False
299+
ready = threading.Event()
300+
values = [b'ham', b'spam']
301+
302+
class WriterThread(threading.Thread):
303+
def run(self):
304+
with CreateKey(HKEY_CURRENT_USER, test_key_name) as key:
305+
values_iter = itertools.cycle(values)
306+
while not done:
307+
val = next(values_iter)
308+
SetValueEx(key, 'test_value', 0, REG_BINARY, val)
309+
ready.set()
310+
311+
thread = WriterThread()
312+
thread.start()
313+
try:
314+
ready.wait()
315+
with CreateKey(HKEY_CURRENT_USER, test_key_name) as key:
316+
for _ in range(1000):
317+
result, typ = QueryValueEx(key, 'test_value')
318+
# The result must be one of the written values,
319+
# not garbage data from uninitialized buffer
320+
self.assertIn(result, values)
321+
finally:
322+
done = True
323+
thread.join()
324+
DeleteKey(HKEY_CURRENT_USER, test_key_name)
325+
294326
def test_long_key(self):
295327
# Issue2810, in 2.6 and 3.1 when the key name was exactly 256
296328
# characters, EnumKey raised "WindowsError: More data is
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix :func:`winreg.QueryValueEx` to not accidentally read garbage buffer under race condition.

PC/winreg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1681,7 +1681,7 @@ winreg_QueryValueEx_impl(PyObject *module, HKEY key, const wchar_t *name)
16811681
return PyErr_SetFromWindowsErrWithFunction(rc,
16821682
"RegQueryValueEx");
16831683
}
1684-
obData = Reg2Py(retBuf, bufSize, typ);
1684+
obData = Reg2Py(retBuf, retSize, typ);
16851685
PyMem_Free(retBuf);
16861686
if (obData == NULL)
16871687
return NULL;

0 commit comments

Comments
 (0)