-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
os: closing os.Stderr causes panic to write to arbitrary files referenced by fd 2 #15970
Comments
I don't think this can be fixed without breaking the Go 1 contract. If we had our time over again, os.Stderr would not be an os.File. |
It seems like an esoteric case, since I haven't found a prior issue logged for this. However, the behavior could be documented to provide clarity since os package has a platform-independent tone. I don't have access to a Windows right now, but "handles" may have an arbitrary numbering that make Windows unaffected. If so, os.Stderr.Close() and panic() lose their consistency between Windows and UNIX. Another question I don't know the answer to is whether this potentiates "stderr closers" to some information disclosure on the condition that a remote party can influence what becomes fd 2 and is able to trigger panics or other low-level printing routines to transmit data back to them through the fd. It seems far-fetched but worth noting. |
I agree with @davecheney; I don't think there is anything we can do here besides document it. |
I can ascertain the behavior for a few Windows client and server systems using go1.7beta1 within the next few days. |
We could open/dup a file-descriptor in place of the stdio fd's after they're closed, after they're closed, so that the fd's are not reused for any semantic purpose. |
I don't think there's a lot of value in guarding against this. What if someone legitimately wants to close os.Stderr and use fd 2 for something else? It's such a corner case that anything we do will be wrong for someone. I vote in favor of documenting this on os.Stdout/Stderr. (is os.Stdin also affected?) |
https://play.golang.org/p/jHoq_1UuSB It depends on the exact definition of affected. The fd 0 is reused, but it also seems improbable for unsuspecting users to trigger the behavior, especially compared to fd 2, which has panic writing to it. Is there a runtime component which uses a hard-coded fd 0 in the same manner that panic uses fd 2? (I couldn't find such usage in the source) |
Tested on a few Windows systems, FD reuse varies across releases. W7 and it's server counterpart wouldn't miswrite to the file, the rest did. https://play.golang.org/p/_DmUtoaBii
Possible documented workaround could be opening os.DevNull immediately after closing os.Stderr. This makes the issue non-reproducible on all tested systems so far. |
CL https://golang.org/cl/23921 mentions this issue. |
On linux/arm go1.6 and plan9/amd64 go1.7beta1 the file opened later can be the fd associated with a Conn resulting from a net.Dial. Would it be sufficient to use "file" given that a Conn can do this as well? Perhaps "underlying file descriptor 2" would clarify that this isn't exclusively an os.File.
|
Yap, I agree too -- I made similar comments in Gerrit. @as would it possible for you to post the comments on the Gerrit code review instead? That way @ianlancetaylor can address them there instead of the CL being submitted without the suggested changes, and him later on discovering your comments later on Github, if he might not have gotten the notification. |
@odeke-em |
(a) 1.7beta1 plan9/amd64
(b) 1.6.2 linux/arm
I first closed standard error, then created a new file, and lastly, called panic(). The panic was written to the created file.
The snippet doesn't produce verifiable results on the Go playground out of the box, compile locally to reproduce. The program creates the file "/tmp/test2", if the issue is reproduced then this file will contain panic output from the runtime.
https://play.golang.org/p/D2mIGkI4Oo
I expected no panic output to be written to the newly-created file.
The panic output was written to a newly-created file.
Notes:
In 1.7beta1 (and possibly below) this file contains a function that references fd 2 numerically:
$GOROOT/src/runtime/write_err.go
The godoc for os does not mention file descriptor reuse
Not tested on Windows or other operating systems/architectures.
Panics are not written if the file is opened with os.Open() or in an explicit read-only mode.
The text was updated successfully, but these errors were encountered: