[PATCH v1 09/17] Fix a couple of bugs in POSIX ACL decoding

rick.macklem
2025-12-31T02:22:24Z

1 - Handle the case where the who is of zero length for
ACL_USER or ACL_GROUP.
2 - Correctly calculate the minimum XDR size of the ACL.

Signed-off-by: Rick Macklem <rmacklem@uoguelph.ca>
---
fs/nfsd/nfs4xdr.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1a6ed0836c40..60197963c854 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -434,12 +434,18 @@ nfsd4_decode_posixace4(struct nfsd4_compoundargs *argp,
return nfserr_bad_xdr;
switch(ace->e_tag) {
case ACL_USER:
- status = nfsd_map_name_to_uid(argp->rqstp,
- (char *)p, val, &ace->e_uid);
+ if (val > 0)
+ status = nfsd_map_name_to_uid(argp->rqstp,
+ (char *)p, val, &ace->e_uid);
+ else
+ status = nfserr_bad_xdr;
break;
case ACL_GROUP:
- status = nfsd_map_name_to_gid(argp->rqstp,
- (char *)p, val, &ace->e_gid);
+ if (val > 0)
+ status = nfsd_map_name_to_gid(argp->rqstp,
+ (char *)p, val, &ace->e_gid);
+ else
+ status = nfserr_bad_xdr;
}

return status;
@@ -455,13 +461,13 @@ nfsd4_decode_posix_acl(struct nfsd4_compoundargs *argp, struct posix_acl **acl)
if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
return nfserr_bad_xdr;

- if (count > xdr_stream_remaining(argp->xdr) / 16)
+ if (count > xdr_stream_remaining(argp->xdr) / (3 * XDR_UNIT))
/*
- * Even with 4-byte names there wouldn't be
+ * Even with 0-byte who strings there wouldn't be
* space for that many aces; something fishy is
* going on:
*/
- return nfserr_fbig;
+ return nfserr_bad_xdr;

*acl = posix_acl_alloc(count, GFP_NOFS);
if (*acl == NULL)
--
2.49.0