You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2020/06/23 20:08:02 UTC
[trafficserver] 02/03: Prevent stale netvc access on SSL Callbacks
(#6925)
This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 5c4bd018d910d47f2e89bb26bac7733ba6039ee7
Author: Sudheer Vinukonda <su...@apache.org>
AuthorDate: Mon Jun 22 05:44:47 2020 -0700
Prevent stale netvc access on SSL Callbacks (#6925)
Since SSL Callbacks are asynchronous in nature, it's possible the
associated NetVC is already freed causing a potential use-after-free
problem.
(cherry picked from commit c7e80542aa1a5323399226f636ef196955f60791)
---
iocore/net/SSLNetVConnection.cc | 4 ++--
iocore/net/SSLUtils.cc | 36 +++++++++++++++++++++++++++++++++++-
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 94a9815..405158f 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -1505,7 +1505,7 @@ SSLNetVConnection::advertise_next_protocol(SSL *ssl, const unsigned char **out,
{
SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
- ink_release_assert(netvc != nullptr);
+ ink_release_assert(netvc && netvc->ssl == ssl);
if (netvc->getNPN(out, outlen)) {
// Successful return tells OpenSSL to advertise.
@@ -1522,7 +1522,7 @@ SSLNetVConnection::select_next_protocol(SSL *ssl, const unsigned char **out, uns
{
SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
- ink_release_assert(netvc != nullptr);
+ ink_release_assert(netvc && netvc->ssl == ssl);
const unsigned char *npnptr = nullptr;
unsigned int npnsize = 0;
if (netvc->getNPN(&npnptr, &npnsize)) {
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index 9387a65..56fae1d 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -250,6 +250,12 @@ set_context_cert(SSL *ssl)
bool found = true;
int retval = 1;
+ if (!netvc || netvc->ssl != ssl) {
+ Debug("ssl.error", "set_context_cert call back on stale netvc");
+ retval = 0; // Error
+ goto done;
+ }
+
Debug("ssl", "set_context_cert ssl=%p server=%s handshake_complete=%d", ssl, servername, netvc->getSSLHandShakeComplete());
// catch the client renegotiation early on
@@ -317,6 +323,11 @@ ssl_verify_client_callback(int preverify_ok, X509_STORE_CTX *ctx)
auto *ssl = static_cast<SSL *>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
+ if (!netvc || netvc->ssl != ssl) {
+ Debug("ssl.error", "ssl_verify_client_callback call back on stale netvc");
+ return false;
+ }
+
netvc->set_verify_cert(ctx);
netvc->callHooks(TS_EVENT_SSL_VERIFY_CLIENT);
netvc->set_verify_cert(nullptr);
@@ -355,6 +366,12 @@ ssl_client_hello_callback(SSL *s, int *al, void *arg)
const char *servername = nullptr;
const unsigned char *p;
size_t remaining, len;
+
+ if (!netvc || netvc->ssl != s) {
+ Debug("ssl.error", "ssl_client_hello_callback call back on stale netvc");
+ return SSL_CLIENT_HELLO_ERROR;
+ }
+
// Parse the server name if the get extension call succeeds and there are more than 2 bytes to parse
if (SSL_client_hello_get0_ext(s, TLSEXT_TYPE_server_name, &p, &remaining) && remaining > 2) {
// Parse to get to the name, originally from test/handshake_helper.c in openssl tree
@@ -414,6 +431,11 @@ ssl_cert_callback(SSL *ssl, void * /*arg*/)
bool reenabled;
int retval = 1;
+ if (!netvc || netvc->ssl != ssl) {
+ Debug("ssl.error", "ssl_cert_callback call back on stale netvc");
+ return 0;
+ }
+
// If we are in tunnel mode, don't select a cert. Pause!
if (HttpProxyPort::TRANSPORT_BLIND_TUNNEL == netvc->attributes) {
return -1; // Pause
@@ -447,6 +469,12 @@ static int
ssl_servername_callback(SSL *ssl, int * /* ad */, void * /*arg*/)
{
SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
+
+ if (!netvc || netvc->ssl != ssl) {
+ Debug("ssl.error", "ssl_servername_callback call back on stale netvc");
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+
netvc->callHooks(TS_EVENT_SSL_SERVERNAME);
const char *name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
@@ -1019,7 +1047,12 @@ ssl_callback_info(const SSL *ssl, int where, int ret)
SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
- if (netvc && (where & SSL_CB_ACCEPT_LOOP) && netvc->getSSLHandShakeComplete() == true &&
+ if (!netvc || netvc->ssl != ssl) {
+ Debug("ssl.error", "ssl_callback_info call back on stale netvc");
+ return;
+ }
+
+ if ((where & SSL_CB_ACCEPT_LOOP) && netvc->getSSLHandShakeComplete() == true &&
SSLConfigParams::ssl_allow_client_renegotiation == false) {
int state = SSL_get_state(ssl);
@@ -1790,6 +1823,7 @@ SSLAccept(SSL *ssl)
#if TS_HAS_TLS_EARLY_DATA
SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
+
if (SSLConfigParams::server_max_early_data > 0 && !netvc->early_data_finish) {
size_t nread;
if (netvc->early_data_buf == nullptr) {