When the link exits on error it currently calls Out.Close, which
will munmap the output buffer and close the file. This may be
called in concurrent phase where other goroutines may be writing
to the output buffer. The munmap can race with the write, causing
it to write to unmapped memory and crash. This CL changes it to
just close the file without unmapping. We're exiting on error
anyway so no need to unmap.
Fixes #47816.
Change-Id: I0e89aca991bdada3d017b7d5c8efc29e46308c03
Reviewed-on: https://go-review.googlesource.com/c/go/+/363357
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
*flagTmpdir = dir
ownTmpDir = true
AtExit(func() {
- ctxt.Out.Close()
os.RemoveAll(*flagTmpdir)
})
}
return nil
}
+// ErrorClose closes the output file (if any).
+// It is supposed to be called only at exit on error, so it doesn't do
+// any clean up or buffer flushing, just closes the file.
+func (out *OutBuf) ErrorClose() {
+ if out.isView {
+ panic(viewCloseError)
+ }
+ if out.f == nil {
+ return
+ }
+ out.f.Close() // best effort, ignore error
+ out.f = nil
+}
+
// isMmapped returns true if the OutBuf is mmaped.
func (out *OutBuf) isMmapped() bool {
return len(out.buf) != 0
AtExit(func() {
if nerrors > 0 {
- ctxt.Out.Close()
+ ctxt.Out.ErrorClose()
mayberemoveoutfile()
}
})