Author: avg
Date: Thu Aug 29 07:19:06 2019
New Revision: 351593
URL: https://svnweb.freebsd.org/changeset/base/351593

Log:
  zfs_ioc_snapshot: check user-prop permissions on snapshotted datasets
  
  Previously, the permissions were checked on the pool which was obviously
  incorrect.
  
  After this change, zfs_check_userprops() only validates the properties
  without any permission checks.  The permissions are checked individually
  for each snapshotted dataset.
  
  This was also committed to ZoL: zfsonlinux/zfs@e6203d2
  
  Reported by:  CyberSecure
  MFC after:    1 week
  Sponsored by: CyberSecure

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c     Thu Aug 
29 02:44:18 2019        (r351592)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c     Thu Aug 
29 07:19:06 2019        (r351593)
@@ -2747,10 +2747,9 @@ retry:
  * Check that all the properties are valid user properties.
  */
 static int
-zfs_check_userprops(const char *fsname, nvlist_t *nvl)
+zfs_check_userprops(nvlist_t *nvl)
 {
        nvpair_t *pair = NULL;
-       int error = 0;
 
        while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
                const char *propname = nvpair_name(pair);
@@ -2759,10 +2758,6 @@ zfs_check_userprops(const char *fsname, nvlist_t *nvl)
                    nvpair_type(pair) != DATA_TYPE_STRING)
                        return (SET_ERROR(EINVAL));
 
-               if (error = zfs_secpolicy_write_perms(fsname,
-                   ZFS_DELEG_PERM_USERPROP, CRED()))
-                       return (error);
-
                if (strlen(propname) >= ZAP_MAXNAMELEN)
                        return (SET_ERROR(ENAMETOOLONG));
 
@@ -3429,12 +3424,11 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl
        nvpair_t *pair;
 
        (void) nvlist_lookup_nvlist(innvl, "props", &props);
-       if ((error = zfs_check_userprops(poolname, props)) != 0)
-               return (error);
-
        if (!nvlist_empty(props) &&
            zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS))
                return (SET_ERROR(ENOTSUP));
+       if ((error = zfs_check_userprops(props)) != 0)
+               return (error);
 
        if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
                return (SET_ERROR(EINVAL));
@@ -3442,7 +3436,7 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl
        for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
            pair = nvlist_next_nvpair(snaps, pair)) {
                const char *name = nvpair_name(pair);
-               const char *cp = strchr(name, '@');
+               char *cp = strchr(name, '@');
 
                /*
                 * The snap name must contain an @, and the part after it must
@@ -3458,6 +3452,18 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl
                if (strncmp(name, poolname, poollen) != 0 ||
                    (name[poollen] != '/' && name[poollen] != '@'))
                        return (SET_ERROR(EXDEV));
+
+               /*
+                * Check for permission to set the properties on the fs.
+                */
+               if (!nvlist_empty(props)) {
+                       *cp = '\0';
+                       error = zfs_secpolicy_write_perms(name,
+                           ZFS_DELEG_PERM_USERPROP, CRED());
+                       *cp = '@';
+                       if (error != 0)
+                               return (error);
+               }
 
                /* This must be the only snap of this fs. */
                for (nvpair_t *pair2 = nvlist_next_nvpair(snaps, pair);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to