Skip to content

Commit c8d1d0d

Browse files
authored
fix: use random suffix for process temp directory instead of PID (aquasecurity#10431)
1 parent 3851371 commit c8d1d0d

2 files changed

Lines changed: 39 additions & 24 deletions

File tree

pkg/x/os/os.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package os
22

33
import (
4-
"fmt"
54
"os"
6-
"path/filepath"
75
"sync"
86
"sync/atomic"
97

@@ -19,12 +17,13 @@ var (
1917
initialized atomic.Bool
2018
)
2119

22-
// initTempDir initializes the process-specific temp directory
20+
// initTempDir initializes a unique temp directory for this process.
21+
// Uses os.MkdirTemp to generate a random suffix, avoiding collisions when
22+
// multiple processes share the same /tmp (e.g. Kubernetes emptyDir volumes
23+
// where all containers run as PID 1).
2324
func initTempDir() (string, error) {
24-
pid := os.Getpid()
25-
tempDir := filepath.Join(os.TempDir(), fmt.Sprintf("trivy-%d", pid))
26-
27-
if err := os.MkdirAll(tempDir, 0o755); err != nil {
25+
tempDir, err := os.MkdirTemp(os.TempDir(), "trivy-") //nolint: gocritic
26+
if err != nil {
2827
return "", xerrors.Errorf("failed to create temp dir: %w", err)
2928
}
3029

@@ -71,8 +70,10 @@ func TempDir() string {
7170
return tempDir
7271
}
7372

74-
// Cleanup removes the entire process-specific temp directory
75-
// Note: On Windows, directory deletion may fail if files are still open
73+
// Cleanup removes the entire process-specific temp directory.
74+
// Note: After Cleanup(), TempDir() will still return the deleted path.
75+
// Callers should not use TempDir() after Cleanup().
76+
// Note: On Windows, directory deletion may fail if files are still open.
7677
func Cleanup() error {
7778
// If temp dir was never initialized, nothing to clean up
7879
if !initialized.Load() {

pkg/x/os/os_test.go

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package os
33
import (
44
"os"
55
"path/filepath"
6-
"strconv"
76
"strings"
87
"sync"
98
"testing"
@@ -12,9 +11,10 @@ import (
1211
"github.com/stretchr/testify/require"
1312
)
1413

15-
// resetForTest resets global variables for testing
14+
// resetForTest resets all global state for testing
1615
func resetForTest() {
1716
tempDirOnce = sync.OnceValues(initTempDir)
17+
initialized.Store(false)
1818
}
1919

2020
func TestTempDir(t *testing.T) {
@@ -26,10 +26,8 @@ func TestTempDir(t *testing.T) {
2626

2727
got := TempDir()
2828

29-
// Should contain process ID
30-
pid := os.Getpid()
31-
want := filepath.Join(os.TempDir(), "trivy-"+strconv.Itoa(pid))
32-
assert.Equal(t, want, got)
29+
// Should be under system temp dir with trivy- prefix
30+
assert.True(t, strings.HasPrefix(got, filepath.Join(os.TempDir(), "trivy-")))
3331

3432
// Directory should exist
3533
_, err := os.Stat(got)
@@ -72,10 +70,8 @@ func TestCreateTemp(t *testing.T) {
7270
_, err = os.Stat(file.Name())
7371
require.NoError(t, err)
7472

75-
// File should be in our temp directory
76-
pid := os.Getpid()
77-
expectedDir := filepath.Join(os.TempDir(), "trivy-"+strconv.Itoa(pid))
78-
assert.True(t, strings.HasPrefix(file.Name(), expectedDir))
73+
// File should be under a trivy- prefixed temp directory
74+
assert.True(t, strings.HasPrefix(file.Name(), filepath.Join(os.TempDir(), "trivy-")))
7975

8076
// Test with specific dir
8177
customDir := t.TempDir()
@@ -123,9 +119,8 @@ func TestMkdirTemp(t *testing.T) {
123119
_, err = os.Stat(dir)
124120
require.NoError(t, err)
125121

126-
// Directory should be in our temp directory
127-
wantParent := filepath.Join(os.TempDir(), "trivy-"+strconv.Itoa(os.Getpid()))
128-
assert.True(t, strings.HasPrefix(dir, wantParent))
122+
// Directory should be under a trivy- prefixed temp directory
123+
assert.True(t, strings.HasPrefix(dir, filepath.Join(os.TempDir(), "trivy-")))
129124

130125
// Test with specific dir
131126
customParent := t.TempDir()
@@ -152,8 +147,8 @@ func TestCleanup(t *testing.T) {
152147
filename := file.Name()
153148
require.NoError(t, file.Close())
154149

155-
// Directory should exist
156-
dir := filepath.Join(os.TempDir(), "trivy-"+strconv.Itoa(os.Getpid()))
150+
// Get the trivy temp directory (parent of the file)
151+
dir := TempDir()
157152
_, err = os.Stat(dir)
158153
require.NoError(t, err)
159154

@@ -173,3 +168,22 @@ func TestCleanup(t *testing.T) {
173168
_, err = os.Stat(dir)
174169
assert.ErrorIs(t, err, os.ErrNotExist)
175170
}
171+
172+
func TestTempDirUniqueness(t *testing.T) {
173+
// Each call to initTempDir should produce a unique directory
174+
resetForTest()
175+
dir1 := TempDir()
176+
t.Cleanup(func() {
177+
_ = os.RemoveAll(dir1)
178+
})
179+
180+
// Reset and get another dir
181+
resetForTest()
182+
dir2 := TempDir()
183+
t.Cleanup(func() {
184+
_ = os.RemoveAll(dir2)
185+
resetForTest()
186+
})
187+
188+
assert.NotEqual(t, dir1, dir2, "two separate initializations should produce different directories")
189+
}

0 commit comments

Comments
 (0)