From 571b4c060b8a81004db5926e0cdb4acccec8c6a2 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 10 Jan 2019 14:18:00 +0000 Subject: [PATCH] mount: check that mountpoint and local directory to mount don't overlap If the mountpoint and the directory to mount overlap this causes a lockup. Fixes #2905 --- cmd/mountlib/mount.go | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/cmd/mountlib/mount.go b/cmd/mountlib/mount.go index c7c50f0e6..4794e2b52 100644 --- a/cmd/mountlib/mount.go +++ b/cmd/mountlib/mount.go @@ -4,6 +4,7 @@ import ( "io" "log" "os" + "path/filepath" "runtime" "strings" "time" @@ -62,6 +63,28 @@ func checkMountEmpty(mountpoint string) error { return nil } +// Check the root doesn't overlap the mountpoint +func checkMountpointOverlap(root, mountpoint string) error { + abs := func(x string) string { + if absX, err := filepath.EvalSymlinks(x); err == nil { + x = absX + } + if absX, err := filepath.Abs(x); err == nil { + x = absX + } + x = filepath.ToSlash(x) + if !strings.HasSuffix(x, "/") { + x += "/" + } + return x + } + rootAbs, mountpointAbs := abs(root), abs(mountpoint) + if strings.HasPrefix(rootAbs, mountpointAbs) || strings.HasPrefix(mountpointAbs, rootAbs) { + return errors.Errorf("mount point %q and directory to be mounted %q mustn't overlap", mountpoint, root) + } + return nil +} + // NewMountCommand makes a mount command with the given name and Mount function func NewMountCommand(commandName string, Mount func(f fs.Fs, mountpoint string) error) *cobra.Command { var commandDefintion = &cobra.Command{ @@ -220,7 +243,14 @@ be copied to the vfs cache before opening with --vfs-cache-mode full. config.PassConfigKeyForDaemonization = true } + mountpoint := args[1] fdst := cmd.NewFsDir(args) + if fdst.Name() == "" || fdst.Name() == "local" { + err := checkMountpointOverlap(fdst.Root(), mountpoint) + if err != nil { + log.Fatalf("Fatal error: %v", err) + } + } // Show stats if the user has specifically requested them if cmd.ShowStats() { @@ -230,7 +260,7 @@ be copied to the vfs cache before opening with --vfs-cache-mode full. // Skip checkMountEmpty if --allow-non-empty flag is used or if // the Operating System is Windows if !AllowNonEmpty && runtime.GOOS != "windows" { - err := checkMountEmpty(args[1]) + err := checkMountEmpty(mountpoint) if err != nil { log.Fatalf("Fatal error: %v", err) } @@ -253,7 +283,7 @@ be copied to the vfs cache before opening with --vfs-cache-mode full. } } - err := Mount(fdst, args[1]) + err := Mount(fdst, mountpoint) if err != nil { log.Fatalf("Fatal error: %v", err) }