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
This commit is contained in:
@@ -4,7 +4,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f *Filer) isBucket(entry *Entry) bool {
|
func (f *Filer) IsBucket(entry *Entry) bool {
|
||||||
if !entry.IsDirectory() {
|
if !entry.IsDirectory() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func (f *Filer) DeleteEntryMetaAndData(ctx context.Context, p util.FullPath, isR
|
|||||||
if ifNotModifiedAfter > 0 && entry.Attr.Mtime.Unix() > ifNotModifiedAfter {
|
if ifNotModifiedAfter > 0 && entry.Attr.Mtime.Unix() > ifNotModifiedAfter {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
isDeleteCollection := f.isBucket(entry)
|
isDeleteCollection := f.IsBucket(entry)
|
||||||
if entry.IsDirectory() {
|
if entry.IsDirectory() {
|
||||||
// delete the folder children, not including the folder itself
|
// 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 {
|
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 {
|
for _, sub := range entries {
|
||||||
lastFileName = sub.Name()
|
lastFileName = sub.Name()
|
||||||
if sub.IsDirectory() {
|
if sub.IsDirectory() {
|
||||||
subIsDeletingBucket := f.isBucket(sub)
|
subIsDeletingBucket := f.IsBucket(sub)
|
||||||
err = f.doBatchDeleteFolderMetaAndData(ctx, sub, isRecursive, ignoreRecursiveError, shouldDeleteChunks, subIsDeletingBucket, false, nil, onHardLinkIdsFn)
|
err = f.doBatchDeleteFolderMetaAndData(ctx, sub, isRecursive, ignoreRecursiveError, shouldDeleteChunks, subIsDeletingBucket, false, nil, onHardLinkIdsFn)
|
||||||
} else {
|
} else {
|
||||||
f.NotifyUpdateEvent(ctx, sub, nil, shouldDeleteChunks, isFromOtherCluster, nil)
|
f.NotifyUpdateEvent(ctx, sub, nil, shouldDeleteChunks, isFromOtherCluster, nil)
|
||||||
|
|||||||
@@ -1,18 +1,29 @@
|
|||||||
package filer
|
package filer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
"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)
|
sourcePath := source.Child(oldName)
|
||||||
if strings.HasPrefix(string(target), string(sourcePath)) {
|
if strings.HasPrefix(string(target), string(sourcePath)) {
|
||||||
return fmt.Errorf("mv: can not move directory to a subdirectory of itself")
|
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)
|
sourceBucket := f.DetectBucket(source)
|
||||||
targetBucket := f.DetectBucket(target)
|
targetBucket := f.DetectBucket(target)
|
||||||
if sourceBucket != targetBucket {
|
if sourceBucket != targetBucket {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func (fs *FilerServer) AtomicRenameEntry(ctx context.Context, req *filer_pb.Atom
|
|||||||
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
|
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
|
||||||
newParent := util.FullPath(filepath.ToSlash(req.NewDirectory))
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ func (fs *FilerServer) StreamRenameEntry(req *filer_pb.StreamRenameEntryRequest,
|
|||||||
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
|
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
|
||||||
newParent := util.FullPath(filepath.ToSlash(req.NewDirectory))
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user