CC: | Lubomir Rintel <lkundrak [...] v3.sk> |
Subject: | [PATCH] Fix a use-after-free error |
Date: | Thu, 5 Dec 2013 15:07:26 +0100 |
To: | bug-Net-SSLeay [...] rt.cpan.org |
From: | Lubomir Rintel <lkundrak [...] v3.sk> |
Avoid using next_proto_data after it has been deallocated.
---
Changes | 1 +
SSLeay.xs | 21 ++++++++++++---------
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/Changes b/Changes
index ab7c950..483628e 100644
--- a/Changes
+++ b/Changes
@@ -8,6 +8,7 @@ Revision history for Perl extension Net::SSLeay.
Adjusted license: in META.yml to be 'openssl'
Adds support for the basic operations necessary to support ECDH for PFS,
e.g. EC_KEY_new_by_curve_name, EC_KEY_free and SSL_CTX_set_tmp_ecdh.
+ Fix an use-after-free error. Patch from Lubomir Rintel.
1.55 2013-06-08
Added support for TLSV1_1 and TLSV1_2 methods with SSL_CTX_tlsv1_1_new(),
diff --git a/SSLeay.xs b/SSLeay.xs
index 16c7604..9fb8e99 100644
--- a/SSLeay.xs
+++ b/SSLeay.xs
@@ -844,19 +844,22 @@ int next_proto_select_cb_invoke(SSL *ssl, unsigned char **out, unsigned char *ou
croak ("Net::SSLeay: next_proto_select_cb_invoke perl function did not return 2 values.\n");
next_proto_data = (unsigned char*)POPpx;
next_proto_status = POPi;
+
+ next_proto_len = strlen((const char*)next_proto_data);
+ if (next_proto_len<=255) {
+ /* store last_status + last_negotiated into global hash */
+ cb_data_advanced_put(ssl, "next_proto_select_cb!!last_status", newSViv(next_proto_status));
+ tmpsv = newSVpv((const char*)next_proto_data, next_proto_len);
+ cb_data_advanced_put(ssl, "next_proto_select_cb!!last_negotiated", tmpsv);
+ *out = (unsigned char *)SvPVX(tmpsv);
+ *outlen = next_proto_len;
+ }
+
PUTBACK;
FREETMPS;
LEAVE;
- if (strlen((const char*)next_proto_data)>255) return SSL_TLSEXT_ERR_ALERT_FATAL;
- next_proto_len = strlen((const char*)next_proto_data);
- /* store last_status + last_negotiated into global hash */
- cb_data_advanced_put(ssl, "next_proto_select_cb!!last_status", newSViv(next_proto_status));
- tmpsv = newSVpv((const char*)next_proto_data, next_proto_len);
- cb_data_advanced_put(ssl, "next_proto_select_cb!!last_negotiated", tmpsv);
- *out = (unsigned char *)SvPVX(tmpsv);
- *outlen = next_proto_len;
- return SSL_TLSEXT_ERR_OK;
+ return next_proto_len>255 ? SSL_TLSEXT_ERR_ALERT_FATAL : SSL_TLSEXT_ERR_OK;
}
else if (SvROK(cb_data) && (SvTYPE(SvRV(cb_data)) == SVt_PVAV)) {
next_proto_len = next_proto_helper_AV2protodata((AV*)SvRV(cb_data), NULL);
--
1.7.1