[PATCH] nfsd: fix posix_acl leak and ignored error in nfsd4_create_file

Jeff Layton posted 1 patch 3 days, 3 hours ago
fs/nfsd/nfs4proc.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
[PATCH] nfsd: fix posix_acl leak and ignored error in nfsd4_create_file
Posted by Jeff Layton 3 days, 3 hours ago
nfsd4_create_file() has two bugs in its ACL handling:

The return value of nfsd4_acl_to_attr() is silently discarded.  When
the NFSv4-to-POSIX ACL conversion fails (e.g., -EINVAL for
unsupported ACE types), the file is created without any ACL and the
client receives NFS4_OK.  This violates RFC 7530/8881 which require
the server to reject unsupported attributes on CREATE.

When start_creating() fails after ACL attributes have been populated
in attrs (either via nfsd4_acl_to_attr or via ownership transfer from
open->op_dpacl/op_pacl), the function jumps to out_write which skips
nfsd_attrs_free().  The posix_acl allocations are leaked.  A client
can trigger this repeatedly with OPEN(CREATE), ACL attributes, and an
invalid filename (e.g., longer than NAME_MAX).

Fix both by capturing the nfsd4_acl_to_attr() return value and by
changing the early error paths to jump to out instead of out_write.
Initialize child to ERR_PTR(-EINVAL) so that end_creating() is safe
to call even if start_creating() was never reached.

Fixes: 7ab96df840e6 ("VFS/nfsd/cachefiles/ovl: add start_creating() and end_creating()")
Reported-by: Chris Mason <clm@meta.com>
Assisted-by: kres:claude-opus-4-6
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/nfsd/nfs4proc.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 85e94c30285a..c82f7c1a3cc8 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -253,7 +253,7 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
 		.na_iattr	= iap,
 		.na_seclabel	= &open->op_label,
 	};
-	struct dentry *parent, *child;
+	struct dentry *parent, *child = ERR_PTR(-EINVAL);
 	__u32 v_mtime, v_atime;
 	struct inode *inode;
 	__be32 status;
@@ -277,10 +277,14 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
 	if (open->op_acl) {
 		if (open->op_dpacl || open->op_pacl) {
 			status = nfserr_inval;
-			goto out_write;
+			goto out;
+		}
+		if (is_create_with_attrs(open)) {
+			status = nfsd4_acl_to_attr(NF4REG, open->op_acl,
+						   &attrs);
+			if (status)
+				goto out;
 		}
-		if (is_create_with_attrs(open))
-			nfsd4_acl_to_attr(NF4REG, open->op_acl, &attrs);
 	} else if (is_create_with_attrs(open)) {
 		/* The dpacl and pacl will get released by nfsd_attrs_free(). */
 		attrs.na_dpacl = open->op_dpacl;
@@ -293,7 +297,7 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
 			       &QSTR_LEN(open->op_fname, open->op_fnamelen));
 	if (IS_ERR(child)) {
 		status = nfserrno(PTR_ERR(child));
-		goto out_write;
+		goto out;
 	}
 
 	if (d_really_is_negative(child)) {
@@ -407,7 +411,6 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
 out:
 	end_creating(child);
 	nfsd_attrs_free(&attrs);
-out_write:
 	fh_drop_write(fhp);
 	return status;
 }

---
base-commit: 910a469edfa98eb15e2a5f7d5f668d19da7b2e6a
change-id: 20260521-nfsd4_create_file_leaks_attrs_on_start_creating_err-a0ae727d7e8f

Best regards,
-- 
Jeff Layton <jlayton@kernel.org>
Re: [PATCH] nfsd: fix posix_acl leak and ignored error in nfsd4_create_file
Posted by Chuck Lever 2 days, 23 hours ago
From: Chuck Lever <chuck.lever@oracle.com>

On Thu, 21 May 2026 12:37:33 -0400, Jeff Layton wrote:
> nfsd4_create_file() has two bugs in its ACL handling:
> 
> The return value of nfsd4_acl_to_attr() is silently discarded.  When
> the NFSv4-to-POSIX ACL conversion fails (e.g., -EINVAL for
> unsupported ACE types), the file is created without any ACL and the
> client receives NFS4_OK.  This violates RFC 7530/8881 which require
> the server to reject unsupported attributes on CREATE.
> 
> [...]

Applied to nfsd-testing, thanks!

[1/1] nfsd: fix posix_acl leak and ignored error in nfsd4_create_file
      commit: 15906201636c0850eff0e2e86791f24e007d4160

--
Chuck Lever <chuck.lever@oracle.com>