fix: harden maintenance operations

This commit is contained in:
proxyctl coordinator
2026-07-17 03:50:18 +08:00
parent d4c76e4b3c
commit b28ebca2d7
9 changed files with 273 additions and 83 deletions
+55
View File
@@ -18,6 +18,22 @@ import (
type Owner struct{ UID, GID int }
// ExistingTrustedRoot returns the nearest existing ancestor without resolving
// symlinks. Descriptor traversal will subsequently reject a symlink ancestor.
func ExistingTrustedRoot(path string) string {
candidate := filepath.Dir(filepath.Clean(path))
for {
if _, err := os.Lstat(candidate); err == nil || !errors.Is(err, fs.ErrNotExist) {
return candidate
}
parent := filepath.Dir(candidate)
if parent == candidate {
return candidate
}
candidate = parent
}
}
func OpenNoFollow(path string, flags int, mode uint32) (*os.File, error) {
fd, err := unix.Open(path, flags|unix.O_CLOEXEC|unix.O_NOFOLLOW, mode)
if err != nil {
@@ -55,6 +71,45 @@ type Store struct {
Owner *Owner
}
// OpenRegular opens a regular file through a descriptor-anchored parent path.
// Parent components and the final file are never followed through symlinks.
func (s Store) OpenRegular(path string, flags int, mode os.FileMode) (*os.File, error) {
directory, base, err := s.openParent(path, flags&unix.O_CREAT != 0)
if err != nil {
return nil, err
}
if err := directory.Chmod(0o700); err != nil {
_ = directory.Close()
return nil, err
}
if s.Owner != nil && (s.Owner.UID != os.Geteuid() || s.Owner.GID != os.Getegid()) {
if err := directory.Chown(s.Owner.UID, s.Owner.GID); err != nil {
_ = directory.Close()
return nil, err
}
}
file, err := OpenAt(directory, base, flags, uint32(mode.Perm()))
_ = directory.Close()
if err != nil {
return nil, err
}
if err := regular(file); err != nil {
_ = file.Close()
return nil, err
}
if err := file.Chmod(mode.Perm()); err != nil {
_ = file.Close()
return nil, err
}
if s.Owner != nil && (s.Owner.UID != os.Geteuid() || s.Owner.GID != os.Getegid()) {
if err := file.Chown(s.Owner.UID, s.Owner.GID); err != nil {
_ = file.Close()
return nil, err
}
}
return file, nil
}
func (s Store) ReadFile(path string) ([]byte, error) {
directory, base, err := s.openParent(path, false)
if err != nil {