Skip to contentSkip to conversation

NFSD: map fh_verify() status codes for NFS_ACLv2 replies

PATCH New Chuck Lever 1 participant 2 messages Sep 16

Subsystems (2)
lore
Share & tools
lore

Chuck Lever

author maintainer
#0 lore raw

PATCH 1/2 NFSD: map fh_verify() status codes for NFS_ACLv2 replies

The NFS_ACL v2 protocol shares its status code space with NFSv2, which has no NFSERR_BADHANDLE and no NFSERR_NOFILEHANDLE. An NFS_ACLv2 GETACL, SETACL, GETATTR, or ACCESS request that carries a malformed or empty file handle gets a reply with status 10001 or 10020, values the client cannot interpret.

Commit 1459ad57673b ("nfsd: Move error code mapping to per-version proc code.") removed the version check from fh_verify() that turned those codes into NFSERR_STALE for any version 2 program. The NFSv2 procedures gained nfsd_map_status() in exchange, but the NFS_ACL v2 procedures did not, so the unmapped status reaches the encoder.

Add the same mapping to the NFS_ACL v2 procedures.

Fixes 1459ad57673b ("nfsd: Move error code mapping to per-version proc code.")
---
 fs/nfsd/nfs2acl.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
fs/nfsd/nfs2acl.c +18 -0
index 0a5c444fef99..0673e83b6666 100644
@@ -59,6 +59,20 @@ static const struct nfsd_access_maps nfsd2_access_maps = {
 	.other		= nfsd2_otheraccess,
 };
 
+static __be32 nfsacld_map_status(__be32 status)
+{
+	switch (status) {
+	case nfserr_nofilehandle:
+	case nfserr_badhandle:
+		status = nfserr_stale;
+		break;
+	case nfserr_wrongsec:
+		status = nfserr_acces;
+		break;
+	}
+	return status;
+}
+
 /*
  * NULL call.
  */
@@ -123,6 +137,7 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst *rqstp)
 
 	/* resp->acl_{access,default} are released in nfssvc_release_getacl. */
 out:
+	resp->status = nfsacld_map_status(resp->status);
 	return rpc_success;
 
 fail:
@@ -181,6 +196,7 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp)
 
 out:
 	/* argp->acl_{access,default} are released in nfsaclsvc_release_setacl. */
+	resp->status = nfsacld_map_status(resp->status);
 	return rpc_success;
 
 out_drop_lock:
@@ -207,6 +223,7 @@ static __be32 nfsacld_proc_getattr(struct svc_rqst *rqstp)
 		goto out;
 	resp->status = fh_getattr(&resp->fh, &resp->stat);
 out:
+	resp->status = nfsacld_map_status(resp->status);
 	return rpc_success;
 }
 
@@ -231,6 +248,7 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)
 		goto out;
 	resp->status = fh_getattr(&resp->fh, &resp->stat);
 out:
+	resp->status = nfsacld_map_status(resp->status);
 	return rpc_success;
 }
 
Signature · 1 line
2.55.0
author maintainer
#1 lore raw

PATCH 2/2 NFSD: map fh_verify() status codes for NFS_ACLv3 replies

The NFS_ACLv3 protocol shares its status code space with NFSv3, which has NFS3ERR_BADHANDLE but no NFSERR_NOFILEHANDLE. An NFS_ACLv3 GETACL or SETACL request that carries an empty file handle gets a reply with status 10020, a value the client cannot interpret.

Commit 1459ad57673b ("nfsd: Move error code mapping to per-version proc code.") made fh_verify() return nfserr_nofilehandle for an empty handle regardless of protocol version. The NFSv3 procedures gained nfsd3_map_status() in exchange, but the NFS_ACLv3 procedures did not, so the unmapped status reaches the encoder.

Add the same mapping to the NFS_ACLv3 procedures.

Fixes 1459ad57673b ("nfsd: Move error code mapping to per-version proc code.")
---
 fs/nfsd/nfs3acl.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
fs/nfsd/nfs3acl.c +15 -0
index 7183995182ab..5219ec634587 100644
@@ -14,6 +14,19 @@
 #include "xdr3.h"
 #include "vfs.h"
 
+static __be32 nfsd3_map_status(__be32 status)
+{
+	switch (status) {
+	case nfserr_nofilehandle:
+		status = nfserr_badhandle;
+		break;
+	case nfserr_wrongsec:
+		status = nfserr_acces;
+		break;
+	}
+	return status;
+}
+
 /*
  * NULL call.
  */
@@ -72,6 +85,7 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst *rqstp)
 
 	/* resp->acl_{access,default} are released in nfs3svc_release_getacl. */
 out:
+	resp->status = nfsd3_map_status(resp->status);
 	return rpc_success;
 
 fail:
@@ -125,6 +139,7 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp)
 	resp->status = nfserrno(error);
 out:
 	/* argp->acl_{access,default} are released in nfs3svc_release_setacl. */
+	resp->status = nfsd3_map_status(resp->status);
 	return rpc_success;
 }
 
Signature · 1 line
2.55.0