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

crypto/tls: Conn#Read blocks on zero length slice argument #7775

gopherbot opened this issue Apr 14, 2014 · 8 comments

crypto/tls: Conn#Read blocks on zero length slice argument #7775

gopherbot opened this issue Apr 14, 2014 · 8 comments


Copy link

by aalevy:

What does 'go version' print?

go version devel +b3405f9c2e32 Sat Apr 12 14:56:17 2014 +1000 + linux/amd64

What steps reproduce the problem?
If possible, include a link to a program on

Example sources files at

1. Generate a certificate (self signed or otherwise)
1. Run server_net.go and connect from telnet over port 8080
2. Run server_tls.go and connect via openssl s_client -connect localhost:8080

What happened?
net.Conn#Read returns immeidately since the buffer passed in as an argument is
zero-length (and the read Syscall returns 0 on a 0 length buffer), while tls.Conn#Read
blocks until there is some data to read even though the buffer is 0-length 

What should have happened instead?
The behavior should have been the same for both -- either block for both (unreasonable
since the read syscall won't block), or don't block in the tls version.

Please provide any additional information below.
This is easy to accomplish by sticking a check for the length at the beginning of
tls.Conn#Read (and I have a patch ready for this), but not sure this is the best place
to do it.
Copy link

minux commented Apr 14, 2014

Comment 1:

Labels changed: added release-go1.3, repo-main.

Status changed to Accepted.

Copy link

Comment 2:

It's possible that people were calling tlsConn.Read(nil) for the side effect of doing
the TLS handshake and getting that error value.
Any fix (at least so late in Go 1.3) should probably preserve that property, like:
func (c *Conn) Read(b []byte) (n int, err error) {
        if err = c.Handshake(); err != nil {
        if len(b) == 0 {

Copy link

Comment 3:

... then again, the Handshake method is public anyway, so I doubt Read(nil) was used

Copy link

Comment 4 by aalevy:

Sounds reasonable to accommodate that anyway - it's the same number of
checks in the normal case and Handshake() is a noop if the connection has
been established. Should I send a change set?

Copy link

agl commented Apr 14, 2014

Comment 5:

I agree that the behaviour should be the same, but I feel that it might be too late in
1.3 to fix this. I'm assuming that this behaviour of crypto/tls has been in there since
I'll send out a patch if the decision is that this is 1.3 worthy.

Copy link

Comment 6 by aalevy:

I'd (obviously) vote for including it in 1.3, especially with Brad's
suggested change:
1. It seems very unlikely that anyone is using crypto/tls this way with
the *expectation* that it will block.
2. If the check for zero-length is after the handshake check, it doesn't
break other reasonable current uses of tls.Conn#Read like checking for
an error in the handshake.

Copy link

Comment 7:

CL mentions this issue.

Copy link

Comment 8:

This issue was closed by revision 853c99d.

Status changed to Fixed.

@rsc rsc added this to the Go1.3 milestone Apr 14, 2015
@rsc rsc removed the release-go1.3 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
FiloSottile pushed a commit to FiloSottile/go that referenced this issue Oct 12, 2018
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet

No branches or pull requests

5 participants