Bug 232021 - zfs cannot mount 'dataset': Insufficient privileges
Summary: zfs cannot mount 'dataset': Insufficient privileges
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 11.2-RELEASE
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-10-07 07:23 UTC by Oleg
Modified: 2019-07-17 09:37 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oleg 2018-10-07 07:23:31 UTC
Unprivileged user will not mount dataset even with 'mount' permissions (by zfs allow) and vfs.usermount=1 set. The same user will be able UNmount the dataset (only id vfs.usermount=1, otherwise - not).

# zfs mount zroot/testset
cannot mount 'zroot/testset': Insufficient privileges

How to repeat:

1) Give permissions to unprivileged user bob:

#zfs allow -u bob mount,mountpoint,.... zroot

2) Check it

#zfs allow zroot

---- Permissions on zroot --------------------------------------------
Local+Descendent permissions:
        user bob clone,create,destroy,diff,hold,mount,mountpoint,quota,receive,rollback,send,snapdir,snapshot,userprop
 
3) Set and check

# sysctl vfs.usermount=1
# sysctl -a|grep vfs.usermount

4) Now mount as bob

# zfs mount zroot/testset
cannot mount 'zroot/testset': Insufficient privileges

The problem has been also well described here https://groups.google.com/forum/#!topic/mailing.freebsd.fs/3Wx4K7pJA7U
Comment 1 Yuri Pankov 2018-10-07 09:24:59 UTC
Check that mountpoint permissions allow your user to mount FS on it.
Comment 2 Oleg 2018-10-07 11:54:42 UTC
#zfs allow zroot/testset

---- Permissions on zroot/testset -----------------------------------------
Local+Descendent permissions:
        user bob clone,create,destroy,diff,hold,mount,mountpoint,quota,receive,rollback,send,snapdir,snapshot,userprop
Comment 3 Yuri Pankov 2018-10-07 12:46:59 UTC
Sorry if I was unclear.

$ sudo zfs create -o mountpoint=/tst zroot/tst
$ sudo zfs umount zroot/tst
$ sudo zfs allow -u yuri mount zroot
$ ls -ld /tst
drwxr-xr-x  2 root  wheel  2 Oct  7 15:44 /tst
$ zfs mount zroot/tst
cannot mount 'zroot/tst': Insufficient privileges
$ sudo chown yuri:staff /tst
$ zfs mount zroot/tst
$
Comment 4 Oleg 2018-10-07 14:02:33 UTC
It doesn't work for me. Anyway it would be a workaround if it would work. The problem has nothing with permissions on dataset/mountpoint. They should be kept as the original, owned by root. Manpage clearly indicates that zfs allow should "Delegates ZFS **administration permission** for the file systems to non-privileged users. It's just about *administration permission* that will allow perform some operation by non-priv user for example for clone/remote backup scenarios. Everything else regard zfs allow works as expected but mount. So it's definitely a bug of implementation.
Comment 5 Yuri Pankov 2018-10-07 14:41:17 UTC
Yes, it is administrative permission, and no, it has *everything* to do with permissions on dataset/mountpoint.  You are allowed to run `zfs mount`, but it's not intended as privilege escalation (you would have to have the suid bit set on zfs binary, and that's likely very bad idea), and has to follow all usual mount semantics.
Comment 6 Oleg 2018-10-07 18:26:26 UTC
If I give such permissions then I know what I'm doing and what can be sequence from my configuration. It's not the same as giving full root. I can limit access for this unprivileged user as I wish using other facilities of the OS, but I don't want limit root, neither I want use root for remote replication and backup scenarios.

How mount is worst than say destroy or rollback in terms of system's vulnerability and stability? If I want give zfs destroy permissions to unprivileged user then it works, but if I want give him mount then it won't. I don't see any logic here.
Comment 7 Oleg 2018-10-07 18:29:57 UTC
Finally, if this is behavior as per design and nobody plan to chang, then it should be mentioned in the manpage that "allow mount" will need additionally this or this... e.g. the user must own dataset, or/and a specific sysctl must be set, or/and setuid/sudo, etc.... In fact means "allow mount will not work, forget about it". It would be maybe better remove mount from zfs allow at all. Result is pretty the same.
Comment 8 Yuri Pankov 2018-10-07 18:44:37 UTC
Ugh.. destroy being successful looks like real bug here, you need to be able to unmount and we have the following in mount(2):

     The unmount() system call may fail with one of the following errors:

     [EPERM]            The caller is neither the super-user nor the user who
                        issued the corresponding mount() call.

