Backport #8240 ยป openssl_invalid_shutdown_fix.diff
ext/openssl/ossl_ssl.c | ||
---|---|---|
static void
|
||
ossl_ssl_free(SSL *ssl)
|
||
{
|
||
ossl_ssl_shutdown(ssl);
|
||
SSL_free(ssl);
|
||
}
|
||
... | ... | |
ossl_ssl_data_get_struct(self, ssl);
|
||
ossl_ssl_shutdown(ssl);
|
||
if (RTEST(ossl_ssl_get_sync_close(self)))
|
||
rb_funcall(ossl_ssl_get_io(self), rb_intern("close"), 0);
|
||
if (ssl) {
|
||
VALUE io = ossl_ssl_get_io(self);
|
||
if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) {
|
||
ossl_ssl_shutdown(ssl);
|
||
SSL_free(ssl);
|
||
DATA_PTR(self) = NULL;
|
||
if (RTEST(ossl_ssl_get_sync_close(self)))
|
||
rb_funcall(io, rb_intern("close"), 0);
|
||
}
|
||
}
|
||
return Qnil;
|
||
}
|
test/openssl/test_ssl.rb | ||
---|---|---|
end
|
||
def test_invalid_shutdown_by_gc
|
||
assert_nothing_raised {
|
||
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
|
||
10.times {
|
||
sock = TCPSocket.new("127.0.0.1", port)
|
||
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
||
GC.start
|
||
ssl.connect
|
||
sock.close
|
||
}
|
||
}
|
||
}
|
||
end
|
||
def test_close_after_socket_close
|
||
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
|
||
sock = TCPSocket.new("127.0.0.1", port)
|
||
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
||
ssl.sync_close = true
|
||
ssl.connect
|
||
sock.close
|
||
assert_nothing_raised do
|
||
ssl.close
|
||
end
|
||
}
|
||
end
|
||
private
|
||
def start_server_version(version, ctx_proc=nil, server_proc=nil, &blk)
|