From cd65b28da051174a13ac76e54b7bb95d3051255c Mon Sep 17 00:00:00 2001 From: James Bardin Date: Sat, 4 Apr 2020 15:46:19 -0400 Subject: [PATCH] don't call os.NewFile on unknown FDs os.NewFile was called on file descriptors 3, 4, and 5 during every init, in case this process happened to be running inside panicwrap. If the runtime has already chosen one of these file descriptors to use internally, starting polling on them can cause the runtime to crash. Initialize the file descriptors lazily, only if we know that they belong to us, after Wrapped is checked. --- helper/wrappedstreams/streams.go | 30 ++++++++++---------------- helper/wrappedstreams/streams_other.go | 15 +++++++++---- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/helper/wrappedstreams/streams.go b/helper/wrappedstreams/streams.go index d3e5cf1c044e..b661ed732152 100644 --- a/helper/wrappedstreams/streams.go +++ b/helper/wrappedstreams/streams.go @@ -10,32 +10,29 @@ import ( // Stdin returns the true stdin of the process. func Stdin() *os.File { - stdin := os.Stdin - if panicwrap.Wrapped(nil) { - stdin = wrappedStdin - } - + stdin, _, _ := fds() return stdin } // Stdout returns the true stdout of the process. func Stdout() *os.File { - stdout := os.Stdout - if panicwrap.Wrapped(nil) { - stdout = wrappedStdout - } - + _, stdout, _ := fds() return stdout } // Stderr returns the true stderr of the process. func Stderr() *os.File { - stderr := os.Stderr + _, _, stderr := fds() + return stderr +} + +func fds() (stdin, stdout, stderr *os.File) { + stdin, stdout, stderr = os.Stdin, os.Stdout, os.Stderr if panicwrap.Wrapped(nil) { - stderr = wrappedStderr + initPlatform() + stdin, stdout, stderr = wrappedStdin, wrappedStdout, wrappedStderr } - - return stderr + return } // These are the wrapped standard streams. These are setup by the @@ -45,8 +42,3 @@ var ( wrappedStdout *os.File wrappedStderr *os.File ) - -func init() { - // Initialize the platform-specific code - initPlatform() -} diff --git a/helper/wrappedstreams/streams_other.go b/helper/wrappedstreams/streams_other.go index 5ffa413bc2b9..82f1e150ca1d 100644 --- a/helper/wrappedstreams/streams_other.go +++ b/helper/wrappedstreams/streams_other.go @@ -4,11 +4,18 @@ package wrappedstreams import ( "os" + "sync" ) +var initOnce sync.Once + func initPlatform() { - // The standard streams are passed in via extra file descriptors. - wrappedStdin = os.NewFile(uintptr(3), "stdin") - wrappedStdout = os.NewFile(uintptr(4), "stdout") - wrappedStderr = os.NewFile(uintptr(5), "stderr") + // These must be initialized lazily, once it's been determined that this is + // a wrapped process. + initOnce.Do(func() { + // The standard streams are passed in via extra file descriptors. + wrappedStdin = os.NewFile(uintptr(3), "stdin") + wrappedStdout = os.NewFile(uintptr(4), "stdout") + wrappedStderr = os.NewFile(uintptr(5), "stderr") + }) }