==================
WARNING: DATA RACE
Write at 0x00c4201ba208 by goroutine 32:
os/exec.(*Cmd).Wait()
/usr/local/Cellar/go/1.9.2/libexec/src/os/exec/exec.go:450 +0x163
github.com/resin-io/sshproxy.(*Server).handleRequests.func1.1()
/Users/wrboyce/Dev/resin/.go/src/github.com/resin-io/sshproxy/sshproxy.go:249 +0x4c
Previous read at 0x00c4201ba208 by goroutine 30:
github.com/resin-io/sshproxy.(*Server).handleRequests.func1()
/Users/wrboyce/Dev/resin/.go/src/github.com/resin-io/sshproxy/sshproxy.go:269 +0x29b
Goroutine 32 (running) created at:
github.com/resin-io/sshproxy.(*Server).handleRequests.func1()
/Users/wrboyce/Dev/resin/.go/src/github.com/resin-io/sshproxy/sshproxy.go:248 +0x8a
Goroutine 30 (finished) created at:
github.com/resin-io/sshproxy.(*Server).handleRequests()
/Users/wrboyce/Dev/resin/.go/src/github.com/resin-io/sshproxy/sshproxy.go:246 +0xb0d
github.com/resin-io/sshproxy.(*Server).handleChannels.func1()
/Users/wrboyce/Dev/resin/.go/src/github.com/resin-io/sshproxy/sshproxy.go:176 +0x8a
==================
Reproducible using:
package sshproxy_test
import (
"net"
"time"
"testing"
"golang.org/x/crypto/ssh"
"github.com/resin-io/sshproxy"
)
func TestRace(t *testing.T) {
server, err := sshproxy.New("/tmp", "/bin/bash", false, nil, nil, nil)
if err != nil {
t.Errorf("error calling sshproxy.New :( %q", err)
}
port := "12345"
go server.Listen(port)
config := &ssh.ClientConfig{
User: "user",
Auth: []ssh.AuthMethod{
ssh.Password("password"),
},
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
}
for i := 0; i < 10; i++ {
client, err := ssh.Dial("tcp", "localhost:12345", config)
if err != nil {
t.Errorf("Cannot connect to server :( %q", err)
}
session, err := client.NewSession()
if err != nil {
t.Errorf("Cannot create session :( %q", err)
}
time.Sleep(time.Second)
_, err = session.SendRequest("exec", false, []byte{0, 0, 0, 4, 't', 'e', 's', 't'})
if err != nil {
t.Errorf("Cannot send exec request :( %q", err)
}
time.Sleep(time.Duration(i * 100) * time.Millisecond)
client.Close()
}
}
Reproducible using: