Skip to content

Commit a0dd9df

Browse files
csapuntzbagder
authored andcommitted
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.
1 parent 4724b9d commit a0dd9df

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

CHANGES

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
Changelog
88

9+
Daniel Stenberg (5 June 2010)
10+
- Constantine Sapuntzakis fixed a case of spurious SSL connection aborts using
11+
libcurl and OpenSSL. "I tracked it down to uncleared error state on the
12+
OpenSSL error stack - patch attached deals with that."
13+
914
Daniel Stenberg (5 June 2010)
1015
- Frank Meier added CURLINFO_PRIMARY_PORT, CURLINFO_LOCAL_IP and
1116
CURLINFO_LOCAL_PORT to curl_easy_getinfo().

RELEASE-NOTES

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ This release includes the following bugfixes:
3737
o TFTP block id wrap
3838
o curl_multi_socket_action() timeout handles inaccuracy in timers better
3939
o SCP/SFTP failure to respect the timeout
40+
o spurious SSL connection aborts with OpenSSL
4041

4142
This release includes the following known bugs:
4243

@@ -49,7 +50,7 @@ advice from friends like these:
4950
Kamil Dudka, Alex Bligh, Ben Greear, Hoi-Ho Chan, Howard Chu, Dirk Manske,
5051
Pavel Raiskup, John-Mark Bell, Eric Mertens, Tor Arntsen, Douglas Kilpatrick,
5152
Igor Novoseltsev, Jason McDonald, Dan Fandrich, Tanguy Fautre, Guenter Knauf,
52-
Julien Chaffraix, Kalle Vahlman, Frank Meier
53+
Julien Chaffraix, Kalle Vahlman, Frank Meier, Constantine Sapuntzakis
5354

5455

5556
Thanks! (and sorry if I forgot to mention someone)

lib/ssluse.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#include <openssl/x509v3.h>
6565
#include <openssl/dsa.h>
6666
#include <openssl/dh.h>
67+
#include <openssl/err.h>
6768
#else
6869
#include <rand.h>
6970
#include <x509v3.h>
@@ -882,6 +883,8 @@ int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
882883
int what = Curl_socket_ready(conn->sock[sockindex],
883884
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
884885
if(what > 0) {
886+
ERR_clear_error();
887+
885888
/* Something to read, let's do it and hope that it is the close
886889
notify alert from the server */
887890
nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
@@ -1684,6 +1687,8 @@ ossl_connect_step2(struct connectdata *conn, int sockindex)
16841687
|| ssl_connect_2_reading == connssl->connecting_state
16851688
|| ssl_connect_2_writing == connssl->connecting_state);
16861689

1690+
ERR_clear_error();
1691+
16871692
err = SSL_connect(connssl->handle);
16881693

16891694
/* 1 is fine
@@ -2512,6 +2517,8 @@ static ssize_t ossl_send(struct connectdata *conn,
25122517
int memlen;
25132518
int rc;
25142519

2520+
ERR_clear_error();
2521+
25152522
memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
25162523
rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
25172524

@@ -2560,6 +2567,8 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
25602567
ssize_t nread;
25612568
int buffsize;
25622569

2570+
ERR_clear_error();
2571+
25632572
buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
25642573
nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize);
25652574
if(nread < 0) {

0 commit comments

Comments
 (0)