Skip to content

Commit dc3e19c

Browse files
committed
gh-145301: Fix double-free in hmac module initialization
1 parent 6b2f0d3 commit dc3e19c

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

Lib/test/test_hashlib.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import tempfile
1919
import threading
2020
import unittest
21+
import subprocess
22+
import textwrap
2123
from test import support
2224
from test.support import _4G, bigmemtest
2325
from test.support import hashlib_helper
@@ -1201,6 +1203,43 @@ def test_readonly_types(self):
12011203
with self.assertRaisesRegex(TypeError, "immutable type"):
12021204
hash_type.value = False
12031205

1206+
@unittest.skipUnless(HASH is not None, 'need _hashlib')
1207+
def test_hashlib_init_memory_error_no_df(self):
1208+
"""gh-145301 regression test."""
1209+
1210+
try:
1211+
import _testcapi
1212+
if not hasattr(_testcapi, 'set_nomemory'):
1213+
self.skipTest('requires _testcapi.set_nomemory')
1214+
except ImportError:
1215+
self.skipTest('requires _testcapi')
1216+
1217+
code = textwrap.dedent("""
1218+
import sys
1219+
import _testcapi
1220+
1221+
if '_hashlib' in sys.modules:
1222+
del sys.modules['_hashlib']
1223+
1224+
_testcapi.set_nomemory(40, 41)
1225+
try:
1226+
import _hashlib
1227+
except (MemoryError, ImportError):
1228+
pass
1229+
finally:
1230+
_testcapi.remove_mem_hooks()
1231+
""")
1232+
1233+
rc = subprocess.call(
1234+
[sys.executable, '-c', code],
1235+
stdout=subprocess.DEVNULL,
1236+
stderr=subprocess.DEVNULL,
1237+
)
1238+
# rc < 0 means crash (signal on Unix), which indicates double-free
1239+
# rc >= 0 means normal exit (even with MemoryError), which is expected
1240+
self.assertGreaterEqual(rc, 0,
1241+
"Process crashed - Loss double-free in _hashlib")
1242+
12041243

12051244
class KDFTests(unittest.TestCase):
12061245

Modules/hmacmodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,8 @@ py_hmac_hinfo_ht_new(void)
14571457
do { \
14581458
int rc = py_hmac_hinfo_ht_add(table, KEY, value); \
14591459
if (rc < 0) { \
1460-
/* entry may already be in ht, will be freed by _Py_hashtable_destroy() */ \
1460+
/* entry may already be in ht, will be freed by \
1461+
_Py_hashtable_destroy() */ \
14611462
if (value->refcnt == 0) { \
14621463
PyMem_Free(value); \
14631464
} \

0 commit comments

Comments
 (0)