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>