Skip to content

Commit 0405f10

Browse files
[3.15] gh-159811: Raise OpenSSL errors in _hashlib.HASH after re-attaching the thread state (GH-159817) (#159927)
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 6db7cb9 commit 0405f10

2 files changed

Lines changed: 15 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: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,12 @@ new_hash_object(PyTypeObject *type)
846846
return retval;
847847
}
848848

849+
/*
850+
* Update the digest context of 'self' with 'len' bytes from 'vp'.
851+
*
852+
* Return 0 on success and -1 if EVP_DigestUpdate() failed. No exception
853+
* is set, so that this can be called without an attached thread state.
854+
*/
849855
static int
850856
_hashlib_HASH_hash(HASHobject *self, const void *vp, Py_ssize_t len)
851857
{
@@ -857,7 +863,6 @@ _hashlib_HASH_hash(HASHobject *self, const void *vp, Py_ssize_t len)
857863
else
858864
process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
859865
if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) {
860-
notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_DigestUpdate));
861866
return -1;
862867
}
863868
len -= process;
@@ -990,7 +995,11 @@ _hashlib_HASH_update_impl(HASHobject *self, PyObject *obj)
990995
result = _hashlib_HASH_hash(self, view.buf, view.len)
991996
);
992997
PyBuffer_Release(&view);
993-
return result < 0 ? NULL : Py_None;
998+
if (result < 0) {
999+
notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_DigestUpdate));
1000+
return NULL;
1001+
}
1002+
Py_RETURN_NONE;
9941003
}
9951004

9961005
static PyMethodDef HASH_methods[] = {
@@ -1304,7 +1313,7 @@ _hashlib_HASH(_hashlibstate *state, const char *digestname, PyObject *data_obj,
13041313
result = _hashlib_HASH_hash(self, view.buf, view.len)
13051314
);
13061315
if (result == -1) {
1307-
assert(PyErr_Occurred());
1316+
notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_DigestUpdate));
13081317
Py_CLEAR(self);
13091318
goto exit;
13101319
}

0 commit comments

Comments
 (0)