aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralex.schade <39062967+aschade92@users.noreply.github.com>2022-02-15 15:35:03 +0000
committerBryan Mills <bcmills@google.com>2022-02-15 21:18:59 +0000
commit08ed4882aaa50c9629a3e8636b699ceff6592ad6 (patch)
tree2601fec60f8722f71dd3371c9ac4ef5bfb8da1df
parentb5af5c0834a57751fae78fefc922f5e9f5b50941 (diff)
downloadgo-08ed4882aaa50c9629a3e8636b699ceff6592ad6.tar.gz
go-08ed4882aaa50c9629a3e8636b699ceff6592ad6.zip
cmd/go/internal/modfetch: avoid leaking a lockedfile.File in case of write errors
The go modules download command has a method called hashZip which checks the hash of a zipped directory versus an expected value, and then writes it out to a file. In the event that the write operation is not successful, we do not close the file, leading to it being leaked. This could happen if the user runs out of disk space, causing the underlying OS write command to return an error. Ultimately, this led to a panic in lockfile.OpenFile which was invoked from a finalizer garbage collecting the leaked file. The result was a stack trace that didn't show the call stack from where the write operation actually failed. Fixes #50858 Change-Id: I4a24d2ab13dc903d623bbf8252b37bb9d724b8de GitHub-Last-Rev: 354ef1d29ed9d9bb2d9bfe4b73306c550aab07fd GitHub-Pull-Request: golang/go#51058 Reviewed-on: https://go-review.googlesource.com/c/go/+/383915 Trust: Cherry Mui <cherryyz@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> Run-TryBot: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
-rw-r--r--src/cmd/go/internal/modfetch/fetch.go11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
index f5423b48ad..21d5f54688 100644
--- a/src/cmd/go/internal/modfetch/fetch.go
+++ b/src/cmd/go/internal/modfetch/fetch.go
@@ -319,7 +319,7 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e
//
// If the hash does not match go.sum (or the sumdb if enabled), hashZip returns
// an error and does not write ziphashfile.
-func hashZip(mod module.Version, zipfile, ziphashfile string) error {
+func hashZip(mod module.Version, zipfile, ziphashfile string) (err error) {
hash, err := dirhash.HashZip(zipfile, dirhash.DefaultHash)
if err != nil {
return err
@@ -331,16 +331,17 @@ func hashZip(mod module.Version, zipfile, ziphashfile string) error {
if err != nil {
return err
}
+ defer func() {
+ if closeErr := hf.Close(); err == nil && closeErr != nil {
+ err = closeErr
+ }
+ }()
if err := hf.Truncate(int64(len(hash))); err != nil {
return err
}
if _, err := hf.WriteAt([]byte(hash), 0); err != nil {
return err
}
- if err := hf.Close(); err != nil {
- return err
- }
-
return nil
}