diff options
author | rhe <rhe@ruby-lang.org> | 2016-05-21 07:25:00 +0000 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-05-31 11:31:27 +0900 |
commit | 63f74fb70f8059e08a69dfe0aa8216ef2d9dd0d3 (patch) | |
tree | 933292a460008c8c2f3dc67f13453bd28b377313 /test/test_ssl.rb | |
parent | fbb063354800b4b561a6b64fccddfcaf8a5011f4 (diff) | |
download | ruby-openssl-63f74fb70f8059e08a69dfe0aa8216ef2d9dd0d3.tar.gz |
openssl: fix possible SEGV on race between SSLSocket#stop and #connect
* ext/openssl/ossl_ssl.c (ossl_ssl_stop): Don't free the SSL struct
here. Since some methods such as SSLSocket#connect releases GVL,
there is a chance of use after free if we free the SSL from another
thread. SSLSocket#stop was documented as "prepares it for another
connection" so this is a slightly incompatible change. However when
this sentence was added (r30090, Add toplevel documentation for
OpenSSL, 2010-12-06), it didn't actually. The current behavior is
from r40304 (Correct shutdown behavior w.r.t GC., 2013-04-15).
[ruby-core:74978] [Bug #12292]
* ext/openssl/lib/openssl/ssl.rb (sysclose): Update doc.
* test/openssl/test_ssl.rb: Test this.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55100 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/test_ssl.rb')
-rw-r--r-- | test/test_ssl.rb | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/test/test_ssl.rb b/test/test_ssl.rb index 32f7cfde..cb119dcd 100644 --- a/test/test_ssl.rb +++ b/test/test_ssl.rb @@ -1169,6 +1169,28 @@ end } end + def test_close_and_socket_close_while_connecting + # test it doesn't cause a segmentation fault + ctx = OpenSSL::SSL::SSLContext.new + ctx.ciphers = "aNULL" + + sock1, sock2 = socketpair + ssl1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx) + ssl2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx) + + t = Thread.new { ssl1.connect } + ssl2.accept + + ssl1.close + sock1.close + t.value rescue nil + ensure + ssl1.close if ssl1 + ssl2.close if ssl2 + sock1.close if sock1 + sock2.close if sock2 + end + def test_get_ephemeral_key return unless OpenSSL::SSL::SSLSocket.method_defined?(:tmp_key) pkey = OpenSSL::PKey |