Browse Source

Prevent bucket renaming in filer, fuse mount, and S3 (#8048)

* prevent bucket renaming in filer, fuse mount, s3

* refactor CanRename to support context propagation

* harden bucket rename validation to fail closed on find error
master
Chris Lu 8 hours ago
committed by GitHub
parent
commit
796a911cb3
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      weed/filer/filer_buckets.go
  2. 4
      weed/filer/filer_delete_entry.go
  3. 13
      weed/filer/filer_rename.go
  4. 4
      weed/server/filer_grpc_server_rename.go

2
weed/filer/filer_buckets.go

@ -4,7 +4,7 @@ import (
"strings"
)
func (f *Filer) isBucket(entry *Entry) bool {
func (f *Filer) IsBucket(entry *Entry) bool {
if !entry.IsDirectory() {
return false
}

4
weed/filer/filer_delete_entry.go

@ -29,7 +29,7 @@ func (f *Filer) DeleteEntryMetaAndData(ctx context.Context, p util.FullPath, isR
if ifNotModifiedAfter > 0 && entry.Attr.Mtime.Unix() > ifNotModifiedAfter {
return nil
}
isDeleteCollection := f.isBucket(entry)
isDeleteCollection := f.IsBucket(entry)
if entry.IsDirectory() {
// delete the folder children, not including the folder itself
err = f.doBatchDeleteFolderMetaAndData(ctx, entry, isRecursive, ignoreRecursiveError, shouldDeleteChunks && !isDeleteCollection, isDeleteCollection, isFromOtherCluster, signatures, func(hardLinkIds []HardLinkId) error {
@ -90,7 +90,7 @@ func (f *Filer) doBatchDeleteFolderMetaAndData(ctx context.Context, entry *Entry
for _, sub := range entries {
lastFileName = sub.Name()
if sub.IsDirectory() {
subIsDeletingBucket := f.isBucket(sub)
subIsDeletingBucket := f.IsBucket(sub)
err = f.doBatchDeleteFolderMetaAndData(ctx, sub, isRecursive, ignoreRecursiveError, shouldDeleteChunks, subIsDeletingBucket, false, nil, onHardLinkIdsFn)
} else {
f.NotifyUpdateEvent(ctx, sub, nil, shouldDeleteChunks, isFromOtherCluster, nil)

13
weed/filer/filer_rename.go

@ -1,18 +1,29 @@
package filer
import (
"context"
"fmt"
"strings"
"github.com/seaweedfs/seaweedfs/weed/util"
)
func (f *Filer) CanRename(source, target util.FullPath, oldName string) error {
func (f *Filer) CanRename(ctx context.Context, source, target util.FullPath, oldName string) error {
sourcePath := source.Child(oldName)
if strings.HasPrefix(string(target), string(sourcePath)) {
return fmt.Errorf("mv: can not move directory to a subdirectory of itself")
}
// Check if attempting to rename a bucket itself
// Need to load the entry to check if it's a bucket
entry, err := f.FindEntry(ctx, sourcePath)
if err != nil {
return err
}
if f.IsBucket(entry) {
return fmt.Errorf("bucket renaming is not allowed")
}
sourceBucket := f.DetectBucket(source)
targetBucket := f.DetectBucket(target)
if sourceBucket != targetBucket {

4
weed/server/filer_grpc_server_rename.go

@ -19,7 +19,7 @@ func (fs *FilerServer) AtomicRenameEntry(ctx context.Context, req *filer_pb.Atom
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
newParent := util.FullPath(filepath.ToSlash(req.NewDirectory))
if err := fs.filer.CanRename(oldParent, newParent, req.OldName); err != nil {
if err := fs.filer.CanRename(ctx, oldParent, newParent, req.OldName); err != nil {
return nil, err
}
@ -55,7 +55,7 @@ func (fs *FilerServer) StreamRenameEntry(req *filer_pb.StreamRenameEntryRequest,
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
newParent := util.FullPath(filepath.ToSlash(req.NewDirectory))
if err := fs.filer.CanRename(oldParent, newParent, req.OldName); err != nil {
if err := fs.filer.CanRename(stream.Context(), oldParent, newParent, req.OldName); err != nil {
return err
}

Loading…
Cancel
Save