diff options
author | Bénédikt Tran <10796600+picnixz@users.noreply.github.com> | 2025-02-24 00:09:14 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-24 00:09:14 (GMT) |
commit | 071820113f11b8f6a21f98652d0840e10268114c (patch) | |
tree | ec6634d173dcbde19b74321423a858d3a85f3c19 | |
parent | 72ea3c030a81262af64ebcae2e83ce2ff529bcef (diff) | |
download | cpython-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.rst | 2 | ||||
-rw-r--r-- | Modules/_hashopenssl.c | 36 |
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; } |