aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-11-13 22:18:00 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-11-13 23:10:16 +0900
commit072d53ecf9844d4080d7fffdf5ef9434d0a9ab82 (patch)
tree4dc79c2149fcb4403c3ca15133838abb1649ed8a
parentc86e2aa39760dc1f9c93ff63084d12d1a950a306 (diff)
downloadruby-openssl-072d53ecf9844d4080d7fffdf5ef9434d0a9ab82.tar.gz
ssl: workaround for new behavior of SSL_read() in OpenSSL >= 1.1.0c
Commit 4880672a9b41 of OpenSSL[1] (which then was backported to 1.1.0 branch at 122580ef71e4) changed the bahavior of SSL_read(): it now returns -1 in the case the underlying BIO reaches EOF unexpectedly. This means, it is possible that rb_sys_fail() is called with errno == 0, resulting in [BUG]. So, as a workaround, let's distinguish IO error from the underlying BIO and EOF in violation of SSL/TLS protocol with the value of errno. [1] https://git.openssl.org/?p=openssl.git;a=commit;h=4880672a9b41a09a0984b55e219f02a2de7ab75e
-rw-r--r--ext/openssl/ossl_ssl.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index cf1502eb..6931e998 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -1706,11 +1706,21 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
rb_io_wait_readable(FPTR_TO_FD(fptr));
continue;
case SSL_ERROR_SYSCALL:
- if(ERR_peek_error() == 0 && nread == 0) {
- if (no_exception_p(opts)) { return Qnil; }
- rb_eof_error();
+ if (!ERR_peek_error()) {
+ /*
+ * XXX: OpenSSL commit 4880672a9b41 (backported to 1.1.0c)
+ * changed SSL_read() to return -1 on unexpected EOF because
+ * it's not retryable, contrary to the manpage.
+ * Remove this comment (and maybe fix the condition) when
+ * the manpage or the implementation is fixed.
+ */
+ if (errno)
+ rb_sys_fail(0);
+ else {
+ if (no_exception_p(opts)) { return Qnil; }
+ rb_eof_error();
+ }
}
- rb_sys_fail(0);
default:
ossl_raise(eSSLError, "SSL_read");
}