From 0c5d725ebf31ce7b6db9d638aab508da3263444d Mon Sep 17 00:00:00 2001 From: Nicola Tuveri Date: Wed, 5 Sep 2018 11:58:55 +0300 Subject: [PATCH] Fix segfault in RSA_free() (and DSA/DH/EC_KEY) `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 Reviewed-by: Tim Hudson Reviewed-by: Matt Caswell Reviewed-by: Matthias St. Pierre Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/7121) --- crypto/dh/dh_lib.c | 2 +- crypto/dsa/dsa_lib.c | 2 +- crypto/ec/ec_key.c | 2 +- crypto/rsa/rsa_lib.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index e425225192..2e0393e475 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -104,7 +104,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); diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 739fde65c4..2eb8ee7ad5 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -111,7 +111,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); diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index ec10b7e4a2..9349abf030 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -51,7 +51,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 diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 61b1c16df6..16e97c2a00 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -115,7 +115,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); -- 2.39.2