...but it succeeds when the caller is not super-user nor it is the one who issued the mount() call.
Comment 9 Oleg 2018-10-07 19:46:28 UTC
Unmount as I told is working well with 'allow mount' permission. I don't see why mount then should be implemented different. Everyone should understand that giving any permissions to manage zfs is already dangerous. Period.
Comment 10 Oleg 2018-10-07 19:50:46 UTC
Once again:

As root:

# zfs create -o mountpoint=/tst zroot1/tst
# ls -ld /tst
drwxr-xr-x  2 root  wheel  2 Oct  7 22:43 /tst/
# zfs allow -u bob clone,create,destroy,diff,hold,mount,mountpoint,quota,receive,send,snapdir,snapshot,userprop,rollback zroot

Now as bob:

# zfs unmount zroot1/tst - success
# zfs destroy zroot1/tst - success

zfs destroy zroot1/tst without zfs unmount zroot1/tst - also success


I don't see any logic to limit "mount". It looks like a bug or wrong implementation.
Comment 11 Oleg 2018-10-07 19:52:01 UTC
zroot -> zroot1
Comment 12 Allan Jude freebsd_committer 2018-10-08 01:07:16 UTC
After investigating further, I am a bit torn on this one.

Rules that apply to mounting:

if vfs.usermount == 1, user must own the directory they are attempting to mount to

https://svnweb.freebsd.org/base/head/sys/kern/vfs_mount.c?view=markup#l855

Rules that apply to unmounting:

if vfs.usermount == 1, user must be the one who mounted the filesystem

UNLESS the filesystem has the VFCF_DELEGADMIN flag (which ZFS does), in which case the 'who did the mounting' check is bypassed. 

https://svnweb.freebsd.org/base/head/sys/kern/vfs_subr.c?view=markup#l718


So, ZFS has an exception to the vfs.usermount rule for unmounting. The kernel allows ZFS to implement its own checks (zfs allow mount) to determine if the umount operation should succeed.

This feels oddly asymmetrical to me, although I see the additional security considerations for mounting, vs umounting.

Making the vfs.usermount 'who did the mounting' check apply feels like a regression against the administrators expressed intent with 'zfs allow mount' on the target filesystem.

So it may be the case that we just need to document this as the intended behaviour.
Comment 13 Allan Jude freebsd_committer 2018-10-08 01:09:48 UTC
(In reply to Oleg from comment #9)
The difference is that unmounting has only one input, the filesystem you wish to unmount.

Mounting is more dangerous. Sure bob is allowed to mount zroot1/tst, but the system call also allows them to mount zroot1/tst to /etc

Now a filesystem the user controls, contains the password file, and that user is now root.

That is why the FreeBSD vfs.usermount feature implements a sanity check, bob can only mount filesystems to directories they is the owner of.
Comment 14 Oleg 2018-10-09 07:55:56 UTC
(In reply to Allan Jude from comment #13)
Bob can unmount /etc or destroy it when permissions delegated incorrectly.
Don't delegate mountpoint permissions if don't want allow mount to /etc.
And so on... this all about acts of admin who configures the system what to allow and what not to allow. Moreover, in my case unprivileged user is managed by the same person, i.e. me and/or replication scripts that run from that user cannot be modified to allow dangerous acts.
 
What really looks "oddly asymmetrical" to me is that VFCF_DELEGADMIN flag is not checked on mount but unmount only. I would like to get a patch to change this behavior or additional dangerous sysctl that will allow mount to anywhere for unprivileged user.

I guess the problem here that vfs.usermount has an effect to any user, not just the one related with delegated permissions with zfs. Right? If so, then I see why  "Mounting is more dangerous". In that case the best solution will be to have individual sysct for both mount and unmount in relation with zfs permission delegation subsystem only... or just leave vfs.usermount for anything else except zfs delegation subsystem and add another permission "unmount" for zfs allow... something like that should cover all scenarios.
Comment 15 Oleg 2018-10-18 14:51:57 UTC
Is it going to be fixed(changed)?