Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/gateway: judge loop symbolic links rather than hard-code deep limit #4045

Merged
merged 13 commits into from
Sep 18, 2023
4 changes: 1 addition & 3 deletions .github/scripts/command/sync_minio.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ test_sync_deep_symlink(){
cat symlink_40 | grep hello
cat symlink_41 && echo "cat symlink_41 fail" && exit 1 || true
cd -
./juicefs sync minio://minioadmin:minioadmin@localhost:9005/myjfs/ minio://minioadmin:minioadmin@localhost:9000/myjfs/ && echo "sync should fail" && exit 1 || true
rm -rf /jfs/symlink_41
./juicefs sync minio://minioadmin:minioadmin@localhost:9005/myjfs/ minio://minioadmin:minioadmin@localhost:9000/myjfs/
./juicefs sync minio://minioadmin:minioadmin@localhost:9005/myjfs/ minio://minioadmin:minioadmin@localhost:9000/myjfs/
for i in {1..40}; do
./mc cat myminio/myjfs/symlink_$i | grep "^hello$"
done
Expand Down
11 changes: 7 additions & 4 deletions pkg/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,10 +681,10 @@ func (fs *FileSystem) lookup(ctx meta.Context, parent Ino, name string, inode *I
}

func (fs *FileSystem) resolve(ctx meta.Context, p string, followLastSymlink bool) (fi *FileStat, err syscall.Errno) {
return fs.doResolve(ctx, p, followLastSymlink, 0)
return fs.doResolve(ctx, p, followLastSymlink, make(map[Ino]struct{}))
}

func (fs *FileSystem) doResolve(ctx meta.Context, p string, followLastSymlink bool, depth int) (fi *FileStat, err syscall.Errno) {
func (fs *FileSystem) doResolve(ctx meta.Context, p string, followLastSymlink bool, visited map[Ino]struct{}) (fi *FileStat, err syscall.Errno) {
var inode Ino
var attr = &Attr{}

Expand Down Expand Up @@ -740,8 +740,11 @@ func (fs *FileSystem) doResolve(ctx meta.Context, p string, followLastSymlink bo
}
fi = AttrToFileInfo(inode, attr)
if (!resolved || followLastSymlink) && fi.IsSymlink() {
if depth > 39 {
if _, ok := visited[inode]; ok {
logger.Errorf("find a loop symlink: %d", inode)
return nil, syscall.ELOOP
} else {
visited[inode] = struct{}{}
}
var buf []byte
err = fs.m.ReadLink(ctx, inode, &buf)
Expand All @@ -753,7 +756,7 @@ func (fs *FileSystem) doResolve(ctx meta.Context, p string, followLastSymlink bo
return &FileStat{name: target}, syscall.ENOTSUP
}
target = path.Join(strings.Join(ss[:i], "/"), target)
fi, err = fs.doResolve(ctx, target, followLastSymlink, depth+1)
fi, err = fs.doResolve(ctx, target, followLastSymlink, visited)
if err != 0 {
return
}
Expand Down