ssh: initialize new channels fully before adding them to chanList
newChannel published the channel into the mux's chanList (via chanList.add) before assigning its localId, and openChannel/Accept set maxIncomingPayload only after newChannel returned. For an outbound channel, whose newChannel runs on an application goroutine, the mux loop could observe the channel through getChan before those fields were initialized, reading a zero localId or maxIncomingPayload with no happens-before relationship. Assign localId inside add while the chanList lock is held, and set maxIncomingPayload (always channelMaxPacket) in newChannel itself, so a channel returned by getChan is always fully initialized. Change-Id: Ib54a5d10dcb5c1ad8ed4dabe5d8d2790778be298 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/797061 Reviewed-by: Filippo Valsorda <filippo@golang.org> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Junyang Shao <shaojunyang@google.com>
This commit is contained in:
+13
-13
@@ -499,19 +499,20 @@ func (ch *channel) handlePacket(packet []byte) error {
|
||||
|
||||
func (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel {
|
||||
ch := &channel{
|
||||
remoteWin: window{Cond: newCond()},
|
||||
myWindow: channelWindowSize,
|
||||
pending: newBuffer(),
|
||||
extPending: newBuffer(),
|
||||
direction: direction,
|
||||
incomingRequests: make(chan *Request, chanSize),
|
||||
msg: make(chan interface{}, chanSize),
|
||||
chanType: chanType,
|
||||
extraData: extraData,
|
||||
mux: m,
|
||||
packetPool: make(map[uint32][]byte),
|
||||
remoteWin: window{Cond: newCond()},
|
||||
myWindow: channelWindowSize,
|
||||
maxIncomingPayload: channelMaxPacket,
|
||||
pending: newBuffer(),
|
||||
extPending: newBuffer(),
|
||||
direction: direction,
|
||||
incomingRequests: make(chan *Request, chanSize),
|
||||
msg: make(chan interface{}, chanSize),
|
||||
chanType: chanType,
|
||||
extraData: extraData,
|
||||
mux: m,
|
||||
packetPool: make(map[uint32][]byte),
|
||||
}
|
||||
ch.localId = m.chanList.add(ch)
|
||||
m.chanList.add(ch)
|
||||
return ch
|
||||
}
|
||||
|
||||
@@ -535,7 +536,6 @@ func (ch *channel) Accept() (Channel, <-chan *Request, error) {
|
||||
if ch.decided {
|
||||
return nil, nil, errDecidedAlready
|
||||
}
|
||||
ch.maxIncomingPayload = channelMaxPacket
|
||||
confirm := channelOpenConfirmMsg{
|
||||
PeersID: ch.remoteId,
|
||||
MyID: ch.localId,
|
||||
|
||||
Reference in New Issue
Block a user