From a0dd9df9ab35528eb9eb669e741a5df4b1fb833c Mon Sep 17 00:00:00 2001 From: Constantine Sapuntzakis Date: Sat, 5 Jun 2010 23:41:58 +0200 Subject: [PATCH] OpenSSL: fix spurious SSL connection aborts Was seeing spurious SSL connection aborts using libcurl and OpenSSL. I tracked it down to uncleared error state on the OpenSSL error stack - patch attached deals with that. Rough idea of problem: Code that uses libcurl calls some library that uses OpenSSL but don't clear the OpenSSL error stack after an error. ssluse.c calls SSL_read which eventually gets an EWOULDBLOCK from the OS. Returns -1 to indicate an error ssluse.c calls SSL_get_error. First thing, SSL_get_error calls ERR_get_error to check the OpenSSL error stack, finds an old error and returns SSL_ERROR_SSL instead of SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. ssluse.c returns an error and aborts the connection Solution: Clear the openssl error stack before calling SSL_* operation if we're going to call SSL_get_error afterwards. Notes: This is much more likely to happen with multi because it's easier to intersperse other calls to the OpenSSL library in the same thread. --- CHANGES | 5 +++++ RELEASE-NOTES | 3 ++- lib/ssluse.c | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 4379303..6ea7c7c 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,11 @@ Changelog Daniel Stenberg (5 June 2010) +- Constantine Sapuntzakis fixed a case of spurious SSL connection aborts using + libcurl and OpenSSL. "I tracked it down to uncleared error state on the + OpenSSL error stack - patch attached deals with that." + +Daniel Stenberg (5 June 2010) - Frank Meier added CURLINFO_PRIMARY_PORT, CURLINFO_LOCAL_IP and CURLINFO_LOCAL_PORT to curl_easy_getinfo(). diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 63860cd..d959919 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -37,6 +37,7 @@ This release includes the following bugfixes: o TFTP block id wrap o curl_multi_socket_action() timeout handles inaccuracy in timers better o SCP/SFTP failure to respect the timeout + o spurious SSL connection aborts with OpenSSL This release includes the following known bugs: @@ -49,7 +50,7 @@ advice from friends like these: Kamil Dudka, Alex Bligh, Ben Greear, Hoi-Ho Chan, Howard Chu, Dirk Manske, Pavel Raiskup, John-Mark Bell, Eric Mertens, Tor Arntsen, Douglas Kilpatrick, Igor Novoseltsev, Jason McDonald, Dan Fandrich, Tanguy Fautre, Guenter Knauf, - Julien Chaffraix, Kalle Vahlman, Frank Meier + Julien Chaffraix, Kalle Vahlman, Frank Meier, Constantine Sapuntzakis Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/ssluse.c b/lib/ssluse.c index 01eba90..1b4da33 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -64,6 +64,7 @@ #include #include #include +#include #else #include #include @@ -882,6 +883,8 @@ int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) int what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); if(what > 0) { + ERR_clear_error(); + /* Something to read, let's do it and hope that it is the close notify alert from the server */ nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf, @@ -1684,6 +1687,8 @@ ossl_connect_step2(struct connectdata *conn, int sockindex) || ssl_connect_2_reading == connssl->connecting_state || ssl_connect_2_writing == connssl->connecting_state); + ERR_clear_error(); + err = SSL_connect(connssl->handle); /* 1 is fine @@ -2512,6 +2517,8 @@ static ssize_t ossl_send(struct connectdata *conn, int memlen; int rc; + ERR_clear_error(); + memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen); @@ -2560,6 +2567,8 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ ssize_t nread; int buffsize; + ERR_clear_error(); + buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize); if(nread < 0) { -- 2.7.4