Skip to content

Commit ed948ea

Browse files
authored
Merge pull request #1115 from rhenium/ky/ssl-handshake-clear-error-on-syserr
ssl: clear error queue before raising SystemCallError
2 parents cfa7645 + d940e09 commit ed948ea

2 files changed

Lines changed: 31 additions & 26 deletions

File tree

‎ext/openssl/ossl_ssl.c‎

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,13 +1874,15 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18741874
io_wait_readable(io);
18751875
continue;
18761876
case SSL_ERROR_SYSCALL:
1877+
if (saved_errno) {
1878+
ossl_clear_error();
18771879
#ifdef __APPLE__
1878-
/* See ossl_ssl_write_internal() */
1879-
if (saved_errno == EPROTOTYPE)
1880-
continue;
1880+
/* See ossl_ssl_write_internal() */
1881+
if (saved_errno == EPROTOTYPE)
1882+
continue;
18811883
#endif
1882-
if (saved_errno)
18831884
rb_exc_raise(rb_syserr_new(saved_errno, funcname));
1885+
}
18841886
/* fallthrough */
18851887
default: {
18861888
VALUE error_append = Qnil;
@@ -2078,20 +2080,20 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
20782080
io_wait_readable(io);
20792081
break;
20802082
case SSL_ERROR_SYSCALL:
2083+
if (saved_errno) {
2084+
ossl_clear_error();
2085+
rb_exc_raise(rb_syserr_new(saved_errno, "SSL_read"));
2086+
}
20812087
if (!ERR_peek_error()) {
2082-
if (saved_errno)
2083-
rb_exc_raise(rb_syserr_new(saved_errno, "SSL_read"));
2084-
else {
2085-
/*
2086-
* The underlying BIO returned 0. This is actually a
2087-
* protocol error. But unfortunately, not all
2088-
* implementations cleanly shutdown the TLS connection
2089-
* but just shutdown/close the TCP connection. So report
2090-
* EOF for now...
2091-
*/
2092-
if (no_exception_p(opts)) { return Qnil; }
2093-
rb_eof_error();
2094-
}
2088+
/*
2089+
* The underlying BIO returned 0. This is actually a
2090+
* protocol error. But unfortunately, not all
2091+
* implementations cleanly shutdown the TLS connection
2092+
* but just shutdown/close the TCP connection. So report
2093+
* EOF for now...
2094+
*/
2095+
if (no_exception_p(opts)) { return Qnil; }
2096+
rb_eof_error();
20952097
}
20962098
/* fall through */
20972099
default:
@@ -2188,18 +2190,20 @@ ossl_ssl_write_internal_safe(VALUE _args)
21882190
io_wait_readable(io);
21892191
continue;
21902192
case SSL_ERROR_SYSCALL:
2193+
if (saved_errno) {
2194+
ossl_clear_error();
21912195
#ifdef __APPLE__
2192-
/*
2193-
* It appears that send syscall can return EPROTOTYPE if the
2194-
* socket is being torn down. Retry to get a proper errno to
2195-
* make the error handling in line with the socket library.
2196-
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2197-
*/
2198-
if (saved_errno == EPROTOTYPE)
2199-
continue;
2196+
/*
2197+
* It appears that send syscall can return EPROTOTYPE if the
2198+
* socket is being torn down. Retry to get a proper errno to
2199+
* make the error handling in line with the socket library.
2200+
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2201+
*/
2202+
if (saved_errno == EPROTOTYPE)
2203+
continue;
22002204
#endif
2201-
if (saved_errno)
22022205
rb_exc_raise(rb_syserr_new(saved_errno, "SSL_write"));
2206+
}
22032207
/* fallthrough */
22042208
default:
22052209
ossl_raise(eSSLError, "SSL_write");

‎test/openssl/test_ssl.rb‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,7 @@ def test_connect_systemcallerror
12551255
assert_raise(Errno::ECONNRESET, Errno::EPIPE) {
12561256
ssl.connect
12571257
}
1258+
assert_empty(OpenSSL.errors)
12581259
ensure
12591260
sock&.close
12601261
end

0 commit comments

Comments
 (0)