Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 May 2009 08:04:40 GMT
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 162705 for review
Message-ID:  <200905250804.n4P84ebN097065@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=162705

Change 162705 by trasz@trasz_victim on 2009/05/25 08:03:40

	Fix ACL size handling in ZFS.

Affected files ...

.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c#3 edit
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/compat/opensolaris/sys/opensolaris_acl.h#3 edit
.. //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#22 edit

Differences ...

==== //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c#3 (text+ko) ====

@@ -107,6 +107,18 @@
 
 	bzero(aclp, sizeof(*aclp));
 
+	if (nentries > ACL_MAX_ENTRIES) {
+		/*
+		 * I believe it may happen only when moving a pool
+		 * from SunOS to FreeBSD.
+		 */
+		printf("acl_from_aces: ZFS ACL too big to fit "
+		    "into 'struct acl'; returning EINVAL.\n");
+		return (EINVAL);
+	}
+
+	KASSERT(nentries >= 1, ("empty ZFS ACL"));
+
 	aclp->acl_cnt = nentries;
 	aclp->acl_maxcnt = ACL_MAX_ENTRIES;
 
@@ -147,14 +159,14 @@
 			entry->ae_entry_type = ACL_ENTRY_TYPE_ALARM;
 			break;
 		default:
-			panic("_acl_from_aces: a_type is 0x%x", ace->a_type);
+			panic("acl_from_aces: a_type is 0x%x", ace->a_type);
 		}
 	}
 
 	return (0);
 }
 
-int
+void
 aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp)
 {
 	int i;
@@ -199,9 +211,7 @@
 			ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
 			break;
 		default:
-			panic("_aces_from_acl: ae_entry_type is 0x%x", entry->ae_entry_type);
+			panic("aces_from_acl: ae_entry_type is 0x%x", entry->ae_entry_type);
 		}
 	}
-
-	return (0);
 }

==== //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/compat/opensolaris/sys/opensolaris_acl.h#3 (text+ko) ====

@@ -29,7 +29,7 @@
 #ifndef OPENSOLARIS_ACL_H
 #define OPENSOLARIS_ACL_H
 
-int aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp);
+void aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp);
 int acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries);
 
 #endif /* OPENSOLARIS_ACL_H */

==== //depot/projects/soc2008/trasz_nfs4acl/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#22 (text+ko) ====

@@ -4855,18 +4855,22 @@
 	if (ap->a_aclp->acl_cnt < 1 || ap->a_aclp->acl_cnt > MAX_ACL_ENTRIES)
 		return (EINVAL);
 
+	/*
+	 * With NFS4 ACLs, chmod(2) may need to add additional entries,
+	 * splitting every entry into two and appending "canonical six"
+	 * entries at the end.  Don't allow for setting an ACL that would
+	 * cause chmod(2) to run out of ACL entries.
+	 */
+	if (inkernelacl->acl_cnt * 2 + 6 > ACL_MAX_ENTRIES)
+		return (ENOSPC);
+
 	vsecattr.vsa_mask = VSA_ACE;
 	aclbsize = ap->a_aclp->acl_cnt * sizeof(ace_t);
 	vsecattr.vsa_aclentp = kmem_alloc(aclbsize, KM_SLEEP);
 	aaclp = vsecattr.vsa_aclentp;
 	vsecattr.vsa_aclentsz = aclbsize;
 
-	error = aces_from_acl(vsecattr.vsa_aclentp, &vsecattr.vsa_aclcnt, ap->a_aclp);
-	if (error != 0) {
-		kmem_free(aaclp, aclbsize);
-		return (EINVAL);
-	}
-
+	aces_from_acl(vsecattr.vsa_aclentp, &vsecattr.vsa_aclcnt, ap->a_aclp);
 	if (error = zfs_setsecattr(ap->a_vp, &vsecattr, 0, ap->a_cred, NULL)) {
 		kmem_free(aaclp, aclbsize);
 		return (error);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905250804.n4P84ebN097065>