Skip to content

Consistenty - IOError vs EBADF? #798

@ioquatix

Description

@ioquatix

SSLSocket error conditions are not consistent with IO.

  1. io.close followed by io.read can result in EBADF rather than IOError.
  2. Without sync_close, io.close followed by io.read will hang. Even if the underlying IO is not closed, I don't think the SSLSocket instance should continue to work after being closed?

Reproduction:

#!/usr/bin/env ruby

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'localhost'
end

require 'socket'
require 'openssl'
require 'localhost'

def read_after_close(io)
  io.close
  io.read
end

begin
  client, server = Socket.pair(:UNIX, :STREAM)
  read_after_close(client)
rescue => error
  $stderr.puts error.full_message
end

begin
  authority = Localhost::Authority.fetch
  
  client, server = Socket.pair(:UNIX, :STREAM)
  
  ssl_server = OpenSSL::SSL::SSLSocket.new(server, authority.server_context)
  ssl_server.sync_close = true
  
  ssl_client = OpenSSL::SSL::SSLSocket.new(client, authority.client_context)
  ssl_client.sync_close = true # If this is not set, `io.read` above will hang which is also a bit odd.
  
  Thread.new{ssl_server.accept}
  
  ssl_client.connect
  
  read_after_close(ssl_client)
rescue => error
  $stderr.puts error.full_message
end

Is this something we can improve?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions