From: Cherry Mui Date: Thu, 11 Nov 2021 21:51:08 +0000 (-0500) Subject: cmd/link: don't unmap output file at error exit X-Git-Tag: go1.18beta1~364 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e9f0381a807d1797e0b5969a29f4a3666a73c9e3;p=gostls13.git cmd/link: don't unmap output file at error exit 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 Run-TryBot: Cherry Mui TryBot-Result: Go Bot Reviewed-by: Than McIntosh --- diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 91665b2ebb..9e13db7b71 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -1103,7 +1103,6 @@ func hostlinksetup(ctxt *Link) { *flagTmpdir = dir ownTmpDir = true AtExit(func() { - ctxt.Out.Close() os.RemoveAll(*flagTmpdir) }) } diff --git a/src/cmd/link/internal/ld/outbuf.go b/src/cmd/link/internal/ld/outbuf.go index 9d5e8854fe..1d21dce9c5 100644 --- a/src/cmd/link/internal/ld/outbuf.go +++ b/src/cmd/link/internal/ld/outbuf.go @@ -131,6 +131,20 @@ func (out *OutBuf) Close() error { 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 diff --git a/src/cmd/link/internal/ld/sym.go b/src/cmd/link/internal/ld/sym.go index 72639962e2..d51a59ef46 100644 --- a/src/cmd/link/internal/ld/sym.go +++ b/src/cmd/link/internal/ld/sym.go @@ -60,7 +60,7 @@ func linknew(arch *sys.Arch) *Link { AtExit(func() { if nerrors > 0 { - ctxt.Out.Close() + ctxt.Out.ErrorClose() mayberemoveoutfile() } })