X509_PUBKEY_set(): Fix memory leak
authorRichard Levitte <levitte@openssl.org>
Fri, 7 Feb 2020 08:13:21 +0000 (09:13 +0100)
committerRichard Levitte <levitte@openssl.org>
Tue, 11 Feb 2020 12:10:24 +0000 (13:10 +0100)
With the provided method of creating the new X509_PUBKEY, an extra
EVP_PKEY is created and needs to be properly cleaned away.

(note: we could choose to keep it just as well, but there are
consequences, explained in a comment in the code)

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/11038)

crypto/x509/x_pubkey.c

index 42b94d9198275cca7b3c73763a1905ab1ec56a56..a583813b5869fdb39987c901003d760a2e82ef59 100644 (file)
@@ -111,6 +111,22 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
         goto error;
     }
     *x = pk;
+
+    /*
+     * pk->pkey is NULL when using the legacy routine, but is non-NULL when
+     * going through the serializer, and for all intents and purposes, it's
+     * a perfect copy of |pkey|, just not the same instance.  In that case,
+     * we could simply return early, right here.
+     * However, in the interest of being cautious leaning on paranoia, some
+     * application might very well depend on the passed |pkey| being used
+     * and none other, so we spend a few more cycles throwing away the newly
+     * created |pk->pkey| and replace it with |pkey|.
+     * TODO(3.0) Investigate if it's safe to change to simply return here
+     * if |pk->pkey != NULL|.
+     */
+    if (pk->pkey != NULL)
+        EVP_PKEY_free(pk->pkey);
+
     pk->pkey = pkey;
     return 1;