From owner-p4-projects@FreeBSD.ORG Mon May 25 08:04:40 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C46601065672; Mon, 25 May 2009 08:04:40 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 84795106564A for ; Mon, 25 May 2009 08:04:40 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 69E478FC2B for ; Mon, 25 May 2009 08:04:40 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n4P84eDu097067 for ; Mon, 25 May 2009 08:04:40 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n4P84ebN097065 for perforce@freebsd.org; Mon, 25 May 2009 08:04:40 GMT (envelope-from trasz@freebsd.org) Date: Mon, 25 May 2009 08:04:40 GMT Message-Id: <200905250804.n4P84ebN097065@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 162705 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 May 2009 08:04:41 -0000 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);