diff --git a/man/man4/zfs.4 b/man/man4/zfs.4 index 30c168253f96..7e58d32cedf3 100644 --- a/man/man4/zfs.4 +++ b/man/man4/zfs.4 @@ -1375,6 +1375,15 @@ which have the .Em no_root_squash option set. . +.It Sy zfs_snapshot_no_setuid Ns = Ns Sy 0 Ns | Ns 1 Pq int +Whether to disable +.Em setuid/setgid +support for snapshot mounts triggered by access to the +.Sy .zfs/snapshot +directory by setting the +.Em nosuid +mount option. +. .It Sy zfs_flags Ns = Ns Sy 0 Pq int Set additional debugging flags. The following flags may be bitwise-ored together: diff --git a/module/os/linux/zfs/zfs_ctldir.c b/module/os/linux/zfs/zfs_ctldir.c index 4250ce32a3fc..9397a5f4ba51 100644 --- a/module/os/linux/zfs/zfs_ctldir.c +++ b/module/os/linux/zfs/zfs_ctldir.c @@ -111,6 +111,7 @@ static krwlock_t zfs_snapshot_lock; */ int zfs_expire_snapshot = ZFSCTL_EXPIRE_SNAPSHOT; static int zfs_admin_snapshot = 0; +static int zfs_snapshot_no_setuid = 0; typedef struct { char *se_name; /* full snapshot name */ @@ -1102,9 +1103,9 @@ zfsctl_snapshot_mount(struct path *path, int flags) zfsvfs_t *zfsvfs; zfsvfs_t *snap_zfsvfs; zfs_snapentry_t *se; - char *full_name, *full_path; - char *argv[] = { "/usr/bin/env", "mount", "-t", "zfs", "-n", NULL, NULL, - NULL }; + char *full_name, *full_path, *options; + char *argv[] = { "/usr/bin/env", "mount", "-t", "zfs", "-n", "-o", NULL, + NULL, NULL, NULL }; char *envp[] = { NULL }; int error; struct path spath; @@ -1118,6 +1119,7 @@ zfsctl_snapshot_mount(struct path *path, int flags) full_name = kmem_zalloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP); full_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); + options = kmem_zalloc(7, KM_SLEEP); error = zfsctl_snapshot_name(zfsvfs, dname(dentry), ZFS_MAX_DATASET_NAME_LEN, full_name); @@ -1133,6 +1135,9 @@ zfsctl_snapshot_mount(struct path *path, int flags) zfsvfs->z_vfs->vfs_mntpoint ? zfsvfs->z_vfs->vfs_mntpoint : "", dname(dentry)); + snprintf(options, 7, "%s", + zfs_snapshot_no_setuid ? "nosuid" : "suid"); + /* * Multiple concurrent automounts of a snapshot are never allowed. * The snapshot may be manually mounted as many times as desired. @@ -1155,8 +1160,9 @@ zfsctl_snapshot_mount(struct path *path, int flags) * value from call_usermodehelper() will be (exitcode << 8 + signal). */ dprintf("mount; name=%s path=%s\n", full_name, full_path); - argv[5] = full_name; - argv[6] = full_path; + argv[6] = options; + argv[7] = full_name; + argv[8] = full_path; error = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); if (error) { if (!(error & MOUNT_BUSY << 8)) { @@ -1317,3 +1323,7 @@ MODULE_PARM_DESC(zfs_admin_snapshot, "Enable mkdir/rmdir/mv in .zfs/snapshot"); module_param(zfs_expire_snapshot, int, 0644); MODULE_PARM_DESC(zfs_expire_snapshot, "Seconds to expire .zfs/snapshot"); + +module_param(zfs_snapshot_no_setuid, int, 0644); +MODULE_PARM_DESC(zfs_snapshot_no_setuid, + "Disable setuid/setgid for automounts in .zfs/snapshot");