chore(deps): bump google.golang.org/grpc from 1.78.0 to 1.79.3 in the go_modules group across 1 directory (#36)

* chore(deps): bump google.golang.org/grpc

Bumps the go_modules group with 1 update in the / directory: [google.golang.org/grpc](https://github.com/grpc/grpc-go).


Updates `google.golang.org/grpc` from 1.78.0 to 1.79.3
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.78.0...v1.79.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.79.3
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <[email protected]>

* Resolve merge conflicts and harden storage paths

Co-authored-by: lukaszraczylo <[email protected]>

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: lukaszraczylo <[email protected]>
This commit is contained in:
dependabot[bot]
2026-09-03 11:16:29 +01:00
committed by GitHub
co-authored by dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> copilot-swe-agent[bot] <198982749+[email protected]> lukaszraczylo
parent 7fb596aafd
commit edeb2eca0c
4 changed files with 85 additions and 25 deletions
+1 -1
View File
@@ -126,6 +126,6 @@ require (
go.yaml.in/yaml/v3 v3.0.5 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/sys v0.47.0 // indirect golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.41.0 // indirect golang.org/x/text v0.41.0 // indirect
google.golang.org/grpc v1.78.0 // indirect google.golang.org/grpc v1.79.3 // indirect
google.golang.org/protobuf v1.36.12 // indirect google.golang.org/protobuf v1.36.12 // indirect
) )
+2 -2
View File
@@ -298,8 +298,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk= google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+54 -21
View File
@@ -91,17 +91,30 @@ func (fs *FilesystemStorage) Put(ctx context.Context, key string, data io.Reader
metrics.RecordStorageOperation("filesystem", "put", "error") metrics.RecordStorageOperation("filesystem", "put", "error")
return err return err
} }
dir := filepath.Dir(path) relPath, err := fs.relativeToBase(path)
if err != nil {
metrics.RecordStorageOperation("filesystem", "put", "error")
return err
}
dir := filepath.Dir(relPath)
root, err := os.OpenRoot(fs.basePath)
if err != nil {
metrics.RecordStorageOperation("filesystem", "put", "error")
return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to open storage root")
}
defer root.Close() // #nosec G307 -- Best-effort cleanup of opened storage root
// Create directory // Create directory
if mkErr := os.MkdirAll(dir, 0750); mkErr != nil { if dir != "." {
metrics.RecordStorageOperation("filesystem", "put", "error") if mkErr := root.MkdirAll(dir, 0750); mkErr != nil {
return errors.Wrap(mkErr, errors.ErrCodeStorageFailure, "failed to create directory") metrics.RecordStorageOperation("filesystem", "put", "error")
return errors.Wrap(mkErr, errors.ErrCodeStorageFailure, "failed to create directory")
}
} }
// Create temp file for atomic write // Create temp file for atomic write
tempPath := path + ".tmp" tempPath := relPath + ".tmp"
tempFile, err := os.Create(tempPath) // #nosec G304 -- Temp path is constructed from sanitized storage key tempFile, err := root.Create(tempPath)
if err != nil { if err != nil {
metrics.RecordStorageOperation("filesystem", "put", "error") metrics.RecordStorageOperation("filesystem", "put", "error")
return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to create temp file") return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to create temp file")
@@ -115,14 +128,14 @@ func (fs *FilesystemStorage) Put(ctx context.Context, key string, data io.Reader
written, err := io.Copy(multiWriter, data) written, err := io.Copy(multiWriter, data)
if err != nil { if err != nil {
_ = tempFile.Close() // #nosec G104 -- Cleanup, error not critical _ = tempFile.Close() // #nosec G104 -- Cleanup, error not critical
_ = os.Remove(tempPath) // #nosec G104 -- Cleanup, error not critical _ = root.Remove(tempPath)
metrics.RecordStorageOperation("filesystem", "put", "error") metrics.RecordStorageOperation("filesystem", "put", "error")
return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to write data") return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to write data")
} }
if err := tempFile.Close(); err != nil { if err := tempFile.Close(); err != nil {
_ = os.Remove(tempPath) // #nosec G104 -- Cleanup, error not critical _ = root.Remove(tempPath)
metrics.RecordStorageOperation("filesystem", "put", "error") metrics.RecordStorageOperation("filesystem", "put", "error")
return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to close temp file") return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to close temp file")
} }
@@ -133,13 +146,13 @@ func (fs *FilesystemStorage) Put(ctx context.Context, key string, data io.Reader
sha256Sum := hex.EncodeToString(sha256Hash.Sum(nil)) sha256Sum := hex.EncodeToString(sha256Hash.Sum(nil))
if opts.ChecksumMD5 != "" && opts.ChecksumMD5 != md5Sum { if opts.ChecksumMD5 != "" && opts.ChecksumMD5 != md5Sum {
_ = os.Remove(tempPath) // #nosec G104 -- Cleanup, error not critical _ = root.Remove(tempPath)
metrics.RecordStorageOperation("filesystem", "put", "checksum_error") metrics.RecordStorageOperation("filesystem", "put", "checksum_error")
return errors.New(errors.ErrCodeChecksumMismatch, "MD5 checksum mismatch") return errors.New(errors.ErrCodeChecksumMismatch, "MD5 checksum mismatch")
} }
if opts.ChecksumSHA256 != "" && opts.ChecksumSHA256 != sha256Sum { if opts.ChecksumSHA256 != "" && opts.ChecksumSHA256 != sha256Sum {
_ = os.Remove(tempPath) // #nosec G104 -- Cleanup, error not critical _ = root.Remove(tempPath)
metrics.RecordStorageOperation("filesystem", "put", "checksum_error") metrics.RecordStorageOperation("filesystem", "put", "checksum_error")
return errors.New(errors.ErrCodeChecksumMismatch, "SHA256 checksum mismatch") return errors.New(errors.ErrCodeChecksumMismatch, "SHA256 checksum mismatch")
} }
@@ -151,13 +164,13 @@ func (fs *FilesystemStorage) Put(ctx context.Context, key string, data io.Reader
fs.mu.Lock() fs.mu.Lock()
if fs.quota > 0 && fs.used+written > fs.quota { if fs.quota > 0 && fs.used+written > fs.quota {
fs.mu.Unlock() fs.mu.Unlock()
_ = os.Remove(tempPath) // #nosec G104 -- Cleanup, error not critical _ = root.Remove(tempPath)
metrics.RecordStorageOperation("filesystem", "put", "quota_exceeded") metrics.RecordStorageOperation("filesystem", "put", "quota_exceeded")
return errors.QuotaExceeded(fs.quota) return errors.QuotaExceeded(fs.quota)
} }
if err := os.Rename(tempPath, path); err != nil { if err := root.Rename(tempPath, relPath); err != nil {
fs.mu.Unlock() fs.mu.Unlock()
_ = os.Remove(tempPath) // #nosec G104 -- Cleanup, error not critical _ = root.Remove(tempPath)
metrics.RecordStorageOperation("filesystem", "put", "error") metrics.RecordStorageOperation("filesystem", "put", "error")
return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to rename temp file") return errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to rename temp file")
} }
@@ -408,22 +421,42 @@ func (fs *FilesystemStorage) keyToPath(key string) (string, error) {
} }
target := filepath.Join(fs.basePath, cleaned) target := filepath.Join(fs.basePath, cleaned)
// Defense-in-depth: verify the resolved absolute path is contained
// within the base directory.
targetAbs, err := filepath.Abs(target) targetAbs, err := filepath.Abs(target)
if err != nil { if err != nil {
return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to resolve path") return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to resolve path")
} }
if err := fs.ensureWithinBase(targetAbs); err != nil {
return "", errors.New(errors.ErrCodeStorageFailure, fmt.Sprintf("path traversal rejected: %s", key))
}
return targetAbs, nil
}
func (fs *FilesystemStorage) ensureWithinBase(path string) error {
rel, err := fs.relativeToBase(path)
if err != nil {
return err
}
if rel == ".." || strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
return errors.New(errors.ErrCodeStorageFailure, fmt.Sprintf("path traversal rejected: %s", path))
}
return nil
}
func (fs *FilesystemStorage) relativeToBase(path string) (string, error) {
baseAbs, err := filepath.Abs(fs.basePath) baseAbs, err := filepath.Abs(fs.basePath)
if err != nil { if err != nil {
return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to resolve base path") return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to resolve base path")
} }
if targetAbs != baseAbs && !strings.HasPrefix(targetAbs, baseAbs+string(os.PathSeparator)) { pathAbs, err := filepath.Abs(path)
return "", errors.New(errors.ErrCodeStorageFailure, fmt.Sprintf("path traversal rejected: %s", key)) if err != nil {
return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to resolve path")
} }
rel, err := filepath.Rel(baseAbs, pathAbs)
return target, nil if err != nil {
return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "failed to compare path")
}
return rel, nil
} }
// calculateUsage calculates current storage usage // calculateUsage calculates current storage usage
+28 -1
View File
@@ -130,7 +130,18 @@ func (s *Storage) Put(ctx context.Context, key string, data io.Reader, opts *sto
s.logger.Warn().Err(err).Str("key", key).Msg("nfs: post-put path lookup failed; skipping fsync") s.logger.Warn().Err(err).Str("key", key).Msg("nfs: post-put path lookup failed; skipping fsync")
return nil return nil
} }
f, err := os.OpenFile(path, os.O_RDWR, 0) // #nosec G304 -- path resolved by sanitizing backend relPath, err := relativeToBase(s.path, path)
if err != nil {
s.logger.Warn().Err(err).Str("key", key).Msg("nfs: post-put path escaped configured base; skipping fsync")
return nil
}
root, err := os.OpenRoot(s.path)
if err != nil {
s.logger.Warn().Err(err).Str("path", s.path).Msg("nfs: failed to open configured base; skipping fsync")
return nil
}
defer root.Close() // #nosec G307 -- Best-effort cleanup of opened NFS root
f, err := root.OpenFile(relPath, os.O_RDWR, 0)
if err != nil { if err != nil {
s.logger.Warn().Err(err).Str("key", key).Msg("nfs: post-put open failed; skipping fsync") s.logger.Warn().Err(err).Str("key", key).Msg("nfs: post-put open failed; skipping fsync")
return nil return nil
@@ -226,6 +237,22 @@ func (s *Storage) GetLocalPath(ctx context.Context, key string) (string, error)
return s.fs.GetLocalPath(ctx, key) return s.fs.GetLocalPath(ctx, key)
} }
func relativeToBase(basePath, path string) (string, error) {
baseAbs, err := filepath.Abs(basePath)
if err != nil {
return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "nfs: failed to resolve base path")
}
pathAbs, err := filepath.Abs(path)
if err != nil {
return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "nfs: failed to resolve path")
}
rel, err := filepath.Rel(baseAbs, pathAbs)
if err != nil {
return "", errors.Wrap(err, errors.ErrCodeStorageFailure, "nfs: failed to compare path")
}
return rel, nil
}
// detectMountType returns the filesystem type backing path. Linux-only: on // detectMountType returns the filesystem type backing path. Linux-only: on
// other platforms the second return value is false. Implementation walks // other platforms the second return value is false. Implementation walks
// /proc/mounts and selects the longest matching mount point, which is the // /proc/mounts and selects the longest matching mount point, which is the