build: do not leak context tmpdir

ParseBuildOpts downloads a URL or stdin context into a temp dir and
stores it in TmpDirToClose, but the caller only removes that when
ParseBuildOpts returns successfully. Every error return after the
download leaks it, including the authfile check reproduced in #22642
and a plain build of a git URL with no Containerfile, which leaves the
whole clone behind.

Use the same succeeded guard TempDirForURL itself uses, one level up so
it covers both tmpdir call sites and the logfile next to them.

Fixes: #22642
Signed-off-by: Tushar Verma <tusharmyself06@gmail.com>
This commit is contained in:
Tushar Verma 2026-08-14 12:02:45 +05:30
parent 9774d5338e
commit fd3937cf62
2 changed files with 29 additions and 0 deletions

View file

@ -195,6 +195,22 @@ func ParseBuildOpts(cmd *cobra.Command, args []string, buildOpts *BuildFlagsWrap
contextDir string
apiBuildOpts entities.BuildOptions
)
// The caller only cleans up TmpDirToClose and LogFileToClose when we
// return successfully, so clean them up ourselves on every error path.
succeeded := false
defer func() {
if succeeded {
return
}
if apiBuildOpts.TmpDirToClose != "" {
if err := os.RemoveAll(apiBuildOpts.TmpDirToClose); err != nil {
logrus.Errorf("Removing temporary directory %q: %v", apiBuildOpts.TmpDirToClose, err)
}
}
if apiBuildOpts.LogFileToClose != nil {
apiBuildOpts.LogFileToClose.Close()
}
}()
if len(args) > 0 {
// The context directory could be a URL. Try to handle that.
tempDir, subDir, err := buildahDefine.TempDirForURL("", "buildah", args[0])
@ -283,6 +299,7 @@ func ParseBuildOpts(cmd *cobra.Command, args []string, buildOpts *BuildFlagsWrap
apiBuildOpts.ContainerFiles = containerFiles
apiBuildOpts.Authfile = buildOpts.Authfile
succeeded = true
return &apiBuildOpts, err
}

View file

@ -34,6 +34,18 @@ EOF
run_podman rmi -f $imgname
}
# 22642: a failed flag check used to leak the downloaded context directory
@test "podman build - no tmpdir leak on early failure" {
tmpdir=$PODMAN_TMPDIR/build-tmp
mkdir -p $tmpdir
TMPDIR=$tmpdir run_podman 125 build --authfile=$PODMAN_TMPDIR/bogus-authfile - <<<"from scratch"
is "$output" ".*credential file is not accessible.*" "expected authfile error"
run ls -A $tmpdir
assert "$output" == "" "leftover files in TMPDIR after failed build"
}
@test "podman buildx - basic test" {
rand_filename=$(random_string 20)
rand_content=$(random_string 50)