diff --git a/Misc/NEWS.d/next/Library/2025-06-16-15-03-03.gh-issue-135561.mJCN8D.rst b/Misc/NEWS.d/next/Library/2025-06-16-15-03-03.gh-issue-135561.mJCN8D.rst new file mode 100644 index 00000000000000..ee743f161138e6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-16-15-03-03.gh-issue-135561.mJCN8D.rst @@ -0,0 +1,2 @@ +Fix a crash on DEBUG builds when an HACL* HMAC routine fails. Patch by +Bénédikt Tran. diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c index b404d5732ec857..9c92d9d145f5a3 100644 --- a/Modules/hmacmodule.c +++ b/Modules/hmacmodule.c @@ -493,36 +493,41 @@ narrow_hmac_hash_kind(hmacmodule_state *state, HMAC_Hash_Kind kind) static int _hacl_convert_errno(hacl_errno_t code, PyObject *algorithm) { + assert(PyGILState_GetThisThreadState() != NULL); + if (code == Hacl_Streaming_Types_Success) { + return 0; + } + + PyGILState_STATE gstate = PyGILState_Ensure(); switch (code) { - case Hacl_Streaming_Types_Success: { - return 0; - } case Hacl_Streaming_Types_InvalidAlgorithm: { // only makes sense if an algorithm is known at call time assert(algorithm != NULL); assert(PyUnicode_CheckExact(algorithm)); PyErr_Format(PyExc_ValueError, "invalid algorithm: %U", algorithm); - return -1; + break; } case Hacl_Streaming_Types_InvalidLength: { PyErr_SetString(PyExc_ValueError, "invalid length"); - return -1; + break; } case Hacl_Streaming_Types_MaximumLengthExceeded: { PyErr_SetString(PyExc_OverflowError, "maximum length exceeded"); - return -1; + break; } case Hacl_Streaming_Types_OutOfMemory: { PyErr_NoMemory(); - return -1; + break; } default: { PyErr_Format(PyExc_RuntimeError, "HACL* internal routine failed with error code: %d", code); - return -1; + break; } } + PyGILState_Release(gstate); + return -1; } /*