Commit d75f4ac2 authored by Levin Zimmermann's avatar Levin Zimmermann Committed by Kirill Smelkov

go/neo/neonet: DialLink: Fix SIGSEGV in case client handshake fails

In case the last 'handshakeClient' call returns an error, 'DialLink'
returns 'link = nil, err = nil'. Callers of 'DialLink' then don't
recognize that 'link' is 'nil', as it's the convention to only check if
'err' is 'nil', which leads to a 'segmentation violation' as soon as
subsequent code tries to access fields of 'link':

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

goroutine 5 [running]:
lab.nexedi.com/kirr/neo/go/neo/neonet.(*NodeLink).NewConn(0x0)
	/srv/slapgrid/slappart82/srv/runner/instance/slappart6/software_release/parts/wendelin.core/wcfs/neo/go/neo/neonet/connection.go:404 +0x4e
lab.nexedi.com/kirr/neo/go/neo/xneo.Dial.func1()
	/srv/slapgrid/slappart82/srv/runner/instance/slappart6/software_release/parts/wendelin.core/wcfs/neo/go/neo/xneo/connect.go:138 +0x52
lab.nexedi.com/kirr/neo/go/internal/xio.WithCloseOnErrCancel.func2()
	/srv/slapgrid/slappart82/srv/runner/instance/slappart6/software_release/parts/wendelin.core/wcfs/neo/go/internal/xio/xio.go:114 +0x6a
created by lab.nexedi.com/kirr/neo/go/internal/xio.WithCloseOnErrCancel in goroutine 21
	/srv/slapgrid/slappart82/srv/runner/instance/slappart6/software_release/parts/wendelin.core/wcfs/neo/go/internal/xio/xio.go:109 +0x1ad
```

This patch fixes this issue so that now 'err' and 'link' are never both
'nil' again.

/reviewed-by @kirr
/reviewed-on kirr/neo!10
parent 03db1d8a
// Copyright (C) 2016-2023 Nexedi SA and Contributors.
// Copyright (C) 2016-2024 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -314,9 +314,10 @@ func init() {
// DialLink connects to address on given network, performs NEO protocol
// handshake and wraps the connection as NodeLink.
func DialLink(ctx context.Context, net xnet.Networker, addr string) (link *NodeLink, err error) {
func DialLink(ctx context.Context, xnet xnet.Networker, addr string) (link *NodeLink, err error) {
for _, enc := range dialEncTryOrder {
peerConn, err := net.Dial(ctx, addr)
var peerConn net.Conn
peerConn, err = xnet.Dial(ctx, addr)
if err != nil {
return nil, err
}
......
......@@ -228,7 +228,6 @@ func _TestHandshake(t *T) {
// TestDialLink_AllHandshakeErr verifies that DialLink returns an error if all handshake attempts fail.
func TestDialLink_AllHandshakeErr(t *testing.T) {
t.Skip("xfail")
X := exc.Raiseif
ctx, cancel := context.WithCancel(context.Background())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment