Skip to content

Tempfile is leaked on the filesystem when atomic rename fails #5

@dolph

Description

@dolph

Summary

In File.Write, if os.Rename(tempName, f.Path) returns an error, log.Fatalf is called and the temp file written next to the target is never cleaned up:

tempName := filepath.Join(f.Dir(), RandomString(20))
if err := os.WriteFile(tempName, []byte(content), f.Mode()); err != nil { ... }
log.Printf("Rewriting %v", f.Path)
if err := os.Rename(tempName, f.Path); err != nil {
    log.Fatalf("Unable to atomically move temp file %v to %v: %v", ...)
}

Impact (Security/Reliability: Medium)

  • Sensitive content from rewritten files is left on disk under an attacker-predictable name (see issue Predictable temp-file names enable a symlink/race attack on file rewrites #3) with the original file's mode bits.
  • Repeated failures fill the directory with stray files (e.g. aB12...).
  • After a panic from any other log.Fatal site in a sibling goroutine, this goroutine may also leave a temp file on disk because os.Exit skips deferred cleanup.

Suggested Fix

defer os.Remove(tempName) immediately after creating the temp file (the deferred remove is a no-op if the rename succeeds because the file no longer exists at tempName). Also avoid log.Fatalf from worker goroutines — return the error so all deferreds run.

Files

  • file_handling.go:78-88 (Write)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions