Skip to content

Commit 1086783

Browse files
authored
fix: separates directory creation from permission checks (#13248)
1 parent 5e560f9 commit 1086783

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

pkg/storage/chunk/client/util/util.go

+18-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"io"
7+
"io/fs"
78
"os"
89

910
ot "github.com/opentracing/opentracing-go"
@@ -67,17 +68,31 @@ func DoParallelQueries(
6768

6869
// EnsureDirectory makes sure directory is there, if not creates it if not
6970
func EnsureDirectory(dir string) error {
71+
return EnsureDirectoryWithDefaultPermissions(dir, 0o777)
72+
}
73+
74+
func EnsureDirectoryWithDefaultPermissions(dir string, mode fs.FileMode) error {
7075
info, err := os.Stat(dir)
7176
if os.IsNotExist(err) {
72-
return os.MkdirAll(dir, 0o777)
77+
return os.MkdirAll(dir, mode)
7378
} else if err == nil && !info.IsDir() {
7479
return fmt.Errorf("not a directory: %s", dir)
75-
} else if err == nil && info.Mode()&0700 != 0700 {
76-
return fmt.Errorf("insufficient permissions: %s %s", dir, info.Mode())
7780
}
7881
return err
7982
}
8083

84+
func RequirePermissions(path string, required fs.FileMode) error {
85+
info, err := os.Stat(path)
86+
if err != nil {
87+
return err
88+
}
89+
90+
if mode := info.Mode(); mode&required != required {
91+
return fmt.Errorf("insufficient permissions for path %s: required %s but found %s", path, required.String(), mode.String())
92+
}
93+
return nil
94+
}
95+
8196
// ReadCloserWithContextCancelFunc helps with cancelling the context when closing a ReadCloser.
8297
// NOTE: The consumer of ReadCloserWithContextCancelFunc should always call the Close method when it is done reading which otherwise could cause a resource leak.
8398
type ReadCloserWithContextCancelFunc struct {
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package util
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestEnsureDir(t *testing.T) {
12+
tmpDir := t.TempDir()
13+
14+
// Directory to be created by EnsureDir
15+
dirPath := filepath.Join(tmpDir, "testdir")
16+
17+
// Ensure the directory does not exist before the test
18+
if _, err := os.Stat(dirPath); !os.IsNotExist(err) {
19+
t.Fatalf("Directory already exists: %v", err)
20+
}
21+
22+
// create with default permissions
23+
require.NoError(t, EnsureDirectoryWithDefaultPermissions(dirPath, 0o640))
24+
25+
// ensure the directory passes the permission check for more restrictive permissions
26+
require.NoError(t, RequirePermissions(dirPath, 0o600))
27+
28+
// ensure the directory fails the permission check for less restrictive permissions
29+
require.Error(t, RequirePermissions(dirPath, 0o660))
30+
}

pkg/storage/stores/shipper/bloomshipper/store.go

+3
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ func NewBloomStore(
324324
if err := util.EnsureDirectory(wd); err != nil {
325325
return nil, errors.Wrapf(err, "failed to create working directory for bloom store: '%s'", wd)
326326
}
327+
if err := util.RequirePermissions(wd, 0o700); err != nil {
328+
return nil, errors.Wrapf(err, "insufficient permissions on working directory for bloom store: '%s'", wd)
329+
}
327330
}
328331

329332
for _, periodicConfig := range periodicConfigs {

0 commit comments

Comments
 (0)