git: 3953a0d780ac - stable/13 - nfsd: Do not accept audit/alarm ACEs for the NFSv4 server

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Tue, 25 Jan 2022 23:24:51 UTC
The branch stable/13 has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=3953a0d780ac5b4fff3d80625c74d012a4744b68

commit 3953a0d780ac5b4fff3d80625c74d012a4744b68
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2022-01-11 17:40:07 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2022-01-25 23:22:37 +0000

    nfsd: Do not accept audit/alarm ACEs for the NFSv4 server
    
    The UFS and ZFS file systems only support Allow/Deny ACEs
    in the NFSv4 ACLs.  This patch does not allow the server
    to parse Audit/Alarm ACEs.  The NFSv4 client is still
    allowed to pase Audit/Alarm ACEs, since non-FreeBSD NFSv4
    servers may use them.
    
    This patch should not have a significant effect, since the
    UFS and ZFS file systems will not handle these ACEs anyhow.
    It simply serves as an additional "safety belt" for the
    NFSv4 server.
    
    (cherry picked from commit a91a57846b5863b7ac4687cf202bb9496e028ab5)
---
 sys/fs/nfs/nfs_commonacl.c      |  6 +++---
 sys/fs/nfs/nfs_commonsubs.c     | 22 +++++++++++-----------
 sys/fs/nfs/nfs_var.h            |  4 ++--
 sys/fs/nfsclient/nfs_clrpcops.c | 16 ++++++++--------
 sys/fs/nfsserver/nfs_nfsdport.c |  4 ++--
 5 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/sys/fs/nfs/nfs_commonacl.c b/sys/fs/nfs/nfs_commonacl.c
index 19492675e731..b733dc52803f 100644
--- a/sys/fs/nfs/nfs_commonacl.c
+++ b/sys/fs/nfs/nfs_commonacl.c
@@ -42,7 +42,7 @@ static int nfsrv_acemasktoperm(u_int32_t acetype, u_int32_t mask, int owner,
  */
 int
 nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
-    int *aceerrp, int *acesizep, NFSPROC_T *p)
+    bool server, int *aceerrp, int *acesizep, NFSPROC_T *p)
 {
 	u_int32_t *tl;
 	int len, gotid = 0, owner = 0, error = 0, aceerr = 0;
@@ -154,9 +154,9 @@ nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
 			acep->ae_entry_type = ACL_ENTRY_TYPE_ALLOW;
 		else if (acetype == NFSV4ACE_DENIEDTYPE)
 			acep->ae_entry_type = ACL_ENTRY_TYPE_DENY;
-		else if (acetype == NFSV4ACE_AUDITTYPE)
+		else if (!server && acetype == NFSV4ACE_AUDITTYPE)
 			acep->ae_entry_type = ACL_ENTRY_TYPE_AUDIT;
-		else if (acetype == NFSV4ACE_ALARMTYPE)
+		else if (!server && acetype == NFSV4ACE_ALARMTYPE)
 			acep->ae_entry_type = ACL_ENTRY_TYPE_ALARM;
 		else
 			aceerr = NFSERR_ATTRNOTSUPP;
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index ff92095b6182..51071a6f03ca 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -1090,8 +1090,8 @@ nfsmout:
  * If the aclp == NULL or won't fit in an acl, just discard the acl info.
  */
 int
-nfsrv_dissectacl(struct nfsrv_descript *nd, NFSACL_T *aclp, int *aclerrp,
-    int *aclsizep, __unused NFSPROC_T *p)
+nfsrv_dissectacl(struct nfsrv_descript *nd, NFSACL_T *aclp, bool server,
+    int *aclerrp, int *aclsizep, __unused NFSPROC_T *p)
 {
 	u_int32_t *tl;
 	int i, aclsize;
@@ -1122,7 +1122,7 @@ nfsrv_dissectacl(struct nfsrv_descript *nd, NFSACL_T *aclp, int *aclerrp,
 	for (i = 0; i < acecnt; i++) {
 		if (aclp && !aceerr)
 			error = nfsrv_dissectace(nd, &aclp->acl_entry[i],
-			    &aceerr, &acesize, p);
+			    server, &aceerr, &acesize, p);
 		else
 			error = nfsrv_skipace(nd, &acesize);
 		if (error)
@@ -1487,8 +1487,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
 				NFSACL_T *naclp;
 
 				naclp = acl_alloc(M_WAITOK);
-				error = nfsrv_dissectacl(nd, naclp, &aceerr,
-				    &cnt, p);
+				error = nfsrv_dissectacl(nd, naclp, true,
+				    &aceerr, &cnt, p);
 				if (error) {
 				    acl_free(naclp);
 				    goto nfsmout;
@@ -1498,8 +1498,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
 				    *retcmpp = NFSERR_NOTSAME;
 				acl_free(naclp);
 			    } else {
-				error = nfsrv_dissectacl(nd, NULL, &aceerr,
-				    &cnt, p);
+				error = nfsrv_dissectacl(nd, NULL, true,
+				    &aceerr, &cnt, p);
 				if (error)
 				    goto nfsmout;
 				*retcmpp = NFSERR_ATTRNOTSUPP;
@@ -1507,11 +1507,11 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
 			  }
 			} else {
 				if (vp != NULL && aclp != NULL)
-				    error = nfsrv_dissectacl(nd, aclp, &aceerr,
-					&cnt, p);
+				    error = nfsrv_dissectacl(nd, aclp, false,
+					&aceerr, &cnt, p);
 				else
-				    error = nfsrv_dissectacl(nd, NULL, &aceerr,
-					&cnt, p);
+				    error = nfsrv_dissectacl(nd, NULL, false,
+					&aceerr, &cnt, p);
 				if (error)
 				    goto nfsmout;
 			}
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 8f7ae9df78e9..b5bc5178187e 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -329,7 +329,7 @@ int nfsm_advance(struct nfsrv_descript *, int, int);
 void *nfsm_dissct(struct nfsrv_descript *, int, int);
 void newnfs_copycred(struct nfscred *, struct ucred *);
 void newnfs_copyincred(struct ucred *, struct nfscred *);
-int nfsrv_dissectacl(struct nfsrv_descript *, NFSACL_T *, int *,
+int nfsrv_dissectacl(struct nfsrv_descript *, NFSACL_T *, bool, int *,
     int *, NFSPROC_T *);
 int nfsrv_getattrbits(struct nfsrv_descript *, nfsattrbit_t *, int *,
     int *);
@@ -433,7 +433,7 @@ int nfs_supportsnfsv4acls(vnode_t);
 
 /* nfs_commonacl.c */
 int nfsrv_dissectace(struct nfsrv_descript *, struct acl_entry *,
-    int *, int *, NFSPROC_T *);
+    bool, int *, int *, NFSPROC_T *);
 int nfsrv_buildacl(struct nfsrv_descript *, NFSACL_T *, enum vtype,
     NFSPROC_T *);
 int nfsrv_compareacl(NFSACL_T *, NFSACL_T *);
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 72e3b74aa31e..9922cf00d464 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -619,8 +619,8 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen,
 			}
 			if (ret)
 				ndp->nfsdl_flags |= NFSCLDL_RECALL;
-			error = nfsrv_dissectace(nd, &ndp->nfsdl_ace, &ret,
-			    &acesize, p);
+			error = nfsrv_dissectace(nd, &ndp->nfsdl_ace, false,
+			    &ret, &acesize, p);
 			if (error)
 				goto nfsmout;
 		} else if (deleg != NFSV4OPEN_DELEGATENONE) {
@@ -2321,8 +2321,8 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
 			}
 			if (ret)
 				dp->nfsdl_flags |= NFSCLDL_RECALL;
-			error = nfsrv_dissectace(nd, &dp->nfsdl_ace, &ret,
-			    &acesize, p);
+			error = nfsrv_dissectace(nd, &dp->nfsdl_ace, false,
+			    &ret, &acesize, p);
 			if (error)
 				goto nfsmout;
 		} else if (deleg != NFSV4OPEN_DELEGATENONE) {
@@ -7759,8 +7759,8 @@ nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp,
 				ndp->nfsdl_flags = NFSCLDL_READ;
 			if (ret != 0)
 				ndp->nfsdl_flags |= NFSCLDL_RECALL;
-			error = nfsrv_dissectace(nd, &ndp->nfsdl_ace, &ret,
-			    &acesize, p);
+			error = nfsrv_dissectace(nd, &ndp->nfsdl_ace, false,
+			    &ret, &acesize, p);
 			if (error != 0)
 				goto nfsmout;
 		} else if (deleg != NFSV4OPEN_DELEGATENONE) {
@@ -7970,8 +7970,8 @@ nfsrpc_createlayout(vnode_t dvp, char *name, int namelen, struct vattr *vap,
 			}
 			if (ret != 0)
 				dp->nfsdl_flags |= NFSCLDL_RECALL;
-			error = nfsrv_dissectace(nd, &dp->nfsdl_ace, &ret,
-			    &acesize, p);
+			error = nfsrv_dissectace(nd, &dp->nfsdl_ace, false,
+			    &ret, &acesize, p);
 			if (error != 0)
 				goto nfsmout;
 		} else if (deleg != NFSV4OPEN_DELEGATENONE) {
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 9d1fbfe5801a..d63a788177b0 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -2993,8 +2993,8 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap,
 			attrsum += NFSX_HYPER;
 			break;
 		case NFSATTRBIT_ACL:
-			error = nfsrv_dissectacl(nd, aclp, &aceerr, &aclsize,
-			    p);
+			error = nfsrv_dissectacl(nd, aclp, true, &aceerr,
+			    &aclsize, p);
 			if (error)
 				goto nfsmout;
 			if (aceerr && !nd->nd_repstat)