Skip to content

Commit 622a80e

Browse files
committed
[3.14] gh-159811: Raise OpenSSL errors in _hashlib.HASH after re-attaching the thread state (GH-159817)
When `EVP_DigestUpdate()` failed, `_hashlib_HASH_hash()` raised a Python exception, however, `_hashlib.HASH.update()` and the `_hashlib.HASH` constructor release the GIL before calling it when the data is larger than `HASHLIB_GIL_MINSIZE` bytes. `_hashlib_HASH_hash()` now only returns an error status and its callers raise the exception once they have re-attached the thread state. (cherry picked from commit 6fa2d64) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent cb6a4bb commit 622a80e

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a crash in :mod:`hashlib` when the OpenSSL routine used by
2+
:meth:`hash.update() <hashlib.hash.update>` or by hash object constructors
3+
fails on data larger than 2048 bytes. Patch by Bénédikt Tran.

‎Modules/_hashopenssl.c‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,12 @@ newEVPobject(PyTypeObject *type)
516516
return retval;
517517
}
518518

519+
/*
520+
* Update the digest context of 'self' with 'len' bytes from 'vp'.
521+
*
522+
* Return 0 on success and -1 if EVP_DigestUpdate() failed. No exception
523+
* is set, so that this can be called without an attached thread state.
524+
*/
519525
static int
520526
EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
521527
{
@@ -527,7 +533,6 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
527533
else
528534
process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
529535
if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) {
530-
notify_ssl_error_occurred();
531536
return -1;
532537
}
533538
len -= process;
@@ -694,8 +699,10 @@ EVP_update_impl(EVPobject *self, PyObject *obj)
694699

695700
PyBuffer_Release(&view);
696701

697-
if (result == -1)
702+
if (result == -1) {
703+
notify_ssl_error_occurred();
698704
return NULL;
705+
}
699706
Py_RETURN_NONE;
700707
}
701708

@@ -1000,7 +1007,7 @@ _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj,
10001007
result = EVP_hash(self, view.buf, view.len);
10011008
}
10021009
if (result == -1) {
1003-
assert(PyErr_Occurred());
1010+
notify_ssl_error_occurred();
10041011
Py_CLEAR(self);
10051012
goto exit;
10061013
}

0 commit comments

Comments
 (0)