tls panic inside /usr/local/go/src/crypto/tls/conn.go

123 views
Skip to first unread message

Andrew Athan

unread,
Feb 10, 2023, 5:24:39 PM2/10/23
to golang-nuts
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5d073c]
goroutine 4133611 [running]:
crypto/tls.(*Conn).handshakeContext.func2()
  /usr/local/go/src/crypto/tls/conn.go:1441 +0xbc
created by crypto/tls.(*Conn).handshakeContext
  /usr/local/go/src/crypto/tls/conn.go:1437 +0x205
Main process exited, code=exited, status=2/INVALIDARGUMENT
Failed with result 'exit-code'.

I'm still evaluating this panic in a high load server app, probably related to using a custom dial func + specifying a handshake timeout. I'm guessing this is not a very oft-used feature of the stack, so I thought I'd post this while I go read the tls/conn.go code. Google did not immediately come up with other reports of this problem but given the location, and that my code doesn't mess with any conn internals beyond specifying the timeout, I'm thinking (probably incorrectly, lol) that this bug may not be mine.

var internalTransport *http.Transport = &http.Transport{
  DialContext: func(ctx context.Context, network, addr string) (ret net.Conn, err error) {
   return transportDialFunc(ctx, network, addr, myStuff)
  },
  TLSHandshakeTimeout: TLS_HANDSHAKE_TIMEOUT,
}

Andrew Athan

unread,
Feb 10, 2023, 5:25:53 PM2/10/23
to golang-nuts
Sorry, I meant to mention this is go 1.19

Andrew Athan

unread,
Feb 10, 2023, 5:33:49 PM2/10/23
to golang-nuts
go func() {
select {
case <-handshakeCtx.Done():
// Close the connection, discarding the error
_ = c.conn.Close()
interruptRes <- handshakeCtx.Err()
case <-done:
interruptRes <- nil
}
}()


I believe the problem may be that this should have said:
conn := c.conn
if conn!= nil {
  conn.Close()
}

???

I'll install golang 1.20 and see if the code has been improved and/or will submit a PR

gbarr

unread,
Feb 11, 2023, 5:32:37 AM2/11/23
to golang-nuts
My guess is that your transportDialFunc function is returning (nil, nil) which the http transport code is not expecting. If you cannot create a connection then you should return a non-nil error. 

However the Transport.dial function in net/http/transport.go does catch this case when using Transport.Dial but not when using Transport.DialContext, so this is the likely location a patch is needed

Graham.

gbarr

unread,
Feb 11, 2023, 5:35:00 AM2/11/23
to golang-nuts
On Saturday, February 11, 2023 at 10:32:37 AM UTC gbarr wrote:
My guess is that your transportDialFunc function is returning (nil, nil) which the http transport code is not expecting. If you cannot create a connection then you should return a non-nil error. 

However the Transport.dial function in net/http/transport.go does catch this case when using Transport.Dial but not when using Transport.DialContext, so this is the likely location a patch is needed

Reply all
Reply to author
Forward
0 new messages