Fix segfault in RSA_free() (and DSA/DH/EC_KEY)
authorNicola Tuveri <nic.tuv@gmail.com>
Wed, 5 Sep 2018 08:58:55 +0000 (11:58 +0300)
committerNicola Tuveri <nic.tuv@gmail.com>
Wed, 5 Sep 2018 12:26:40 +0000 (15:26 +0300)
`RSA_free()` and friends are called in case of error from
`RSA_new_method(ENGINE *e)` (or the respective equivalent functions).

For the rest of the description I'll talk about `RSA_*`, but the same
applies for the equivalent `DSA_free()`, `DH_free()`, `EC_KEY_free()`.

If `RSA_new_method()` fails because the engine does not implement the
required method, when `RSA_free(RSA *r)` is called,
`r->meth == NULL` and a segfault happens while checking if
`r->meth->finish` is defined.

This commit fixes this issue by ensuring that `r->meth` is not NULL
before dereferencing it to check for `r->meth->finish`.

Fixes #7102 .

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7121)

crypto/dh/dh_lib.c
crypto/dsa/dsa_lib.c
crypto/ec/ec_key.c
crypto/rsa/rsa_lib.c

index 716f4a4b0a571b85ba974f2850732f0cfc64d3c1..d277faa398f0e5e03e7fe0c6ac62313db0003d3c 100644 (file)
@@ -103,7 +103,7 @@ void DH_free(DH *r)
         return;
     REF_ASSERT_ISNT(i < 0);
 
-    if (r->meth->finish)
+    if (r->meth != NULL && r->meth->finish != NULL)
         r->meth->finish(r);
 #ifndef OPENSSL_NO_ENGINE
     ENGINE_finish(r->engine);
index 9598846e3bc8b8f64abc4e70b3a682440ab01c16..92758ca4c6175faade2af42a06778a2b14ea8564 100644 (file)
@@ -112,7 +112,7 @@ void DSA_free(DSA *r)
         return;
     REF_ASSERT_ISNT(i < 0);
 
-    if (r->meth->finish)
+    if (r->meth != NULL && r->meth->finish != NULL)
         r->meth->finish(r);
 #ifndef OPENSSL_NO_ENGINE
     ENGINE_finish(r->engine);
index f1f0afb466b50329666e99b7100a097b94bfa427..df35b64888c5e83c60d85ee5d762d17742537d87 100644 (file)
@@ -55,7 +55,7 @@ void EC_KEY_free(EC_KEY *r)
         return;
     REF_ASSERT_ISNT(i < 0);
 
-    if (r->meth->finish != NULL)
+    if (r->meth != NULL && r->meth->finish != NULL)
         r->meth->finish(r);
 
 #ifndef OPENSSL_NO_ENGINE
index e1377a06906be6e923bd91f66c95e12a6c5fbd47..97552fa335b2a40473c91109e0ba26f2c0aad883 100644 (file)
@@ -112,7 +112,7 @@ void RSA_free(RSA *r)
         return;
     REF_ASSERT_ISNT(i < 0);
 
-    if (r->meth->finish)
+    if (r->meth != NULL && r->meth->finish != NULL)
         r->meth->finish(r);
 #ifndef OPENSSL_NO_ENGINE
     ENGINE_finish(r->engine);