Skip to content

crypto/tls: panic with crypto/tls/fipsonly #67145

Description

@etodd

Go version

go version go1.22.2 linux/amd64

Output of go env in your module/workspace:

O111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT='boringcrypto'
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.2'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/root/thing/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build4147770740=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I attempted to connect to AWS Aurora over TLS using database/sql with GOEXPERIMENT=boringcrypto and import _ "crypto/tls/fipsonly" and got an error. It is difficult to reproduce because I connected and queried one Aurora instance just fine, but the other threw an error.

What did you see happen?

I got an error when attempting the connection. It was a recovered nil pointer panic. After removing the recover() call, I got this:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6772f2]

goroutine 1 [running]:
internal/godebug.(*Setting).IncNonDefault(0x7bf6a0?)
        /usr/local/go/src/internal/godebug/godebug.go:102 +0x12
crypto/tls.(*clientHandshakeState).pickCipherSuite(0xc00007eea0)
        /usr/local/go/src/crypto/tls/handshake_client.go:530 +0xbd
crypto/tls.(*clientHandshakeState).processServerHello(0xc00007eea0)
        /usr/local/go/src/crypto/tls/handshake_client.go:755 +0x25
crypto/tls.(*clientHandshakeState).handshake(0xc00007eea0)
        /usr/local/go/src/crypto/tls/handshake_client.go:442 +0x35
crypto/tls.(*Conn).clientHandshake(0xc000004a88, {0x872190, 0xc0000744b0})
        /usr/local/go/src/crypto/tls/handshake_client.go:274 +0x685
crypto/tls.(*Conn).handshakeContext(0xc000004a88, {0x872120, 0xaae120})
        /usr/local/go/src/crypto/tls/conn.go:1553 +0x3cb
crypto/tls.(*Conn).HandshakeContext(...)
        /usr/local/go/src/crypto/tls/conn.go:1493
crypto/tls.(*Conn).Handshake(...)
        /usr/local/go/src/crypto/tls/conn.go:1477
crypto/tls.(*Conn).Write(0x7c1f80?, {0xc00015c029, 0x60, 0x1ff})
        /usr/local/go/src/crypto/tls/conn.go:1194 +0xe5
github.com/lib/pq.(*conn).sendStartupPacket(0xc0001356c0?, 0xc00007a720?)
        /root/thing/vendor/github.com/lib/pq/conn.go:965 +0x78
github.com/lib/pq.(*conn).startup(0xc00015c008, 0xc00007a720)
        /root/thing/vendor/github.com/lib/pq/conn.go:1170 +0x605
github.com/lib/pq.(*Connector).open(0xc0000120c0, {0x872120, 0xaae120})
        /root/thing/vendor/github.com/lib/pq/conn.go:378 +0x4aa
github.com/lib/pq.DialOpen({0x871578, 0xc00012ea10}, {0xc000152000?, 0x20?})
        /root/thing/vendor/github.com/lib/pq/conn.go:328 +0x77
github.com/lib/pq.Open(...)
        /root/thing/vendor/github.com/lib/pq/conn.go:318
main.(*connector).Connect(0x18?, {0xc00011c248?, 0x18?})
        /root/thing/config.go:49 +0xc5
github.com/lib/pq.(*NoticeHandlerConnector).Connect(0xc0000120a8, {0x872120?, 0xaae120?})
        /root/thing/vendor/github.com/lib/pq/notice.go:39 +0x31
database/sql.(*DB).conn(0xc00007e820, {0x872120, 0xaae120}, 0x1)
        /usr/local/go/src/database/sql/sql.go:1415 +0x71e
database/sql.(*DB).query(0xc00007e820, {0x872120, 0xaae120}, {0x7ffa82, 0x9}, {0x0, 0x0, 0x0}, 0x88?)
        /usr/local/go/src/database/sql/sql.go:1749 +0x65
database/sql.(*DB).QueryContext.func1(0x28?)
        /usr/local/go/src/database/sql/sql.go:1732 +0x4f
database/sql.(*DB).retry(0xc000135d38?, 0xc000135d58)
        /usr/local/go/src/database/sql/sql.go:1566 +0x42
database/sql.(*DB).QueryContext(0xc00007e820?, {0x872120?, 0xaae120?}, {0x7ffa82?, 0xc000135e10?}, {0x0?, 0x7ff612?, 0x8?})
        /usr/local/go/src/database/sql/sql.go:1731 +0xc5
database/sql.(*DB).Query(...)
        /usr/local/go/src/database/sql/sql.go:1745
main.main()
        /root/thing/main.go:35 +0x21c
exit status 2

It seems this if statement prevents tlsrsakex.Value() from being called a few lines later:

if needFIPS() {

But then sometime later, this line calls tlsrsakex.IncNonDefault():

tlsrsakex.IncNonDefault()

Unfortunately this comment explains that Value() must always be called before IncNonDefault():

// Note that Value must be called at least once before IncNonDefault.

What did you expect to see?

I expected the connection to succeed for both AWS Aurora instances.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions