[PATCH] Fix possible use after free in tls_connection_private_key
Alexander Kabaev
kan at freebsd.org
Wed Jul 12 17:59:51 PDT 2017
The code erroneously sets callback on the SSL_CTX, but the code
uses SSL_use_PrivateKey_file, which accepts con->ssl and in turn
invokes PEM_read_bio_PrivateKey as follows:
pkey = PEM_read_bio_PrivateKey(in, NULL,
ssl->default_passwd_callback,
ssl->default_passwd_callback_userdata);
So the tls_connection_private_key always fails first time around, and when
it does so, it leaves callback pointer in SSL_CTX set to tls_passwd_cb,
and callback userdata set to strdup-ed and then freed string. So, at the
time of the next iteraction, these callback and dangling data are copied
from SSL_CTX to SSL and callback does get invoked and it accesses the
freed memory as the password string.
To fix the issue, remove the code to set/clear callback in SSL_CTX and
set it only in conn->ssl for the duration of the function.
Signed-off-by: Alexander Kabaev <kan at FreeBSD.org>
---
src/crypto/tls_openssl.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 07c61193a..63279f8f1 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -2782,7 +2782,6 @@ static int tls_connection_private_key(struct tls_data *data,
const u8 *private_key_blob,
size_t private_key_blob_len)
{
- SSL_CTX *ssl_ctx = data->ssl;
char *passwd;
int ok;
@@ -2796,8 +2795,8 @@ static int tls_connection_private_key(struct tls_data *data,
} else
passwd = NULL;
- SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
- SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
+ SSL_set_default_passwd_cb(conn->ssl, tls_passwd_cb);
+ SSL_set_default_passwd_cb_userdata(conn->ssl, passwd);
ok = 0;
while (private_key_blob) {
@@ -2879,15 +2878,14 @@ static int tls_connection_private_key(struct tls_data *data,
break;
}
+ SSL_set_default_passwd_cb(conn->ssl, NULL);
+ os_free(passwd);
if (!ok) {
tls_show_errors(MSG_INFO, __func__,
"Failed to load private key");
- os_free(passwd);
return -1;
}
ERR_clear_error();
- SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
- os_free(passwd);
if (!SSL_check_private_key(conn->ssl)) {
tls_show_errors(MSG_INFO, __func__, "Private key failed "
--
2.13.0
More information about the Hostap
mailing list