Skip to content

crypto/tls: set timeout so that Close does not block indefinitely #31224

Closed
@NWilson

Description

@NWilson

What did you do?

Reading the documentation for tls.Conn (https://golang.org/pkg/crypto/tls/) the deadline behaviour is not clearly explained.

  • It's not obvious that Read calls may block forever unless the write deadline is set to a non-zero time. (This is because handshaking is done internally, which writes.) Since this is different to net.TLSConn, it should be called out.
  • It's reasonable to understand that Handshake calls need to have both read and write deadline set... but could be called out explicitly.
  • But the killer: calling Close on a tls.Conn risks blocking forever, unless the write deadline has been set! (It writes out a close alert.)

This last one is the worst. It would be very easy to have a defer'ed call to Close, and assume that it will always return promptly, when in fact it may be possible for a malicious client to fill up the socket buffers with handshaking data, so that writing the close alert blocks (on an OS with tiny socket buffers?).

I have (or had) some code that does the following:

for {
  conn, _ := listener.Accept() // error handling omitted for clarity
  if tooManyConns() {
    conn.Close() // oops, may block!
    continue
  }
  go handleConn(conn)
}

I have now carefully gone and wrapped all calls to Close with a safeClose wrapper method that calls SetWriteDeadline first!

Perhaps Close should actually call SetWriteDeadline on the underlying connection with a sane value (eg time.Now().Add(100*time.Millisecond)) to ensure that no-one else is caught out.

Thankfully, http.conn.serve does call SetWriteDeadline as soon as possible for TLS connections, and never sets a zero write deadline, so that code at least is safe, and can't call Close with a zero deadline.

What did you expect to see?

More mention of what deadlines need to set, to prevent each method blocking.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.help wanted

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions