mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	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. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Matt Ahrens <mahrens@delphix.com> Signed-off-by: Andriy Gapon <avg@FreeBSD.org> Closes #9179 Closes #9180
This commit is contained in:
		
							parent
							
								
									ea34735203
								
							
						
					
					
						commit
						931bef81c8
					
				@ -2744,10 +2744,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);
 | 
			
		||||
@ -2756,10 +2755,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));
 | 
			
		||||
 | 
			
		||||
@ -3473,19 +3468,18 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	snaps = fnvlist_lookup_nvlist(innvl, "snaps");
 | 
			
		||||
	poollen = strlen(poolname);
 | 
			
		||||
	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
 | 
			
		||||
@ -3502,6 +3496,18 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
 | 
			
		||||
		    (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);
 | 
			
		||||
		    pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user