FAILED: patch "[PATCH] nfsd: fix stale s2s_cp_stateids IDR entry for async COPY" failed to apply to 6.12-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x d0beaee498e11880e72826026db0e9c9890fc114
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090320-purple-stiffness-b344@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d0beaee498e11880e72826026db0e9c9890fc114 Mon Sep 17 00:00:00 2001
From: Jeff Layton <[email protected]>
Date: Fri, 10 Jul 2026 10:00:07 -0400
Subject: [PATCH] nfsd: fix stale s2s_cp_stateids IDR entry for async COPY
For an async COPY, nfsd4_copy() called nfs4_init_copy_state() before dup_copy_fields(), so the s2s_cp_stateids IDR was pointed at &u->copy->cp_stateid -- memory in the per-rqstp COMPOUND buffer that is reused by the next request. dup_copy_fields() copies only the value into async_copy, so the IDR slot dangled at the transient buffer for the whole background copy. Any IDR walker then dereferences reused request memory:
the laundromat reads cs_type from it and, if the bytes look like an expired NFS4_COPYNOTIFY_STID, follows into refcount_dec()/idr_remove()/kfree() on garbage; manage_cpntf_state() has the same exposure via idr_find().
Duplicate the fields first, then register the stateid on the stable async_copy. result->cb_stateid is unchanged.
fs/nfsd/nfs4proc.c +5 -4
@@ -2237,11 +2237,12 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, async_copy->cp_src =kmalloc_obj (*async_copy->cp_src);if (!async_copy->cp_src) goto out_dec_async_copy_err; -if (!nfs4_init_copy_state (nn, copy)) - goto out_dec_async_copy_err; -memcpy (&result->cb_stateid, ©->cp_stateid.cs_stid, -sizeof (result->cb_stateid));dup_copy_fields (copy, async_copy); + +if (!nfs4_init_copy_state (nn, async_copy)) + goto out_dec_async_copy_err; +memcpy (&result->cb_stateid, &async_copy->cp_stateid.cs_stid, +sizeof (result->cb_stateid));if ((READ_ONCE (copy->nf_dst->nf_file->f_mode) &FMODE_NOCMTIME ) !=0 ) async_copy->attr_update = true;
Sasha Levin
maintainerPATCH 1/2 nfsd: update mtime/ctime on COPY in presence of delegated attributes
From: Olga Kornievskaia <[email protected]>
[ Upstream commit 4183cf383b6faec17a0882b84cd2d901dba62b16 ]
When delegated attributes are given on open, the file is opened with NOCMTIME and modifying operations do not update mtime/ctime as to not get out-of-sync with the client's delegated view. However, for COPY operation, the server should update its view of mtime/ctime and reflect that in any GETATTR queries.
[ Stable adaptation: Linux 6.12 does not contain the Fixes commit or nfsd_update_cmtime_attr(), so omit the timestamp-update call sites. Keep the attr_update context needed by d0beaee498e1 ("nfsd: fix stale s2s_cp_stateids IDR entry for async COPY"), and alias its newer error label to the existing 6.12 cleanup path. ]
Stable-dep-of: d0beaee498e1 ("nfsd: fix stale s2s_cp_stateids IDR entry for async COPY")
--- fs/nfsd/nfs4proc.c | 8 ++++++-- fs/nfsd/xdr4.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)
fs/nfsd/nfs4proc.c +6 -2
@@ -1853,12 +1853,15 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out_err; async_copy->cp_src =kmalloc (sizeof (*async_copy->cp_src),GFP_KERNEL );if (!async_copy->cp_src) - goto out_err; + goto out_dec_async_copy_err;if (!nfs4_init_copy_state (nn, copy)) - goto out_err; + goto out_dec_async_copy_err;memcpy (&result->cb_stateid, ©->cp_stateid.cs_stid,sizeof (result->cb_stateid));dup_copy_fields (copy, async_copy); +if ((READ_ONCE (copy->nf_dst->nf_file->f_mode) & +FMODE_NOCMTIME ) !=0 ) + async_copy->attr_update = true; async_copy->copy_task =kthread_create (nfsd4_do_async_copy, async_copy,"%s" ,"copy thread" );if (IS_ERR (async_copy->copy_task))
@@ -1877,6 +1880,7 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,trace_nfsd_copy_done (copy, status);release_copy_files (copy);return status; +out_dec_async_copy_err: out_err:if (nfsd4_ssc_is_inter (copy)) {/*
fs/nfsd/xdr4.h +1 -0
@@ -736,6 +736,7 @@ struct nfsd4_copy {struct nfsd_file *nf_src;struct nfsd_file *nf_dst; +bool attr_update;copy_stateid_t cp_stateid;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 nfsd: fix stale s2s_cp_stateids IDR entry for async COPY
From: Jeff Layton <[email protected]>
[ Upstream commit d0beaee498e11880e72826026db0e9c9890fc114 ]
For an async COPY, nfsd4_copy() called nfs4_init_copy_state() before dup_copy_fields(), so the s2s_cp_stateids IDR was pointed at &u->copy->cp_stateid -- memory in the per-rqstp COMPOUND buffer that is reused by the next request. dup_copy_fields() copies only the value into async_copy, so the IDR slot dangled at the transient buffer for the whole background copy. Any IDR walker then dereferences reused request memory:
the laundromat reads cs_type from it and, if the bytes look like an expired NFS4_COPYNOTIFY_STID, follows into refcount_dec()/idr_remove()/kfree() on garbage; manage_cpntf_state() has the same exposure via idr_find().
Duplicate the fields first, then register the stateid on the stable async_copy. result->cb_stateid is unchanged.
--- fs/nfsd/nfs4proc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/nfsd/nfs4proc.c +4 -3
@@ -1854,11 +1854,12 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, async_copy->cp_src =kmalloc (sizeof (*async_copy->cp_src),GFP_KERNEL );if (!async_copy->cp_src) goto out_dec_async_copy_err; -if (!nfs4_init_copy_state (nn, copy)) +dup_copy_fields (copy, async_copy); + +if (!nfs4_init_copy_state (nn, async_copy)) goto out_dec_async_copy_err; -memcpy (&result->cb_stateid, ©->cp_stateid.cs_stid, +memcpy (&result->cb_stateid, &async_copy->cp_stateid.cs_stid,sizeof (result->cb_stateid)); -dup_copy_fields (copy, async_copy);if ((READ_ONCE (copy->nf_dst->nf_file->f_mode) &FMODE_NOCMTIME ) !=0 ) async_copy->attr_update = true;
Signature · 1 line
2.53.0