Skip to content

Commit 269c5f1

Browse files
committed
ssh: fix data race in dh group exchange sha256
Fixes golang/go#37607
1 parent 78000ba commit 269c5f1

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

ssh/kex.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,10 @@ func (gex *dhGEXSHA) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, e
573573
}
574574

575575
func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
576+
gex = &dhGEXSHA{
577+
hashFunc: gex.hashFunc,
578+
}
579+
576580
// Send GexRequest
577581
kexDHGexRequest := kexDHGexRequestMsg{
578582
MinBits: dhGroupExchangeMinimumBits,
@@ -678,6 +682,10 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak
678682
//
679683
// This is a minimal implementation to satisfy the automated tests.
680684
func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
685+
gex = &dhGEXSHA{
686+
hashFunc: gex.hashFunc,
687+
}
688+
681689
// Receive GexRequest
682690
packet, err := c.readPacket()
683691
if err != nil {

ssh/test/concurrent_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2012 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build !windows,!solaris,!js
6+
7+
package test
8+
9+
import (
10+
"sync"
11+
"testing"
12+
13+
"golang.org/x/crypto/ssh"
14+
)
15+
16+
// Concurrent functional tests.
17+
18+
// This test needs to be executed using the race detector in order to be effective.
19+
// #37607
20+
func TestRunConcurrent(t *testing.T) {
21+
affectedKex := []string{"diffie-hellman-group-exchange-sha1", "diffie-hellman-group-exchange-sha256"}
22+
23+
var config ssh.Config
24+
config.SetDefaults()
25+
kexOrder := config.KeyExchanges
26+
// Based on the discussion in #17230, the key exchange algorithms
27+
// diffie-hellman-group-exchange-sha1 and diffie-hellman-group-exchange-sha256
28+
// are not included in the default list of supported kex so we have to add them
29+
// here manually.
30+
kexOrder = append(kexOrder, affectedKex...)
31+
for _, kex := range affectedKex {
32+
t.Run(kex, func(t *testing.T) {
33+
wg := sync.WaitGroup{}
34+
for i := 0; i < 3; i++ {
35+
wg.Add(1)
36+
go func() {
37+
defer wg.Done()
38+
server := newServer(t)
39+
defer server.Shutdown()
40+
41+
conf := clientConfig()
42+
// Don't fail if sshd doesn't have the kex.
43+
conf.KeyExchanges = append([]string{kex}, kexOrder...)
44+
conn, err := server.TryDial(conf)
45+
if err == nil {
46+
conn.Close()
47+
} else {
48+
t.Errorf("failed for kex %q", kex)
49+
}
50+
}()
51+
}
52+
wg.Wait()
53+
})
54+
}
55+
}

0 commit comments

Comments
 (0)