Skip to content

Commit 3421009

Browse files
[3.15] gh-159811: Raise OpenSSL errors in _hashlib.HMAC after re-attaching the thread state (GH-159818) (#159926)
gh-159811: Raise OpenSSL errors in `_hashlib.HMAC` after re-attaching the thread state (GH-159818) `hashlib_openssl_HMAC_update_once()` set an exception when the OpenSSL HMAC update function failed, but it was called inside a GIL-released region and the object's mutex held by `_hashlib.HMAC.update()` and `_hashlib.hmac_new()` when the data exceeds `HASHLIB_GIL_MINSIZE` bytes. Instead, the HMAC update function is called directly in `_hmac_update()`, and the exception is set once the thread state is re-attached and the mutex is released (restores the behavior prior to gh-134531). Since the OpenSSL error queue is per thread, the exception type and message are unaffected. (cherry picked from commit b4b81e1) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent d89f40b commit 3421009

2 files changed

Lines changed: 10 additions & 12 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:`hmac` when the OpenSSL routine used by
2+
:meth:`hmac.HMAC.update` or by :func:`hmac.new` fails on data larger
3+
than 2048 bytes. Patch by Bénédikt Tran.

‎Modules/_hashopenssl.c‎

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,16 +1975,6 @@ hashlib_HMAC_get_hashlib_digest_name(HMACobject *self)
19751975
#endif
19761976
}
19771977

1978-
static int
1979-
hashlib_openssl_HMAC_update_once(PY_HMAC_CTX_TYPE *ctx, const Py_buffer *v)
1980-
{
1981-
if (!PY_HMAC_update(ctx, (const unsigned char *)v->buf, (size_t)v->len)) {
1982-
notify_smart_ssl_error_occurred_in(Py_STRINGIFY(PY_HMAC_update));
1983-
return -1;
1984-
}
1985-
return 0;
1986-
}
1987-
19881978
/* Thin wrapper around PY_HMAC_CTX_free that allows to pass a NULL 'ctx'. */
19891979
static inline void
19901980
hashlib_openssl_HMAC_CTX_free(PY_HMAC_CTX_TYPE *ctx)
@@ -2239,10 +2229,15 @@ _hmac_update(HMACobject *self, PyObject *obj)
22392229
GET_BUFFER_VIEW_OR_ERROR(obj, &view, return -1);
22402230
HASHLIB_EXTERNAL_INSTRUCTIONS_LOCKED(
22412231
self, view.len,
2242-
r = hashlib_openssl_HMAC_update_once(self->ctx, &view)
2232+
r = PY_HMAC_update(self->ctx, (const unsigned char *)view.buf,
2233+
(size_t)view.len)
22432234
);
22442235
PyBuffer_Release(&view);
2245-
return r;
2236+
if (r == 0) {
2237+
notify_smart_ssl_error_occurred_in(Py_STRINGIFY(PY_HMAC_update));
2238+
return -1;
2239+
}
2240+
return 0;
22462241
}
22472242

22482243
/*[clinic input]

0 commit comments

Comments
 (0)