-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SSL_write: bad length
#793
Comments
The code in question: static VALUE
ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
{
SSL *ssl;
rb_io_t *fptr;
int num, nonblock = opts != Qfalse;
VALUE tmp;
GetSSL(self, ssl);
if (!ssl_started(ssl))
rb_raise(eSSLError, "SSL session is not started yet");
tmp = rb_str_new_frozen(StringValue(str));
VALUE io = rb_attr_get(self, id_i_io);
GetOpenFile(io, fptr);
/* SSL_write(3ssl) manpage states num == 0 is undefined */
num = RSTRING_LENINT(tmp);
if (num == 0)
return INT2FIX(0);
for (;;) {
int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
switch (ssl_get_error(ssl, nwritten)) {
case SSL_ERROR_NONE:
return INT2NUM(nwritten);
case SSL_ERROR_WANT_WRITE:
if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
io_wait_writable(io);
continue;
case SSL_ERROR_WANT_READ:
if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
io_wait_readable(io);
continue;
case SSL_ERROR_SYSCALL:
#ifdef __APPLE__
/*
* It appears that send syscall can return EPROTOTYPE if the
* socket is being torn down. Retry to get a proper errno to
* make the error handling in line with the socket library.
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
*/
if (errno == EPROTOTYPE)
continue;
#endif
if (errno) rb_sys_fail(0);
/* fallthrough */
default:
ossl_raise(eSSLError, "SSL_write");
}
}
} |
I see we are also setting |
If you can make a reproducer, you might get more information by enabling |
It's possible, although it would be an error in user code. The first By default OpenSSL checks if the buffer pointer is the same, as a quick sanity check, and One kind of diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
index 10942191dd76..bc638b121334 100644
--- a/test/openssl/test_pair.rb
+++ b/test/openssl/test_pair.rb
@@ -368,7 +368,7 @@ def test_write_nonblock_retry
assert_equal written, readed
# this fails if SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is missing:
- buf2 = Marshal.load(Marshal.dump(buf))
+ buf2 = Marshal.load(Marshal.dump(buf))[0..100]
assert_kind_of Integer, s1.write_nonblock(buf2, exception: false)
}
end |
I found a separate bug due to data corruption in my program. Maybe it was responsible for the error reported here… I also saw double free and core dump due to my invalid handling of OpenSSL sockets. I fixed the root cause and the problems appear to have all resolved, but I’ll keep an eye on it to see if |
Using OpenSSL::SSL incorrectly isn't supposed to cause a double free or core dump, as we try to avoid C-level undefined behavior. There must be something wrong. |
I observed double free segfault once and several sigabrt in production environment due to my programming error. I don't have time right now to investigate, but I'll try to circle back to this issue in the future to investigate. I think it's something to do with |
For reference, I observed this again:
The context is a bit different this time, maybe we were trying to write to a closed connection. |
I've noticed errors in Falcon when using recent versions of this gem.
Specifically,
SSL_write: bad length
is common.I was checking this issue: openssl/openssl#21002
I found this warning as a result: https://docs.openssl.org/master/man3/SSL_write/#warnings
I wonder if we are running into this issue?
I'll try to make a small reproduction.
The text was updated successfully, but these errors were encountered: