diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-04-15 12:06:01 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-04-16 20:07:10 +0900 |
commit | c4030a10535232988bf597759278f700d82f104b (patch) | |
tree | aa7b001dfadec9435c6fe542700e82dcb7fa24d1 /ext | |
parent | 1826991f26249735e29b06778723f4808f0ee1dc (diff) | |
download | ruby-c4030a10535232988bf597759278f700d82f104b.tar.gz |
ext/openssl: make OpenSSL::SSL::SSLSocket non-reusable
Fix the segmentation fault due to use after free of SSL object.
Don't free the SSL object in SSLSocket#stop and leave it in RTypedData.
OpenSSL::SSL::SSLSocket#stop (and the wrapper method #sysclose) was
documented as "Stops the SSL connection and prepares it for another
connection" and this patch changes it: once the SSLSocket stopped, it
can no longer hold a new SSL connection.
The method used to free the SSL object immediately after SSL_shutdown(),
but it is problematic. Since some methods, such as SSLSocket#connect
release the GVL while waiting the peer, there is a good chance that the
SSL object is freed from another thread and this leads to a segmentation
fault.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/openssl/lib/openssl/ssl.rb | 5 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.c | 7 |
2 files changed, 7 insertions, 5 deletions
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb index 57519f2c21..9893757011 100644 --- a/ext/openssl/lib/openssl/ssl.rb +++ b/ext/openssl/lib/openssl/ssl.rb @@ -290,7 +290,10 @@ module OpenSSL # call-seq: # ssl.sysclose => nil # - # Shuts down the SSL connection and prepares it for another connection. + # Sends "close notify" to the peer and tries to shut down the SSL + # connection gracefully. + # + # If sync_close is set to +true+, the underlying IO is also closed. def sysclose return if closed? stop diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 96c7990046..416fa91cae 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1598,7 +1598,8 @@ ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self) * call-seq: * ssl.stop => nil * - * Stops the SSL connection and prepares it for another connection. + * Sends "close notify" to the peer and tries to shut down the SSL connection + * gracefully. */ static VALUE ossl_ssl_stop(VALUE self) @@ -1607,14 +1608,12 @@ ossl_ssl_stop(VALUE self) /* ossl_ssl_data_get_struct() is not usable here because it may return * from this function; */ - GetSSL(self, ssl); if (ssl) { + /* the SSL object will be freed by GC */ ossl_ssl_shutdown(ssl); - SSL_free(ssl); } - DATA_PTR(self) = NULL; return Qnil; } |