diff --git a/CHANGELOG.md b/CHANGELOG.md index f5a405c1291..79beb00fbfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ * [CHANGE] TraceQL: Add range condition for byte predicates [#4198](https://github.com/grafana/tempo/pull/4198) (@ie-pham) * [CHANGE] Return 422 for TRACE_TOO_LARGE queries [#4160](https://github.com/grafana/tempo/pull/4160) (@zalegrala) * [CHANGE] Upgrade OTEL sdk to reduce allocs [#4243](https://github.com/grafana/tempo/pull/4243) (@joe-elliott) +* [CHANGE] Tighten file permissions [#4251](https://github.com/grafana/tempo/pull/4251) (@zalegrala) * [FEATURE] Discarded span logging `log_discarded_spans` [#3957](https://github.com/grafana/tempo/issues/3957) (@dastrobu) * [FEATURE] TraceQL support for instrumentation scope [#3967](https://github.com/grafana/tempo/pull/3967) (@ie-pham) * [ENHANCEMENT] TraceQL: Attribute iterators collect matched array values [#3867](https://github.com/grafana/tempo/pull/3867) (@electron0zero, @stoewer) diff --git a/cmd/tempo-cli/cmd-gen-bloom.go b/cmd/tempo-cli/cmd-gen-bloom.go index e3ccf553c93..fee0a178c26 100644 --- a/cmd/tempo-cli/cmd-gen-bloom.go +++ b/cmd/tempo-cli/cmd-gen-bloom.go @@ -29,7 +29,7 @@ type forEachRecord func(id common.ID) error func ReplayBlockAndDoForEachRecord(meta *backend.BlockMeta, filepath string, forEach forEachRecord) error { // replay file to extract records - f, err := os.OpenFile(filepath, os.O_RDONLY, 0o644) + f, err := os.OpenFile(filepath, os.O_RDONLY, 0o600) if err != nil { return err } diff --git a/cmd/tempo-cli/cmd-gen-index.go b/cmd/tempo-cli/cmd-gen-index.go index 279937ac7b1..e4ddd928973 100644 --- a/cmd/tempo-cli/cmd-gen-index.go +++ b/cmd/tempo-cli/cmd-gen-index.go @@ -24,7 +24,7 @@ type indexCmd struct { func ReplayBlockAndGetRecords(meta *backend.BlockMeta, filepath string) ([]v2.Record, error, error) { var replayError error // replay file to extract records - f, err := os.OpenFile(filepath, os.O_RDONLY, 0o644) + f, err := os.OpenFile(filepath, os.O_RDONLY, 0o600) if err != nil { return nil, nil, err } @@ -152,7 +152,7 @@ func (cmd *indexCmd) Run(ctx *globalOptions) error { // get index file with records indexFilePath := cmd.backendOptions.Bucket + cmd.TenantID + "/" + cmd.BlockID + "/" + indexFilename - indexFile, err := os.OpenFile(indexFilePath, os.O_RDONLY, 0o644) + indexFile, err := os.OpenFile(indexFilePath, os.O_RDONLY, 0o600) if err != nil { fmt.Println("error opening index file") return err @@ -166,7 +166,7 @@ func (cmd *indexCmd) Run(ctx *globalOptions) error { // data reader dataFilePath := cmd.backendOptions.Bucket + cmd.TenantID + "/" + cmd.BlockID + "/" + dataFilename - dataFile, err := os.OpenFile(dataFilePath, os.O_RDONLY, 0o644) + dataFile, err := os.OpenFile(dataFilePath, os.O_RDONLY, 0o600) if err != nil { fmt.Println("error opening data file") return err diff --git a/cmd/tempo-cli/cmd-migrate-overrides-config.go b/cmd/tempo-cli/cmd-migrate-overrides-config.go index 6042f2b82c7..30eec739fb7 100644 --- a/cmd/tempo-cli/cmd-migrate-overrides-config.go +++ b/cmd/tempo-cli/cmd-migrate-overrides-config.go @@ -68,7 +68,7 @@ func (cmd *migrateOverridesConfigCmd) Run(*globalOptions) error { } if cmd.ConfigDest != "" { - if err := os.WriteFile(cmd.ConfigDest, configBytes, 0o644); err != nil { + if err := os.WriteFile(cmd.ConfigDest, configBytes, 0o600); err != nil { return fmt.Errorf("failed to write config file: %w", err) } } else { @@ -90,7 +90,7 @@ func (cmd *migrateOverridesConfigCmd) Run(*globalOptions) error { } if cmd.OverridesDest != "" { - if err := os.WriteFile(cmd.OverridesDest, overridesBytes, 0o644); err != nil { + if err := os.WriteFile(cmd.OverridesDest, overridesBytes, 0o600); err != nil { return fmt.Errorf("failed to write overrides file: %w", err) } } else { diff --git a/cmd/tempo/Dockerfile b/cmd/tempo/Dockerfile index b2b412372ab..8e77d926244 100644 --- a/cmd/tempo/Dockerfile +++ b/cmd/tempo/Dockerfile @@ -6,7 +6,7 @@ COPY bin/linux/tempo-${TARGETARCH} /tempo RUN addgroup -g 10001 -S tempo && \ adduser -u 10001 -S tempo -G tempo -RUN mkdir -p /var/tempo && \ +RUN mkdir -p /var/tempo -m 0700 && \ chown -R tempo:tempo /var/tempo USER 10001:10001 diff --git a/integration/e2e/ca/ca.go b/integration/e2e/ca/ca.go index 81f1bd8a8ec..9f752c93208 100644 --- a/integration/e2e/ca/ca.go +++ b/integration/e2e/ca/ca.go @@ -178,7 +178,7 @@ func (ca *ca) writeCACertificate(path string) error { return err } - return writeExclusivePEMFile(path, "CERTIFICATE", 0o644, derBytes) + return writeExclusivePEMFile(path, "CERTIFICATE", 0o600, derBytes) } func (ca *ca) writeCertificate(template *x509.Certificate, certPath string, keyPath string) error { @@ -208,5 +208,5 @@ func (ca *ca) writeCertificate(template *x509.Certificate, certPath string, keyP return err } - return writeExclusivePEMFile(certPath, "CERTIFICATE", 0o644, derBytes) + return writeExclusivePEMFile(certPath, "CERTIFICATE", 0o600, derBytes) } diff --git a/integration/util/util.go b/integration/util/util.go index 6ddd7dc14ab..cd3248b21ec 100644 --- a/integration/util/util.go +++ b/integration/util/util.go @@ -311,6 +311,10 @@ func CopyTemplateToSharedDir(s *e2e.Scenario, src, dst string, data any) (string func writeFileToSharedDir(s *e2e.Scenario, dst string, content []byte) (string, error) { dst = filepath.Join(s.SharedDir(), dst) + // NOTE: since the integration tests are setup outside of the container + // before container execution, the permissions within the container must be + // able to read the configuration. + // Ensure the entire path of directories exists err := os.MkdirAll(filepath.Dir(dst), os.ModePerm) if err != nil { diff --git a/modules/generator/generator.go b/modules/generator/generator.go index 1b76317aacc..2b0078c03f8 100644 --- a/modules/generator/generator.go +++ b/modules/generator/generator.go @@ -73,7 +73,7 @@ func New(cfg *Config, overrides metricsGeneratorOverrides, reg prometheus.Regist return nil, ErrUnconfigured } - err := os.MkdirAll(cfg.Storage.Path, os.ModePerm) + err := os.MkdirAll(cfg.Storage.Path, 0o700) if err != nil { return nil, fmt.Errorf("failed to mkdir on %s: %w", cfg.Storage.Path, err) } diff --git a/modules/generator/generator_test.go b/modules/generator/generator_test.go index dcfafaca163..db05dfb5ef8 100644 --- a/modules/generator/generator_test.go +++ b/modules/generator/generator_test.go @@ -53,7 +53,7 @@ overrides: collection_interval: 1s processors: - %s -`, user1, spanmetrics.Name)), os.ModePerm)) +`, user1, spanmetrics.Name)), 0o700)) o, err := overrides.NewOverrides(overridesConfig, nil, prometheus.NewRegistry()) require.NoError(t, err) @@ -92,7 +92,7 @@ overrides: collection_interval: 1s processors: - %s -`, user1, spanmetrics.Count.String())), os.ModePerm)) +`, user1, spanmetrics.Count.String())), 0o700)) time.Sleep(15 * time.Second) // Wait for overrides to be applied. Reload is hardcoded to 10s :( // Only Count should be enabled for user1 diff --git a/modules/generator/storage/instance.go b/modules/generator/storage/instance.go index d07e7d418ff..f05a4d4dc2e 100644 --- a/modules/generator/storage/instance.go +++ b/modules/generator/storage/instance.go @@ -74,7 +74,7 @@ func New(cfg *Config, o Overrides, tenant string, reg prometheus.Registerer, log // Create WAL directory with necessary permissions // This creates both // and //wal/. If we don't create the wal // subdirectory remote storage logs a scary error. - err = os.MkdirAll(filepath.Join(walDir, "wal"), 0o755) + err = os.MkdirAll(filepath.Join(walDir, "wal"), 0o700) if err != nil { return nil, fmt.Errorf("could not create directory for metrics WAL: %w", err) } diff --git a/modules/overrides/runtime_config_overrides_test.go b/modules/overrides/runtime_config_overrides_test.go index 72ef2d52d16..18e2a62b731 100644 --- a/modules/overrides/runtime_config_overrides_test.go +++ b/modules/overrides/runtime_config_overrides_test.go @@ -219,7 +219,7 @@ func TestRuntimeConfigOverrides(t *testing.T) { buff, err := yaml.Marshal(legacyOverrides) require.NoError(t, err) - err = os.WriteFile(overridesFile, buff, os.ModePerm) + err = os.WriteFile(overridesFile, buff, 0o700) require.NoError(t, err) cfg.PerTenantOverrideConfig = overridesFile @@ -578,7 +578,7 @@ overrides: overridesFile := filepath.Join(t.TempDir(), "Overrides.yaml") - require.NoError(t, os.WriteFile(overridesFile, []byte(perTenantOverrides), os.ModePerm)) + require.NoError(t, os.WriteFile(overridesFile, []byte(perTenantOverrides), 0o700)) cfg.PerTenantOverrideConfig = overridesFile cfg.PerTenantOverridePeriod = model.Duration(time.Hour) @@ -606,7 +606,7 @@ func createAndInitializeRuntimeOverridesManager(t *testing.T, defaultLimits Over if perTenantOverrides != nil { overridesFile := filepath.Join(t.TempDir(), "Overrides.yaml") - err := os.WriteFile(overridesFile, perTenantOverrides, os.ModePerm) + err := os.WriteFile(overridesFile, perTenantOverrides, 0o700) require.NoError(t, err) cfg.PerTenantOverrideConfig = overridesFile diff --git a/modules/overrides/user_configurable_overrides_test.go b/modules/overrides/user_configurable_overrides_test.go index 48db5aaa292..b583f105b5d 100644 --- a/modules/overrides/user_configurable_overrides_test.go +++ b/modules/overrides/user_configurable_overrides_test.go @@ -296,7 +296,7 @@ func localUserConfigOverrides(t *testing.T, baseLimits Overrides, perTenantOverr if perTenantOverrides != nil { overridesFile := filepath.Join(t.TempDir(), "Overrides.yaml") - err := os.WriteFile(overridesFile, perTenantOverrides, os.ModePerm) + err := os.WriteFile(overridesFile, perTenantOverrides, 0o700) require.NoError(t, err) baseCfg.PerTenantOverrideConfig = overridesFile diff --git a/modules/overrides/userconfigurable/client/client.go b/modules/overrides/userconfigurable/client/client.go index c39b766b7f3..b0d302ec082 100644 --- a/modules/overrides/userconfigurable/client/client.go +++ b/modules/overrides/userconfigurable/client/client.go @@ -120,7 +120,7 @@ func initBackend(cfg *Config) (rw backend.VersionedReaderWriter, err error) { return nil, err } // Create overrides directory with necessary permissions - err = os.MkdirAll(path.Join(cfg.Local.Path, OverridesKeyPath), os.ModePerm) + err = os.MkdirAll(path.Join(cfg.Local.Path, OverridesKeyPath), 0o700) if err != nil { return nil, err } diff --git a/tempodb/backend/local/local.go b/tempodb/backend/local/local.go index b75edd585f1..3c738ff8cfc 100644 --- a/tempodb/backend/local/local.go +++ b/tempodb/backend/local/local.go @@ -30,7 +30,7 @@ var ( ) func NewBackend(cfg *Config) (*Backend, error) { - err := os.MkdirAll(cfg.Path, os.ModePerm) + err := os.MkdirAll(cfg.Path, 0o700) if err != nil { return nil, err } @@ -54,7 +54,7 @@ func (rw *Backend) Write(ctx context.Context, name string, keypath backend.KeyPa } blockFolder := rw.rootPath(keypath) - err := os.MkdirAll(blockFolder, os.ModePerm) + err := os.MkdirAll(blockFolder, 0o700) if err != nil { return err } @@ -87,7 +87,7 @@ func (rw *Backend) Append(ctx context.Context, name string, keypath backend.KeyP var dst *os.File if tracker == nil { blockFolder := rw.rootPath(keypath) - err := os.MkdirAll(blockFolder, os.ModePerm) + err := os.MkdirAll(blockFolder, 0o700) if err != nil { return nil, err } @@ -234,7 +234,7 @@ func (rw *Backend) Read(ctx context.Context, name string, keypath backend.KeyPat filename := rw.objectFileName(keypath, name) - f, err := os.OpenFile(filename, os.O_RDONLY, 0o644) + f, err := os.OpenFile(filename, os.O_RDONLY, 0o600) if err != nil { return nil, -1, readError(err) } @@ -262,7 +262,7 @@ func (rw *Backend) ReadRange(ctx context.Context, name string, keypath backend.K filename := rw.objectFileName(keypath, name) - f, err := os.OpenFile(filename, os.O_RDONLY, 0o644) + f, err := os.OpenFile(filename, os.O_RDONLY, 0o600) if err != nil { return readError(err) } diff --git a/tempodb/encoding/v2/wal_block.go b/tempodb/encoding/v2/wal_block.go index e128883be79..7f4f8aca7b3 100644 --- a/tempodb/encoding/v2/wal_block.go +++ b/tempodb/encoding/v2/wal_block.go @@ -62,7 +62,7 @@ func createWALBlock(meta *backend.BlockMeta, filepath, dataEncoding string, inge name := h.fullFilename() - f, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644) + f, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600) if err != nil { return nil, err } @@ -350,7 +350,7 @@ func (a *walBlock) file() (*os.File, error) { if a.readFile == nil { name := a.fullFilename() - a.readFile, err = os.OpenFile(name, os.O_RDONLY, 0o644) + a.readFile, err = os.OpenFile(name, os.O_RDONLY, 0o600) } }) diff --git a/tempodb/encoding/vparquet2/schema_test.go b/tempodb/encoding/vparquet2/schema_test.go index 9ddb4925f3d..0ceb2cf3141 100644 --- a/tempodb/encoding/vparquet2/schema_test.go +++ b/tempodb/encoding/vparquet2/schema_test.go @@ -394,7 +394,7 @@ func TestParquetRowSizeEstimate(t *testing.T) { } func estimateRowSize(t *testing.T, name string) { - f, err := os.OpenFile(name, os.O_RDONLY, 0o644) + f, err := os.OpenFile(name, os.O_RDONLY, 0o600) require.NoError(t, err) fi, err := f.Stat() diff --git a/tempodb/encoding/vparquet2/wal_block.go b/tempodb/encoding/vparquet2/wal_block.go index 583e312f13b..6b7f451b638 100644 --- a/tempodb/encoding/vparquet2/wal_block.go +++ b/tempodb/encoding/vparquet2/wal_block.go @@ -166,7 +166,7 @@ func createWALBlock(meta *backend.BlockMeta, filepath, dataEncoding string, inge } // build folder - err := os.MkdirAll(b.walPath(), os.ModePerm) + err := os.MkdirAll(b.walPath(), 0o700) if err != nil { return nil, err } @@ -216,7 +216,7 @@ func (w *walBlockFlush) file(ctx context.Context) (*pageFile, error) { return nil, err } - file, err := os.OpenFile(w.path, os.O_RDONLY, 0o644) + file, err := os.OpenFile(w.path, os.O_RDONLY, 0o600) if err != nil { return nil, fmt.Errorf("error opening file: %w", err) } @@ -376,7 +376,7 @@ func (b *walBlock) openWriter() (err error) { nextFile := len(b.flushed) + 1 filename := b.filepathOf(nextFile) - b.file, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o644) + b.file, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o600) if err != nil { return fmt.Errorf("error opening file: %w", err) } diff --git a/tempodb/encoding/vparquet3/schema_test.go b/tempodb/encoding/vparquet3/schema_test.go index 18aa8d4dcf0..768366e6bee 100644 --- a/tempodb/encoding/vparquet3/schema_test.go +++ b/tempodb/encoding/vparquet3/schema_test.go @@ -441,7 +441,7 @@ func TestParquetRowSizeEstimate(t *testing.T) { } func estimateRowSize(t *testing.T, name string) { - f, err := os.OpenFile(name, os.O_RDONLY, 0o644) + f, err := os.OpenFile(name, os.O_RDONLY, 0o600) require.NoError(t, err) fi, err := f.Stat() diff --git a/tempodb/encoding/vparquet3/wal_block.go b/tempodb/encoding/vparquet3/wal_block.go index d58d1ff6c52..7d9e639e6e3 100644 --- a/tempodb/encoding/vparquet3/wal_block.go +++ b/tempodb/encoding/vparquet3/wal_block.go @@ -164,7 +164,7 @@ func createWALBlock(meta *backend.BlockMeta, filepath, dataEncoding string, inge } // build folder - err := os.MkdirAll(b.walPath(), os.ModePerm) + err := os.MkdirAll(b.walPath(), 0o700) if err != nil { return nil, err } @@ -214,7 +214,7 @@ func (w *walBlockFlush) file(ctx context.Context) (*pageFile, error) { return nil, err } - file, err := os.OpenFile(w.path, os.O_RDONLY, 0o644) + file, err := os.OpenFile(w.path, os.O_RDONLY, 0o600) if err != nil { return nil, fmt.Errorf("error opening file: %w", err) } @@ -387,7 +387,7 @@ func (b *walBlock) openWriter() (err error) { nextFile := len(b.flushed) + 1 filename := b.filepathOf(nextFile) - b.file, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o644) + b.file, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o600) if err != nil { return fmt.Errorf("error opening file: %w", err) } diff --git a/tempodb/encoding/vparquet4/schema_test.go b/tempodb/encoding/vparquet4/schema_test.go index 81233d929dd..9681a569232 100644 --- a/tempodb/encoding/vparquet4/schema_test.go +++ b/tempodb/encoding/vparquet4/schema_test.go @@ -847,7 +847,7 @@ func TestParquetRowSizeEstimate(t *testing.T) { } func estimateRowSize(t *testing.T, name string) { - f, err := os.OpenFile(name, os.O_RDONLY, 0o644) + f, err := os.OpenFile(name, os.O_RDONLY, 0o600) require.NoError(t, err) fi, err := f.Stat() diff --git a/tempodb/encoding/vparquet4/wal_block.go b/tempodb/encoding/vparquet4/wal_block.go index dcb476bd856..2fc8fcb2934 100644 --- a/tempodb/encoding/vparquet4/wal_block.go +++ b/tempodb/encoding/vparquet4/wal_block.go @@ -164,7 +164,7 @@ func createWALBlock(meta *backend.BlockMeta, filepath, dataEncoding string, inge } // build folder - err := os.MkdirAll(b.walPath(), os.ModePerm) + err := os.MkdirAll(b.walPath(), 0o700) if err != nil { return nil, err } @@ -214,7 +214,7 @@ func (w *walBlockFlush) file(ctx context.Context) (*pageFile, error) { return nil, err } - file, err := os.OpenFile(w.path, os.O_RDONLY, 0o644) + file, err := os.OpenFile(w.path, os.O_RDONLY, 0o600) if err != nil { return nil, fmt.Errorf("error opening file: %w", err) } @@ -388,7 +388,7 @@ func (b *walBlock) openWriter() (err error) { nextFile := len(b.flushed) + 1 filename := b.filepathOf(nextFile) - b.file, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o644) + b.file, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o600) if err != nil { return fmt.Errorf("error opening file: %w", err) } diff --git a/tempodb/wal/wal.go b/tempodb/wal/wal.go index d18a535a2d3..055bbb61f5d 100644 --- a/tempodb/wal/wal.go +++ b/tempodb/wal/wal.go @@ -46,14 +46,14 @@ func New(c *Config) (*WAL, error) { } // make folder - err := os.MkdirAll(c.Filepath, os.ModePerm) + err := os.MkdirAll(c.Filepath, 0o700) if err != nil { return nil, err } // Setup local backend in /blocks/ blocksFolderPath := filepath.Join(c.Filepath, blocksDir) - err = os.MkdirAll(blocksFolderPath, os.ModePerm) + err = os.MkdirAll(blocksFolderPath, 0o700) if err != nil { return nil, err } diff --git a/tempodb/wal/wal_test.go b/tempodb/wal/wal_test.go index 705c96d7e81..51d1b45f341 100644 --- a/tempodb/wal/wal_test.go +++ b/tempodb/wal/wal_test.go @@ -336,15 +336,15 @@ func TestInvalidFilesAndFoldersAreHandled(t *testing.T) { } // create unparseable filename - err = os.WriteFile(filepath.Join(tempDir, "fe0b83eb-a86b-4b6c-9a74-dc272cd5700e:tenant:v2:notanencoding"), []byte{}, 0o644) + err = os.WriteFile(filepath.Join(tempDir, "fe0b83eb-a86b-4b6c-9a74-dc272cd5700e:tenant:v2:notanencoding"), []byte{}, 0o600) require.NoError(t, err) // create empty block - err = os.WriteFile(filepath.Join(tempDir, "fe0b83eb-a86b-4b6c-9a74-dc272cd5700e:blerg:v2:gzip"), []byte{}, 0o644) + err = os.WriteFile(filepath.Join(tempDir, "fe0b83eb-a86b-4b6c-9a74-dc272cd5700e:blerg:v2:gzip"), []byte{}, 0o600) require.NoError(t, err) // create unparseable block - require.NoError(t, os.MkdirAll(filepath.Join(tempDir, "fe0b83eb-a86b-4b6c-9a74-dc272cd5700e+tenant+vOther"), os.ModePerm)) + require.NoError(t, os.MkdirAll(filepath.Join(tempDir, "fe0b83eb-a86b-4b6c-9a74-dc272cd5700e+tenant+vOther"), 0o700)) blocks, err := wal.RescanBlocks(0, log.NewNopLogger()) require.NoError(t, err, "unexpected error getting blocks")