From 5c7982d1f7c6a5fed2ec0c835a81f6cafed510f4 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Fri, 19 Jun 2026 15:22:42 +0000 Subject: [PATCH] fix(downloader): resolve gosec G122 in CleanupStalePartialFiles CI's code-scanning (gosec) flagged G122 (symlink TOCTOU) for the os.Remove call inside the filepath.WalkDir callback. Collect the stale paths during the walk and delete them afterwards instead of mutating the tree from inside the callback. Behavior is unchanged; the existing specs still pass. Signed-off-by: Ettore Di Giacinto Assisted-by: Claude:claude-opus-4-8 [Claude Code] --- pkg/downloader/partial.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/pkg/downloader/partial.go b/pkg/downloader/partial.go index 7ad52f171..f816bb09f 100644 --- a/pkg/downloader/partial.go +++ b/pkg/downloader/partial.go @@ -33,7 +33,11 @@ func CleanupStalePartialFiles(root string, olderThan time.Duration) (int, error) } cutoff := time.Now().Add(-olderThan) - removed := 0 + + // Collect candidates during the walk and delete them afterwards rather than + // mutating the tree from inside the WalkDir callback (avoids the symlink + // TOCTOU class flagged by gosec G122, and never removes an entry mid-walk). + var stale []string err := filepath.WalkDir(root, func(path string, d fs.DirEntry, walkErr error) error { if walkErr != nil { return nil // skip unreadable subtree, keep going @@ -45,13 +49,21 @@ func CleanupStalePartialFiles(root string, olderThan time.Duration) (int, error) if err != nil || info.ModTime().After(cutoff) { return nil } + stale = append(stale, path) + return nil + }) + if err != nil { + return 0, err + } + + removed := 0 + for _, path := range stale { if err := os.Remove(path); err != nil { xlog.Warn("failed to remove stale partial download", "file", path, "error", err) - return nil + continue } removed++ xlog.Info("removed stale partial download", "file", path) - return nil - }) - return removed, err + } + return removed, nil }