diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index f0e2d527af2615..b4861366b11162 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -16,14 +16,16 @@ import sys import sysconfig import tempfile +import textwrap import threading import unittest from test import support from test.support import _4G, bigmemtest from test.support import hashlib_helper -from test.support.import_helper import import_fresh_module +from test.support import import_helper from test.support import requires_resource from test.support import threading_helper +from test.support.script_helper import assert_python_ok from http.client import HTTPException @@ -37,7 +39,7 @@ builtin_hashes = set(map(str.strip, builtin_hash_names)) # Public 'hashlib' module with OpenSSL backend for PBKDF2. -openssl_hashlib = import_fresh_module('hashlib', fresh=['_hashlib']) +openssl_hashlib = import_helper.import_fresh_module('hashlib', fresh=['_hashlib']) try: import _hashlib @@ -1201,6 +1203,22 @@ def test_readonly_types(self): with self.assertRaisesRegex(TypeError, "immutable type"): hash_type.value = False + @unittest.skipUnless(HASH is not None, 'need _hashlib') + def test_hashlib_init_memory_error_no_df(self): + """gh-145301 regression test.""" + import_helper.import_module('_testcapi') + code = textwrap.dedent(""" + import _testcapi + _testcapi.set_nomemory(40, 41) + try: + import _hashlib + except (MemoryError, ImportError): + pass + finally: + _testcapi.remove_mem_hooks() + """) + assert_python_ok('-c', code) + class KDFTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst b/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst new file mode 100644 index 00000000000000..7aeb6a1145ab4c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst @@ -0,0 +1,2 @@ +:mod:`hashlib`: fix a crash when the initialization of the underlying C +extension module fails. diff --git a/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst b/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst new file mode 100644 index 00000000000000..436ff316b2c327 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst @@ -0,0 +1,2 @@ +:mod:`hmac`: fix a crash when the initialization of the underlying C +extension module fails. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 77832a768e0cbc..e19eb1abcf2c4d 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -268,7 +268,7 @@ py_hashentry_table_new(void) { if (h->py_alias != NULL) { if (_Py_hashtable_set(ht, (const void*)entry->py_alias, (void*)entry) < 0) { - PyMem_Free(entry); + /* entry is already in ht, will be freed by _Py_hashtable_destroy() */ goto error; } entry->refcnt++; diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c index f074f24807703c..a61b03c533ba3b 100644 --- a/Modules/hmacmodule.c +++ b/Modules/hmacmodule.c @@ -1453,16 +1453,19 @@ py_hmac_hinfo_ht_new(void) assert(value->display_name == NULL); value->refcnt = 0; -#define Py_HMAC_HINFO_LINK(KEY) \ - do { \ - int rc = py_hmac_hinfo_ht_add(table, KEY, value); \ - if (rc < 0) { \ - PyMem_Free(value); \ - goto error; \ - } \ - else if (rc == 1) { \ - value->refcnt++; \ - } \ +#define Py_HMAC_HINFO_LINK(KEY) \ + do { \ + int rc = py_hmac_hinfo_ht_add(table, KEY, value); \ + if (rc < 0) { \ + /* entry may already be in ht, freed upon exit */ \ + if (value->refcnt == 0) { \ + PyMem_Free(value); \ + } \ + goto error; \ + } \ + else if (rc == 1) { \ + value->refcnt++; \ + } \ } while (0) Py_HMAC_HINFO_LINK(e->name); Py_HMAC_HINFO_LINK(e->hashlib_name);