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
This commit is contained in:
parent
ff72059a94
commit
571b4c060b
1 changed files with 32 additions and 2 deletions
|
@ -4,6 +4,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -62,6 +63,28 @@ func checkMountEmpty(mountpoint string) error {
|
||||||
return nil
|
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
|
// 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 {
|
func NewMountCommand(commandName string, Mount func(f fs.Fs, mountpoint string) error) *cobra.Command {
|
||||||
var commandDefintion = &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
|
config.PassConfigKeyForDaemonization = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mountpoint := args[1]
|
||||||
fdst := cmd.NewFsDir(args)
|
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
|
// Show stats if the user has specifically requested them
|
||||||
if cmd.ShowStats() {
|
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
|
// Skip checkMountEmpty if --allow-non-empty flag is used or if
|
||||||
// the Operating System is Windows
|
// the Operating System is Windows
|
||||||
if !AllowNonEmpty && runtime.GOOS != "windows" {
|
if !AllowNonEmpty && runtime.GOOS != "windows" {
|
||||||
err := checkMountEmpty(args[1])
|
err := checkMountEmpty(mountpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Fatal error: %v", err)
|
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 {
|
if err != nil {
|
||||||
log.Fatalf("Fatal error: %v", err)
|
log.Fatalf("Fatal error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue