summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>2025-02-24 00:09:14 (GMT)
committerGitHub <noreply@github.com>2025-02-24 00:09:14 (GMT)
commit071820113f11b8f6a21f98652d0840e10268114c (patch)
treeec6634d173dcbde19b74321423a858d3a85f3c19
parent72ea3c030a81262af64ebcae2e83ce2ff529bcef (diff)
downloadcpython-071820113f11b8f6a21f98652d0840e10268114c.zip
cpython-071820113f11b8f6a21f98652d0840e10268114c.tar.gz
cpython-071820113f11b8f6a21f98652d0840e10268114c.tar.bz2
gh-130151: Fix reference leaks in `_hashlib.hmac_{new,digest}` (GH-130152)
* fix leak in `_hashlib.hmac_new` * fix leak in `hmac_digest` * fix exception type in `_hashlib.HMAC.copy`
-rw-r--r--Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst2
-rw-r--r--Modules/_hashopenssl.c36
2 files changed, 20 insertions, 18 deletions
diff --git a/Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst b/Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst
new file mode 100644
index 0000000..4638f13
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst
@@ -0,0 +1,2 @@
+Fix reference leaks in :func:`!_hashlib.hmac_new` and
+:func:`!_hashlib.hmac_digest`. Patch by Bénédikt Tran.
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index d7586fe..7f70f31 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -1556,7 +1556,6 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
PyObject *digestmod)
/*[clinic end generated code: output=c20d9e4d9ed6d219 input=5f4071dcc7f34362]*/
{
- PyTypeObject *type = get_hashlib_state(module)->HMACtype;
PY_EVP_MD *digest;
HMAC_CTX *ctx = NULL;
HMACobject *self = NULL;
@@ -1569,8 +1568,8 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
}
if (digestmod == NULL) {
- PyErr_SetString(
- PyExc_TypeError, "Missing required parameter 'digestmod'.");
+ PyErr_SetString(PyExc_TypeError,
+ "Missing required parameter 'digestmod'.");
return NULL;
}
@@ -1581,40 +1580,37 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
ctx = HMAC_CTX_new();
if (ctx == NULL) {
- _setException(PyExc_ValueError, NULL);
+ PyErr_NoMemory();
goto error;
}
- r = HMAC_Init_ex(
- ctx,
- (const char*)key->buf,
- (int)key->len,
- digest,
- NULL /*impl*/);
+ r = HMAC_Init_ex(ctx, key->buf, (int)key->len, digest, NULL /* impl */);
PY_EVP_MD_free(digest);
if (r == 0) {
_setException(PyExc_ValueError, NULL);
goto error;
}
- self = (HMACobject *)PyObject_New(HMACobject, type);
+ _hashlibstate *state = get_hashlib_state(module);
+ self = PyObject_New(HMACobject, state->HMACtype);
if (self == NULL) {
goto error;
}
self->ctx = ctx;
+ ctx = NULL; // 'ctx' is now owned by 'self'
HASHLIB_INIT_MUTEX(self);
if ((msg_obj != NULL) && (msg_obj != Py_None)) {
- if (!_hmac_update(self, msg_obj))
+ if (!_hmac_update(self, msg_obj)) {
goto error;
+ }
}
-
- return (PyObject*)self;
+ return (PyObject *)self;
error:
if (ctx) HMAC_CTX_free(ctx);
- if (self) PyObject_Free(self);
+ Py_XDECREF(self);
return NULL;
}
@@ -1681,14 +1677,14 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
HMAC_CTX *ctx = HMAC_CTX_new();
if (ctx == NULL) {
- return _setException(PyExc_ValueError, NULL);
+ return PyErr_NoMemory();
}
if (!locked_HMAC_CTX_copy(ctx, self)) {
HMAC_CTX_free(ctx);
return _setException(PyExc_ValueError, NULL);
}
- retval = (HMACobject *)PyObject_New(HMACobject, Py_TYPE(self));
+ retval = PyObject_New(HMACobject, Py_TYPE(self));
if (retval == NULL) {
HMAC_CTX_free(ctx);
return NULL;
@@ -1703,7 +1699,10 @@ static void
_hmac_dealloc(HMACobject *self)
{
PyTypeObject *tp = Py_TYPE(self);
- HMAC_CTX_free(self->ctx);
+ if (self->ctx != NULL) {
+ HMAC_CTX_free(self->ctx);
+ self->ctx = NULL;
+ }
PyObject_Free(self);
Py_DECREF(tp);
}
@@ -1748,6 +1747,7 @@ _hmac_digest(HMACobject *self, unsigned char *buf, unsigned int len)
return 0;
}
if (!locked_HMAC_CTX_copy(temp_ctx, self)) {
+ HMAC_CTX_free(temp_ctx);
_setException(PyExc_ValueError, NULL);
return 0;
}