fs/nfsd/nfs4proc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
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>
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>
© 2016 - 2026 Red Hat, Inc.