From nobody Mon Jun 30 14:53:50 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bW8LR5yWhz60Ylj; Mon, 30 Jun 2025 14:53:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bW8LR2DH3z4Qj7; Mon, 30 Jun 2025 14:53:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1751295231; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7jnOh2/MDhsfkQL+xF1sTpQ/uMdsKKd6erojj0nCZgA=; b=u3EU19J2aexQdOxyYyH4g5IHDmpBiWUn2Q/bXKsU64zWwW8YHjllo4tI99QUC9tfE5jgJJ nqLuqz6NAQDvslON6WvBxTcRhWzDsaWOEOZpRTYtVuXmCTvddaM9lRl40jI9X9Cjs6x+fc 9CiOoqJcKPOnqkadPH1ho6OyKH1XxaKHJ8BjvA9OoXmb2MRBJfA0Q1KLudKG+RwUiA1xGT JNq9Ax/aL1KACnQj42wVisnp2999KqwV5HCQSkVBPQRvGCR/jmDe0jl3tybgtfwC4Ay1E0 uHfjfzQkvjS+hCNuMcAGoKkY3fofqqzMZ83i+LquvStTfybK6Z+oz81L1/FrgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1751295231; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7jnOh2/MDhsfkQL+xF1sTpQ/uMdsKKd6erojj0nCZgA=; b=tA1JFYzGmfzZZa/hq9ONWXYdrUj+F3vHkKTa8M2ga2pHw627laL2gKe3JNatf9wFrJ7v8q zfK6fRezp/kZLCfBgkkx9QOxO/E8wDDMGF6I7UvvytnUhPFmESo5rBIakc7macOdR/T5pA IeTvGPBp7ql04tx4TitbRQUtA5kJnk6uz1hRyFBCvQdGap4r7rCz5GVlPljFmdSOw0JnsT Q2jnkDI5VuxUr3iY4FAbgZ91Pd9Xi1Wo+QVmUpcrh8gtyUXUrRqohti3JufB6k1EwW4pip 2qX4JpATNDJKgs78v2O8vxtu55JBhU4FhFS6n/tQ/o7gB2MIozeDUGTdkZ/LKg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1751295231; a=rsa-sha256; cv=none; b=RY/ud7i/9/IDmuhXf51433fJ2RFjiDNQ749xJVmmi41NWlO97dSw2L4nA1yWWtXPt8Nn+g HcKVvu05StRLVJK361h55SN/CPxZHyWOZkHUtplCTK/CrWNwi+2VTvupxH7IrIuJvj+FLn HmQUS4U7jki0xbU+AnBz0st2CjfXGjTbTLPGQ9MTSNiqbX3kJmIw+cJfvtN9zrK0ueMhIM hZcPM9850RKzOZF9IyYHymxH5sEiGcSp6D8V+Rbg/70C8R8wR5mg8ICfZpqN4t5/jVi174 yEcHSi6QZG4IOWyyUE1dDuXz0RRoDae+Up21I+NxKG8/6B+Q7UnhFfW6MOE+PA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bW8LR0WChz17gg; Mon, 30 Jun 2025 14:53:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 55UEroG8035527; Mon, 30 Jun 2025 14:53:50 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 55UEro8u035524; Mon, 30 Jun 2025 14:53:50 GMT (envelope-from git) Date: Mon, 30 Jun 2025 14:53:50 GMT Message-Id: <202506301453.55UEro8u035524@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Rick Macklem Subject: git: 50e733f19b37 - main - nfscl: Use delegation ACE when mounted with nocto List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 50e733f19b37421a64045e131766ad79d08497a4 Auto-Submitted: auto-generated The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=50e733f19b37421a64045e131766ad79d08497a4 commit 50e733f19b37421a64045e131766ad79d08497a4 Author: Rick Macklem AuthorDate: 2025-06-30 14:51:01 +0000 Commit: Rick Macklem CommitDate: 2025-06-30 14:51:01 +0000 nfscl: Use delegation ACE when mounted with nocto For NFSv4.1/4.2, there is an ACE in the delegation reply. Without this patch, this ACE is ignored by the NFSv4 client. This patch enables use of the ACE to avoid the need for Access RPCs when the "nocto" option is specified. This requires a NFSv4.1/4.2 server that does not reply with a bogus ACE that is too generous w.r.t. access permissions. Note that the recent commit 0d51adee3072 added use of the NFSv4 ACL for generation of the ACE in the reply. This patch might be needed for this client change to work correctly if NFSv4 ACLs are being used on the NFSv4.1/4.2 exported file systems. This only affects NFSv4 mounts with the "nocto" mount option and only if NFSv4 servers are issuing delegations with ACEs that specify access. Some NFSv4 servers, such as the Linux knfsd reply with ACEs that do not allow any access, so this patch has no effect for them. --- sys/fs/nfs/nfs_commonacl.c | 2 +- sys/fs/nfs/nfs_var.h | 1 + sys/fs/nfsclient/nfs_clstate.c | 51 ++++++++++++++++++++++++++++++++++++++++++ sys/fs/nfsclient/nfs_clvnops.c | 12 ++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonacl.c b/sys/fs/nfs/nfs_commonacl.c index 69afa8d41712..bba1d8821a9b 100644 --- a/sys/fs/nfs/nfs_commonacl.c +++ b/sys/fs/nfs/nfs_commonacl.c @@ -65,7 +65,7 @@ nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep, goto nfsmout; } else if (len == 0) { /* Netapp filers return a 0 length who for nil users */ - acep->ae_tag = ACL_UNDEFINED_TAG; + acep->ae_tag = ACL_EVERYONE; /* Avoid panics. */ acep->ae_id = ACL_UNDEFINED_ID; acep->ae_perm = (acl_perm_t)0; acep->ae_entry_type = ACL_ENTRY_TYPE_DENY; diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index f59a898369e8..3b6c1ec90c06 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -658,6 +658,7 @@ void nfscl_freelayout(struct nfscllayout *); void nfscl_freeflayout(struct nfsclflayout *); void nfscl_freedevinfo(struct nfscldevinfo *); int nfscl_layoutcommit(vnode_t, NFSPROC_T *); +int nfscl_delegacecheck(struct vnode *, accmode_t, struct ucred *); void nfscl_startdelegrecall(struct nfsclclient *, struct nfsfh *); /* nfs_clport.c */ diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index fe3682ae437e..1ae5ed1a75ca 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -5953,6 +5953,57 @@ tryagain: return (0); } +/* + * Check access against a delegation ace. + * Return EINVAL for any case where the check cannot be completed. + */ +int +nfscl_delegacecheck(struct vnode *vp, accmode_t accmode, struct ucred *cred) +{ + struct nfsclclient *clp; + struct nfscldeleg *dp; + struct nfsnode *np; + struct nfsmount *nmp; + struct acl *aclp; + int error; + + np = VTONFS(vp); + nmp = VFSTONFS(vp->v_mount); + if (!NFSHASNFSV4(nmp) || !NFSHASNFSV4N(nmp) || vp->v_type != VREG) + return (EINVAL); + NFSLOCKMNT(nmp); + if ((nmp->nm_privflag & NFSMNTP_DELEGISSUED) == 0) { + NFSUNLOCKMNT(nmp); + return (EINVAL); + } + NFSUNLOCKMNT(nmp); + aclp = acl_alloc(M_WAITOK); + NFSLOCKCLSTATE(); + clp = nfscl_findcl(nmp); + if (clp == NULL) { + NFSUNLOCKCLSTATE(); + acl_free(aclp); + return (EINVAL); + } + dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len); + if (dp != NULL && (dp->nfsdl_flags & (NFSCLDL_RECALL | + NFSCLDL_DELEGRET)) == 0) { + memcpy(&aclp->acl_entry[0], &dp->nfsdl_ace, + sizeof(struct acl_entry)); + NFSUNLOCKCLSTATE(); + aclp->acl_cnt = 1; + error = vaccess_acl_nfs4(vp->v_type, np->n_vattr.na_uid, + np->n_vattr.na_gid, aclp, accmode, cred); + acl_free(aclp); + if (error == 0 || error == EACCES) + return (error); + } else { + NFSUNLOCKCLSTATE(); + acl_free(aclp); + } + return (EINVAL); +} + /* * Start the recall of a delegation. Called for CB_RECALL and REMOVE * when nlink == 0 after the REMOVE. diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 84046cdb503e..0049d7edca33 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -480,6 +480,18 @@ nfs_access(struct vop_access_args *ap) break; } } + + /* + * For NFSv4, check for a delegation with an Allow ACE, to see + * if that permits access. + */ + if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOCTO) != 0) { + error = nfscl_delegacecheck(vp, ap->a_accmode, ap->a_cred); + if (error == 0) + return (error); + error = 0; + } + /* * For nfs v3 or v4, check to see if we have done this recently, and if * so return our cached result instead of making an ACCESS call.