diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-11-13 22:18:00 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-11-13 23:10:16 +0900 |
commit | 072d53ecf9844d4080d7fffdf5ef9434d0a9ab82 (patch) | |
tree | 4dc79c2149fcb4403c3ca15133838abb1649ed8a /ext | |
parent | c86e2aa39760dc1f9c93ff63084d12d1a950a306 (diff) | |
download | ruby-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
Diffstat (limited to 'ext')
-rw-r--r-- | ext/openssl/ossl_ssl.c | 18 |
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"); } |