]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-130151: Fix reference leaks in `_hashlib.hmac_{new,digest}` (GH-130152...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 24 Feb 2025 08:19:49 +0000 (09:19 +0100)
committerGitHub <noreply@github.com>
Mon, 24 Feb 2025 08:19:49 +0000 (00:19 -0800)
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`
(cherry picked from commit 071820113f11b8f6a21f98652d0840e10268114c)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst [new file with mode: 0644]
Modules/_hashopenssl.c

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 (file)
index 0000000..4638f13
--- /dev/null
@@ -0,0 +1,2 @@
+Fix reference leaks in :func:`!_hashlib.hmac_new` and
+:func:`!_hashlib.hmac_digest`. Patch by Bénédikt Tran.
index a04dc26587ad998f514d2ad0fd085106a76f6d69..2f7d277e07bac0e53bfbfff47760bb567fbde87e 100644 (file)
@@ -1557,7 +1557,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;
@@ -1570,8 +1569,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;
     }
 
@@ -1582,40 +1581,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;
 }
 
@@ -1682,14 +1678,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;
@@ -1704,7 +1700,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);
 }
@@ -1749,6 +1748,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;
     }