Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/crypto/ssh: Channel.Read incorrectly returns write error instead of io.EOF #45912

Open
hwh33 opened this issue May 2, 2021 · 2 comments
Open

x/crypto/ssh: Channel.Read incorrectly returns write error instead of io.EOF #45912

hwh33 opened this issue May 2, 2021 · 2 comments
Labels
NeedsInvestigation
Milestone

Comments

@hwh33
Copy link

@hwh33 hwh33 commented May 2, 2021

What version of Go are you using (go version)?

go version go1.16.3 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/hwh33/Library/Caches/go-build"
GOENV="/Users/hwh33/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/hwh33/Code/golang/pkg/mod"
GONOPROXY="github.com/getlantern/*"
GONOSUMDB="github.com/getlantern/*"
GOOS="darwin"
GOPATH="/Users/hwh33/Code/golang"
GOPRIVATE="github.com/getlantern/*"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.3"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/hwh33/Code/golang/src/github.com/getlantern/ossh/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/cm/89l8fqlj6c5dc09fc9mb14dh0000gn/T/go-build3841693344=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

  • Set up a pair of ssh.Conns (client and server).
  • Open a channel between the connections.
  • Write a bunch of data to the client side of the channel.
  • Close the client connection.
  • Read from the server channel.

Example:
https://play.golang.org/p/JAd3orfmiye

(The Go Playground sometimes sees the TCP dial/listen as a deadlock. It will often work though.)

What did you expect to see?

The data from the peer, then io.EOF.

What did you see instead?

Partial data, and a write-related error. Usually write: broken pipe or write: protocol wrong type for socket

More details

This only happens if the peer has closed the ssh.Conn (or the underlying transport). I believe the bug is rooted in an incorrect assumption here. The comment indicates that the channel should be tolerant of errors adjusting the window when the peer has closed the connection. The assumption is that such errors will be exclusively io.EOF. Perhaps something has changed, but this is not currently the case.

I'm actually not sure what the fix should be here as I'm not sure what error could be expected. I don't think net.Conn.Write makes any kind of guarantees about behavior when the peer has closed the connection. Somehow though, the buffered data should be returned to the reader, followed by io.EOF.

@gopherbot gopherbot added this to the Unreleased milestone May 2, 2021
@hwh33
Copy link
Author

@hwh33 hwh33 commented May 2, 2021

It seems like there's another issue beyond the block of code I linked to above (this one). Even if you ignore the error returned by c.adjustWindow there, the Channel.Read call still sometimes returns an early io.EOF.

@cagedmantis cagedmantis added the NeedsInvestigation label May 5, 2021
@cagedmantis
Copy link
Contributor

@cagedmantis cagedmantis commented May 5, 2021

/cc @FiloSottile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation
Projects
None yet
Development

No branches or pull requests

3 participants