diff --git a/cmd/podman/common/build.go b/cmd/podman/common/build.go index c54b048dfe..2e9f98830d 100644 --- a/cmd/podman/common/build.go +++ b/cmd/podman/common/build.go @@ -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 } diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 38ae11b032..a7c891afbc 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -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)