diff --git a/changelog/unreleased/pull-5718 b/changelog/unreleased/pull-5718 new file mode 100644 index 000000000..f349bb744 --- /dev/null +++ b/changelog/unreleased/pull-5718 @@ -0,0 +1,9 @@ +Enhancement: stricter early mountpoint validation in `mount` + +`restic mount` accepted parameters that would lead to a FUSE mount operation +failing after having done computationally intensive work to prepare the mount. +The `mountpoint` argument supplied must now refer to the name of a directory +that the current user can access and write to, otherwise `restic mount` will +exit with an error before interacting with the repository. + +https://github.com/restic/restic/pull/5718 diff --git a/cmd/restic/cmd_mount.go b/cmd/restic/cmd_mount.go index 202109fa6..eb86cbada 100644 --- a/cmd/restic/cmd_mount.go +++ b/cmd/restic/cmd_mount.go @@ -11,6 +11,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" + "golang.org/x/sys/unix" "github.com/restic/restic/internal/data" "github.com/restic/restic/internal/debug" @@ -35,8 +36,8 @@ func newMountCommand(globalOptions *global.Options) *cobra.Command { Use: "mount [flags] mountpoint", Short: "Mount the repository", Long: ` -The "mount" command mounts the repository via fuse to a directory. This is a -read-only mount. +The "mount" command mounts the repository via fuse over a writeable directory. +The repository will be mounted read-only. Snapshot Directories ==================== @@ -133,9 +134,19 @@ func runMount(ctx context.Context, opts MountOptions, gopts global.Options, args // Check the existence of the mount point at the earliest stage to // prevent unnecessary computations while opening the repository. - if _, err := os.Stat(mountpoint); errors.Is(err, os.ErrNotExist) { + stat, err := os.Stat(mountpoint) + if errors.Is(err, os.ErrNotExist) { printer.P("Mountpoint %s doesn't exist", mountpoint) - return err + return errors.Fatal("invalid mountpoint") + } else if !stat.IsDir() { + printer.P("Mountpoint %s is not a directory", mountpoint) + return errors.Fatal("invalid mountpoint") + } + + err = unix.Access(mountpoint, unix.W_OK|unix.X_OK) + if err != nil { + printer.P("Mountpoint %s is not writeable or not excutable", mountpoint) + return errors.Fatal("inaccessible mountpoint") } debug.Log("start mount")