From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5DE6F3672BE; Thu, 28 May 2026 21:55:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005328; cv=none; b=UM1S5bkoi9BeWN6WuQVe7T7cK9b78oP7r9CrDMzvduub8pVb8bnkKqcxpH2X4qlxdF302ZSWxrSPYb2miTMn2giu8V12XcawpZIkI1vh7uvEbNrnRSiVBSyvVQ0ESJe4hchI0JM1Ex5SU0SpRGiGVY5EHbMMs7UGSVjvvuNtBrk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005328; c=relaxed/simple; bh=cX9C/qVyQU8pvqlAUJU6eoyurocysZu5TAs9BRPfrRA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kWGYsHwqc2LfbaC/n1xSyJKqv63Vl3riwje985niGjKIKqc7CCkIUP/xGSt4YGH1lZkKTtj0D5gMNbKzqkpDvYTDGj9fGjaU21dK4pIPfqlhitY1yhdA8TOrFPm5BxnuPrIsTL0mnUCSRwoMeWdeDX3Pp6po4QEaJkW3/GVUJG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JqP9WU9Y; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JqP9WU9Y" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EBCC41F000E9; Thu, 28 May 2026 21:55:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005327; bh=LPLNwfji0HPhNzNdQtvJ/50kq50rLrKE1Be8JnkY63g=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=JqP9WU9Y5kdfa6RGlatFinXE09612BbivgX6AWepeUr71ETKwx1PFVmuO8QHx78IV SWYEEsYS1tectnBwkp7tOYQxvElZzQ/ZhFdrfh7Mz0IaIoYikazJtWXVTWeqR9EKzE zMizq4XpJtel6j/pjjQsyJsaueG8qgi0Iy5tTeVDmrgjauIAvjNvDo27AyREFintmY ZnlzL3+v/e5Jj0PO1GEC4tam/z+QgTdFCsREiFYt6XV3Z5dpX8AUKLMS7aT3H2mkuM OWaREMKwFgjNx2WWh6UXUV5za+e1fVdCehQHxwXUB1Oyl52czBC86N10QdcfgAXa7X YXTMoFmE/8Ecg== From: Jeff Layton Date: Thu, 28 May 2026 17:55:12 -0400 Subject: [PATCH 01/10] nfsd: fix BUG_ON in nfsd4_alloc_layout_stateid on racing delegation revoke Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-1-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1838; i=jlayton@kernel.org; h=from:subject:message-id; bh=cX9C/qVyQU8pvqlAUJU6eoyurocysZu5TAs9BRPfrRA=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnJMxZdUpKbZD69svgy6FKF7BxP7SPSuaRF+ IrEY1zUHQOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5yQAKCRAADmhBGVaC FcCHD/0dhxKO14VGazK5MQTth84tAg4nOadzgPfe/hSDYfFNvQh7Ps/iBFCHjZ6X+KFV1PAeRiv q87sjv3WxlchTRzMgmOMl1xzxdoxyC6aBOxWECSdbLKoUONXImujMH93YFm0LKF/jPsM5X5/pHP P9cL7YPkn+oPiAOhI3lLFLUAGfGg5v7GO6lP4WdjdE8p0e0CdrceWd6I4Ugrjcc31LezGG21SMA /hrZ1ZSKGgHzg8TvXWfe0IWz27I5NeKE7o45AjFplJ1E47ranboRqmB0IwHPq+5OJx0hxQ0SVNg k7399hRLC+Q50ZbwaT2z5ZDS0Qsjflx7vSh08MMlb8twXcJfSnchBK32KyUSB5GFPCgA/m8z7SD e85sqwwHaAXnr6DI96XP876Uk9ROhzaZJHWmZXc/+Lugdf0l77Y0u4Fi6T/PjzWxpWFtkRnTzL6 Ru6OueYYct4q8aF4LrTJvcXgSV7MTkHsaV9gfLyzQQZfIeKKJEtyjHcMzLmx3xFOtS7CgsupRxZ B+A/Q+0QORRmXjQa9S+SQowajSUxKMRVoSUJ1mgCT/GXLys2y2cPw49z2E5ki8TVmytqmpGrcW1 9rReBVCoOjDMZM1D1i/eX9ytZSRIloC2IiswVW3ldAWH1PwBwYkc1bcGivQp7y06hHOtyd+0lvY x843d49M5qjJLFw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 nfsd4_alloc_layout_stateid reads fp->fi_deleg_file without holding fi_lock when the parent stateid is a delegation. A concurrent delegation revoke via the laundromat can clear fi_deleg_file under fi_lock, causing nfsd_file_get() to return NULL and triggering the BUG_ON. This race is client-reachable: two NFS clients can trigger it by having one hold a delegation while another opens the same file to force a recall. When the first client doesn't respond to the recall, the laundromat revokes it. A concurrent LAYOUTGET from any client using the delegation stateid hits the race window. Fix this by taking fi_lock around the fi_deleg_file read in the SC_TYPE_DELEG path, and replacing the BUG_ON with a graceful error return that cleans up the partially-initialized layout stateid. Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Jeff Layton --- fs/nfsd/nfs4layouts.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 9ed2e3d65062..5d48c7673fa1 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -247,11 +247,17 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_stat= e *cstate, nfsd4_init_cb(&ls->ls_recall, clp, &nfsd4_cb_layout_ops, NFSPROC4_CLNT_CB_LAYOUT); =20 - if (parent->sc_type =3D=3D SC_TYPE_DELEG) + if (parent->sc_type =3D=3D SC_TYPE_DELEG) { + spin_lock(&fp->fi_lock); ls->ls_file =3D nfsd_file_get(rcu_dereference_protected(fp->fi_deleg_fil= e, 1)); - else + spin_unlock(&fp->fi_lock); + } else { ls->ls_file =3D find_any_file(fp); - BUG_ON(!ls->ls_file); + } + if (!ls->ls_file) { + nfs4_put_stid(stp); + return NULL; + } =20 ls->ls_fenced =3D false; ls->ls_fence_delay =3D 0; --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D10AF3655C4; Thu, 28 May 2026 21:55:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005332; cv=none; b=YE0OOsd+SMGsEmiH38BndA6slEyj5F28qrZCkeeiPpETk7xOG+HbMoBbhSij7x51DE2jV9PLcqlGgCheeCIFCOWhIq+XQYtdzMBMr8n1cjrOY1ZAR/3TpT8r+/wO5UIjlGrNkQJG0MDUqtlZFgUbAXR7en1v8sMf/x8RxbjzsyE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005332; c=relaxed/simple; bh=+1egxb1h4y2B2aNDpEQu+OZaOf0TQfGCXOYKnLxQ5lU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WV4b7YT8v207bVrT2XOLFG4dR5jaSmMgXdUpoewUWZSutYBAM0DSM61KulR5rWG9rP0veKxNPF/ZyAsRrow2YjNppXEAXwy6QlWqRPB/L29IemoP/+Ss7Hpp0n+vI3lpCV/AySNuhqVgRQXc9NoZkbr+6bpj3sYHWmry38bHXYc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DoVLVc4E; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DoVLVc4E" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 753AF1F00ACA; Thu, 28 May 2026 21:55:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005328; bh=J/z8Oz1VKieRRTsML+iXe4muZfZGdxmLjJ0FZi/X4wc=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=DoVLVc4EnDRqTU1RJe7XrjR/aEiDbzy71BC/pJlAHzonK5B0+aBE/aokd4ccDsjR3 ZMkD/flx+5DmTy7obNt3kT0FGfjdZnzwzC7u1gvPv/+/KNWwYKb0MYebBXIS0husnR hCfz+y0kvfLS9XKcDHFbNdrmyDLHtipQHC7cqdUcRzxwlRVT7XfBJ8U9hJXYbK8q9a s1+0F5N+Ai4PAjoSJfUW/KDS9Wp79GETKAIhD74jcdPb6TMuGyyy9mnZMSbn0D+g1x tL8oninox0aSwU9TIspSx+Mex1OZG5ZPeWdIy1+C+VvX4m72/z0D2x2KdLyq3boHQH 7mPry8Eq5KwMg== From: Jeff Layton Date: Thu, 28 May 2026 17:55:13 -0400 Subject: [PATCH 02/10] nfsd: drain callbacks and clear cl_cb_session Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-2-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5832; i=jlayton@kernel.org; h=from:subject:message-id; bh=9ZUym2wgilGmSwTI4ZQgv6cu3Cq2Hj2EPxdd/eLxtLQ=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnKm7OkdNAxVZlJQoYqRbptggne280lxckVQ sjczEGHsl+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5ygAKCRAADmhBGVaC FXkxD/wPTHJYpCfR4XF/8j6hpJkn/3FdisO3EkmMMn4twCXomfe5BIpj/PoHnOU4P7cCuxIeyca xiSKhzOE/QActMBcdqnVhaMXe9ENfOwoZAGaHSYO4QcPU8vVv7bTYf5jgY+Fs7WtkkL56mt4uKg 3YtA/9gMNAgkZlVPsTDodrumqJgHjvDzW7Uzki0K0S2Jfp75FewJOc8oUzF6m+qjge7FNorLIEs 5Eq/tQbNp1fSGUmus6lkt004VDBEbegKyiMsUGei4sD9EvLXiW6izOVYLa2oclcpJZU7vFPV7kP 5u8G8YI5G1EfloWN4O0EEzjauwFSGnWTQJCM/TFAUmv02Wjy7wzcJvpDMSh8mdCBDXz2SJQa8UT g3RE+IPESc/KxLMULRIieCjogSDvETkZR5jQLjY5D+KSPaQrTXHV2PJsFwJpfsyGT2zbCQA5pjq HgqhuG/iZKR6Gt4rsF+ASYvwX1w8vVrXaakk0tPu1KaKFpMBKxzoOdiNYmPhuGj3zdP6yGE4Afd YZ7pYg2wy80UvUyktYhyjVUz6BW83wU/3F9+SobvpTmOW5uL5XObM397i/8rgD6140Yg1PAEhr6 HCz9Symbbrd6ae2seDbticCh401uqA2+gi24is2rGITrphTZYnzRRs4sdiyYlZ3ASSygMMCrMjd TAQgpXy97MSKq9g== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason After a DESTROY_SESSION the per-session teardown path can free a session while rpciod still holds an inflight callback rpc_task that dereferences clp->cl_cb_session. nfsd4_probe_callback_sync() flushes cl_callback_wq, but once nfsd4_run_cb_work() has called rpc_call_async() the rpc_task lives on rpciod; flushing the workqueue does not wait for it. After the flush returns, nfsd4_destroy_session() proceeds through nfsd4_put_session_locked() and free_session() kfree()s the slab while rpciod's nfsd4_cb_sequence_done(), grab_slot(), and nfsd41_cb_release_slot() are still dereferencing cb->cb_clp->cl_cb_session. destroy path rpciod ------------ ------ unhash_session(ses) nfsd4_probe_callback_sync(clp) flush_workqueue(cl_callback_wq) /* returns; rpc_task still live */ nfsd4_put_session_locked(ses) free_session(ses) -> kfree(ses) nfsd4_cb_sequence_done() reads cb_clp->cl_cb_session /* freed slab */ A second window exists in nfsd4_process_cb_update(). When __nfsd4_find_backchannel() returns NULL because unhash_session() has already removed the destroyed session from cl_sessions, setup_callback_client() takes the v4.1 early return if (!conn->cb_xprt || !ses) return -EINVAL; so clp->cl_cb_session =3D ses never fires and the field retains a pointer to the about-to-be-freed session. Symmetrically, if a later probe finds a different session's backchannel conn and that setup_callback_client() call fails, the error tail must still scrub any previously published cl_cb_session. Fix by mirroring the two-stage drain that nfsd4_shutdown_callback() already performs: call nfsd41_cb_inflight_wait_complete() in nfsd4_probe_callback_sync() after flush_workqueue() so rpciod-side nfsd41_cb_inflight_end() decrements are observed before the caller releases the final session reference. The two direct callers, nfsd4_destroy_session() and nfsd4_init_conn() (itself invoked from nfsd4_create_session() and nfsd4_bind_conn_to_session()), run in sleepable process context and tolerate the wait_var_event() sleep: nfsd4_destroy_session() (fs/nfsd/nfs4state.c): unhash_session(ses); spin_unlock(&nn->client_lock); /* spinlock dropped */ nfsd4_probe_callback_sync(ses->se_client); nfsd4_init_conn() (fs/nfsd/nfs4state.c): acquires no locks in its body; calls nfsd4_hash_conn(), nfsd4_register_conn(), then nfsd4_probe_callback_sync() -- entirely in sleepable process context. Also clear clp->cl_cb_session unconditionally on the nfsd4_process_cb_update() error return so every setup_callback_client() failure -- whether c is NULL or points at a different session whose probe failed -- leaves the field NULL rather than pointing at a session that may subsequently be freed. Fixes: dcbeaa68dbbd ("nfsd4: allow backchannel recovery") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfsd/nfs4callback.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 1964a213f80e..1cf6b6100357 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -1205,9 +1205,8 @@ static int setup_callback_client(struct nfs4_client *= clp, struct nfs4_cb_conn *c } else { if (!conn->cb_xprt || !ses) return -EINVAL; - clp->cl_cb_session =3D ses; args.bc_xprt =3D conn->cb_xprt; - args.prognumber =3D clp->cl_cb_session->se_cb_prog; + args.prognumber =3D ses->se_cb_prog; args.protocol =3D conn->cb_xprt->xpt_class->xcl_ident | XPRT_TRANSPORT_BC; args.authflavor =3D ses->se_cb_sec.flavor; @@ -1225,8 +1224,10 @@ static int setup_callback_client(struct nfs4_client = *clp, struct nfs4_cb_conn *c return -ENOMEM; } =20 - if (clp->cl_minorversion !=3D 0) + if (clp->cl_minorversion !=3D 0) { clp->cl_cb_conn.cb_xprt =3D conn->cb_xprt; + clp->cl_cb_session =3D ses; + } clp->cl_cb_client =3D client; clp->cl_cb_cred =3D cred; rcu_read_lock(); @@ -1299,6 +1300,7 @@ void nfsd4_probe_callback_sync(struct nfs4_client *cl= p) { nfsd4_probe_callback(clp); flush_workqueue(clp->cl_callback_wq); + nfsd41_cb_inflight_wait_complete(clp); } =20 void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *c= onn) @@ -1679,7 +1681,17 @@ static struct nfsd4_conn * __nfsd4_find_backchannel(= struct nfs4_client *clp) * Note there isn't a lot of locking in this code; instead we depend on * the fact that it is run from clp->cl_callback_wq, which won't run two * work items at once. So, for example, clp->cl_callback_wq handles all - * access of cl_cb_client and all calls to rpc_create or rpc_shutdown_clie= nt. + * access of cl_cb_client and cl_cb_session, and all calls to rpc_create + * or rpc_shutdown_client. + * + * rpciod-side readers of cl_cb_session (encode_cb_sequence4args(), + * nfsd4_cb_sequence_done(), the cb-slot helpers, and the cb_sequence + * tracepoints) run outside cl_callback_wq. The + * nfsd41_cb_inflight_wait_complete() drain in nfsd4_probe_callback_sync() + * waits until cl_cb_inflight reaches zero before the caller proceeds with + * session teardown; any rpc_task that reads cl_cb_session must hold an + * inflight pin (via nfsd41_cb_inflight_begin) for this fence to be + * effective. */ static void nfsd4_process_cb_update(struct nfsd4_callback *cb) { @@ -1731,6 +1743,7 @@ static void nfsd4_process_cb_update(struct nfsd4_call= back *cb) nfsd4_mark_cb_down(clp); if (c) svc_xprt_put(c->cn_xprt); + clp->cl_cb_session =3D NULL; return; } } --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0CAF73644A4; Thu, 28 May 2026 21:55:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005333; cv=none; b=TpjlUy0njWRa9TzQsW8xwi5fYTLdXRTifusxRI+1RgVZrWYgpfHhS1AyWZIo4SYb8OLCmMqxyttY45IeDA2ou10AV4e2+KCdTy66Nv48HNepW+uPwZSaB8BsssDRE6d3jarG/4Y+ZBYpi5cs7hz/RKsTLINPwrYhjddvObzBn8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005333; c=relaxed/simple; bh=bPsFkrpRs6hSWic3IFxHIrBk5YaT5H9qSNCV2LZkyhs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EvoAmdM2lm8Zj+ASmaIDlo3epwCujkuZmcj+P75CJHU9ZrBvBJ4zgDnkKL4QRRUuuAcKyXcUhe/W/0EUppBhxMgo8Ky6EKyFJQmcktPyBKhpCOZzS3G2zCh8mt192MkT3DoLWpk3UpJgWYZ8zOD+PTWS9+GU70hZSfZ1az9Jhvc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XhoayxJY; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XhoayxJY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F35111F00A3C; Thu, 28 May 2026 21:55:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005330; bh=lPROnSbjSsIPlcTzwf+m0DG24gbchZyKCSA4wNPEkEU=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=XhoayxJYWvjNzFDj1RrPUMhTIN3i6kF0kneyF9a0xUaQisE4/hQpcWY1uHg4rPOmu sBrh06/Ho2TK7rfXimNWfm+lTzoaa+Z/GPHSlguOhAq4tiE9lIk4x7ianIY7eft+72 hYX73iTnprPPHU68rEY3+nt0dnmSLrb5ttZhTMA+hKnlHJdRRVV2hNRnqgo3/L8deK NqR6L4QLmlEfwcQ3xn/5ocYUFULu9MQS44Cw/ljXXE55FkGiJ/RCqG2RzoTvOrGO/L d9OwCosqJZ1+iCLiWjIYtzQlyNvTb9mQYudLW2MqoaekmtknEGEczjtYo3E24uoNAe Bn1vgY9UFUURg== From: Jeff Layton Date: Thu, 28 May 2026 17:55:14 -0400 Subject: [PATCH 03/10] nfsd: serialize nfsd4_end_grace() with atomic test-and-set Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-3-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3295; i=jlayton@kernel.org; h=from:subject:message-id; bh=30FTxhGBSIxdJftpkF72BilKDBsAuHh6QS6iR1DtDR0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnKT1M8rClrrM6loRWP9OpKfa0KdwujZm9uO xMqS/z4JSSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5ygAKCRAADmhBGVaC FXTsD/9zgCjyhXFwqBjdcc/athv9WS3QVicB5KZD19rlPQtugNM7PjB85DdKmIzGaHFBaZJB6J/ Jr2S0TUk43SqZJ+6Np9I/oTivI6pNfyp7s90m+bvzNdGjslCy3OlzNyo/VbOfgEfA/NqQD9Ht8U 99I8KlJcfI0l1tgfPZyFsFBzukUL5xtww3LfnRyfkDz4y7kVwTruVaui6QvCpPEIwy1jFrPp8m2 0Ydq+LjW/S0dPKXeB9BUdqeXGoGfdAngCiqi4SeLDjvEDRut2wlfxzEJL97k5MOHvtbdTMZUOSn Kd74dO9+GcJ5gqvOsFKAYhkujbUoHSwTvegxgeVRGbJA22jyu21rGoIYNAZpDNDfo4aqpOyGn4K 5RjruGjPrBCb4tHZIVqih7uyqLKV2qa3aqEvnshQkFMzqE72yuhGuKZ/oZ7BxftfdV7bwVrKfQh +jbzuUow1jWKmzx1+280QcUUmzEJJXnBqGOCeB38KhYU0B2LBuLRovsbsmoOptejMZ/gu7DPxvV 5f+R8Lk43TlvNI3B4aUbcLPi7A4OibY2tqIG2Loq2028GFZnx81xtdEfbHjSB32Luwe3pBphBLX KSJ8TbQitLA1+TDb+R60jki58gV9olDwb2o5yQagtc+PdwvElF4qUpiqUxqQXt2hMab15MtmvN4 FuATUYISpzcSEbw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason nfsd4_end_grace() guards its drain path with a plain bool: if (nn->grace_ended) return; nn->grace_ended =3D true; The read and the write are independent, and nothing in struct nfsd_net serializes them. At least two contexts can reach this code with no lock held: laundromat path laundry_wq kworker nfs4_laundromat() nfsd4_end_grace() RECLAIM_COMPLETE path nfsd compound kthread nfsd4_reclaim_complete() inc_reclaim_complete() nfsd4_end_grace() Both callers can observe grace_ended =3D=3D false on different CPUs, both store true, and both proceed into nfsd4_record_grace_done(), which invokes the active client_tracking_ops->grace_done callback. For tracking ops that drain reclaim_str_hashtbl (legacy_tracking_ops via nfsd4_recdir_purge_old, and the cld v1+ ops via nfsd4_cld_grace_done), grace_done calls nfs4_release_reclaim(), which walks every bucket of reclaim_str_hashtbl with no lock and calls nfs4_remove_reclaim_record() (list_del + kfree) on each entry. Two concurrent walkers corrupt the list and double-free every nfs4_client_reclaim. A concurrent nfsd4_find_reclaim_client() iterating the same bucket reads through freed memory. A third call site exists in nfs4_state_start_net() on the skip_grace startup path, but it runs under nfsd_mutex before any client has connected and before the laundromat's first delayed work fires, so it cannot race with the two callers above. Fix by replacing the read/write pair with try_cmpxchg() so exactly one caller transitions grace_ended from false to true and proceeds into the drain; the loser returns immediately. bool supports 1-byte cmpxchg on all supported architectures, and no lock ordering changes are needed. Fixes: 362063a595be ("nfsd: keep a tally of RECLAIM_COMPLETE operations whe= n using nfsdcld") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfsd/nfs4state.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f4d12dbcf97b..dc4ac541436f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7022,12 +7022,23 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_co= mpound_state *cstate, static void nfsd4_end_grace(struct nfsd_net *nn) { - /* do nothing if grace period already ended */ - if (nn->grace_ended) + bool expected =3D false; + + /* + * nfsd4_end_grace() can be entered concurrently from the + * laundromat workqueue and from an nfsd compound thread + * handling RECLAIM_COMPLETE. Without serialization, both + * callers can observe grace_ended=3D=3Dfalse and proceed into + * nfsd4_record_grace_done(). For tracking ops whose + * grace_done drains reclaim_str_hashtbl, that results in + * list corruption and a double free of every + * nfs4_client_reclaim entry. Use an atomic test-and-set so + * exactly one caller proceeds. + */ + if (!try_cmpxchg(&nn->grace_ended, &expected, true)) return; =20 trace_nfsd_grace_complete(nn); - nn->grace_ended =3D true; /* * If the server goes down again right now, an NFSv4 * client will still be allowed to reclaim after it comes back up, --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0CB8B36493E; Thu, 28 May 2026 21:55:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005333; cv=none; b=PUlohuCmxDFSnbfx2UGJWXih0JoVcMr/vlrTLGOKdz4ZGZVZ4iimopus5pLSY0ACSJK3SNbK0dtZIT3sZOKrZ+ElHXM7f/vb1VFNmRsy9M6vGCQ/PkxIPIdtdLiLma3RTbmcY10lGRHam6toM47eUuQbZzZNzKQaMKXLxeBfdR0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005333; c=relaxed/simple; bh=NTxvBikEtOWE6eoBgtuqv2QDtEqrRU/9xyko/1B/ClQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=g0LIgHcGYuctHWsLwLGsaNecrNjjpuieji+cVLbaWe3ZneZCYAs6M71w9MfDDFlxWJMsoTkh3OadJx1KIPyBj2raMRUfmmwWTdNot8owdKOHkmX7f8aoikm5UyjJ8kvl4XWmCet+7fDeDDOBYPxRyBxWRq5zwj3TwpkZ8+s3SEs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dcvsohaE; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dcvsohaE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7C4641F00A3A; Thu, 28 May 2026 21:55:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005331; bh=dE1rjKPKQe+XjshW5SwZJ20tfVteIu00jKY4gIg77rk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=dcvsohaE9Xx/Oc+57UYR7kUrkEEcaHmBV8mz0zh+EYcvEIVaCpl+D1/E5xQFgO+GD LsMH+LbKeSqfS53WtrVPPxmFFSvEke+TXqQFRgJXCvlavuX+fGT0zgLr2HEUmOWJbv fRI+gSbYfPj6a8dzyg/3I1EqU7ysl1Y8pJM1KHrZeQvbCBpcnywY/mDhw3q/EO64SI bhHGYTyN6Kz4ctYgT9bFvB79DmdToErSmWFiCflWCBXzH8zuwU5d5BOt8S9FntrGmW fPWLf27WxYUeNgH+pUELkCqT61S3/FNdT0hsZH4H2/3u2ozV6BXpvxgx2rBRy+ijkO ZLpwaWazoAuUA== From: Jeff Layton Date: Thu, 28 May 2026 17:55:15 -0400 Subject: [PATCH 04/10] nfsd: dedup nfs4_client_to_reclaim inserts Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-4-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5436; i=jlayton@kernel.org; h=from:subject:message-id; bh=SoCWNwxU7epGWy7WggaAHHHC1Dyj0mj3LwA/2kXoKzk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnKXEL4+gmztbEaIk9X1hLy1jUTVqOFqIsfx eL+C2sgG+OJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5ygAKCRAADmhBGVaC FSrOD/9TDFAeKF1CCHcgEU2Z3+fjfRAdcIkYwTA1B1zFMOWGs2s0g8uDvSPef9hoyEWBotCO3rw KvGSeTgC0JP38u+wJy44oJzR1A0awHgS3coCN3Yg2g6mz5Q2huvPOe1w26lFAjvPo386YUnbYi5 2775Y8o6aIbKKqnNuMtAFjdOP5ii6NOvktRIwyaA7GShj8zQfMvjEuNfCHw9fVCdBab4rg0E88x Ane/UHLXqanJI/K+5TZbZzRLSEUq9EryV6X6JK/uLP1NG3RiIxgs7TGH4KL1qlDJlOAP8ykrO28 PGUu5R+BrPQO4/FciisC1XtCb/OprdJwm0JVoCI7JbF7fcRYTPWuUWEtV/JOPc4i1mQyH9dWIqj 45cv87n4ZVNid/LpqKCWHMgoOKuhuhnEyKPgzYaCGhoQrrshjfiNnnxYmh1sp9m7t78ghsTPXGI yGi9huwUXk/w1cgApnyFwlBAUXSs3L1OUUsCB+8lbG5HEKUBv8baPvHwhxxlSMLvjlqk2akorRQ OpLuyrSR4oicjcmhjLKvQh6EDPPKiKxu3NnYLZhNUVf4FEfG2yZrRBu5UpXHzwL3JsCYai3tG3g 7g5QgrljZlnyjGSv8Y7Y1R3tsFKTAZIUU1ThGouXJD1n0rvPAHt5I4dZgUpmi9DnXGKCPUcmK5G VyFS6gEHGCX/8AQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason nfs4_client_to_reclaim() unconditionally allocates a new nfs4_client_reclaim, prepends it to reclaim_str_hashtbl[], and bumps reclaim_str_hashtbl_size with no check for an existing entry for the same client name. After a reboot with a populated recovery directory that inflates the counter by one for every client that reclaims: boot: load_recdir() nfs4_client_to_reclaim(name) /* entry #1, size++ */ grace: RECLAIM_COMPLETE __nfsd4_create_reclaim_record_grace() nfs4_client_to_reclaim(name) /* entry #2, size++ */ inc_reclaim_complete() ends the grace period early only when atomic_inc_return(&nn->nr_reclaim_complete) =3D=3D nn->reclaim_str_hashtbl_size With reclaim_str_hashtbl_size at 2N and nr_reclaim_complete capped at N, the equality never holds and the fast end-of-grace path is dead. The grace period always runs out the full 90-second laundromat timer, and the shadow entry left in the hash table carries a dangling cr_clp for any reader that walks it. Fix nfs4_client_to_reclaim() to compute strhashval first, look the name up with nfsd4_find_reclaim_client(), and on a hit fold the new princhash into the existing record (if it lacks one) and return that record without allocating or touching reclaim_str_hashtbl_size. On kmemdup() failure during the fold-in, return NULL so __cld_pipe_inprogress_downcall() surfaces -EFAULT to nfsdcld, matching the miss-path contract. Because the fold-in writes cr_princhash.data and cr_princhash.len on a record that is already linked into reclaim_str_hashtbl[], pair the two stores with smp_store_release() on .len after WRITE_ONCE() on .data, and have nfsd4_cld_check_v2() read .len with smp_load_acquire() before READ_ONCE() on .data, so a concurrent principal-hash check cannot observe a torn (data, len) pair. Fixes: 362063a595be ("nfsd: keep a tally of RECLAIM_COMPLETE operations whe= n using nfsdcld") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfsd/nfs4recover.c | 16 +++++++++++++--- fs/nfsd/nfs4state.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 6ea25a52d2f4..f7905aa9fdce 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -1215,6 +1215,7 @@ nfsd4_cld_check_v2(struct nfs4_client *clp) struct cld_net *cn =3D nn->cld_net; #endif struct nfs4_client_reclaim *crp; + unsigned int princhashlen; char *principal =3D NULL; =20 /* did we already find that this client is stable? */ @@ -1249,8 +1250,17 @@ nfsd4_cld_check_v2(struct nfs4_client *clp) #endif return -ENOENT; found: - if (crp->cr_princhash.len) { + /* + * nfs4_client_to_reclaim() may fold a princhash into an + * already-listed reclaim record concurrently with this read. + * Pair with the smp_store_release() on cr_princhash.len there: + * if we observe a non-zero len we must also observe the + * matching .data pointer. + */ + princhashlen =3D smp_load_acquire(&crp->cr_princhash.len); + if (princhashlen) { u8 digest[SHA256_DIGEST_SIZE]; + u8 *pdata; =20 if (clp->cl_cred.cr_raw_principal) principal =3D clp->cl_cred.cr_raw_principal; @@ -1259,8 +1269,8 @@ nfsd4_cld_check_v2(struct nfs4_client *clp) if (principal =3D=3D NULL) return -ENOENT; sha256(principal, strlen(principal), digest); - if (memcmp(crp->cr_princhash.data, digest, - crp->cr_princhash.len)) + pdata =3D READ_ONCE(crp->cr_princhash.data); + if (memcmp(pdata, digest, princhashlen)) return -ENOENT; } crp->cr_clp =3D clp; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index dc4ac541436f..3709d0ebcd99 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9289,6 +9289,41 @@ nfs4_client_to_reclaim(struct xdr_netobj name, struc= t xdr_netobj princhash, unsigned int strhashval; struct nfs4_client_reclaim *crp; =20 + /* + * A reclaim record for this client name may already exist (for + * example, populated at boot from the recovery directory before + * an in-grace RECLAIM_COMPLETE or an nfsdcld downcall delivers + * the same name). Dedup here so reclaim_str_hashtbl_size stays + * equal to the number of distinct client names; inc_reclaim_complete + * relies on that equality to end the grace period via the fast path. + */ + crp =3D nfsd4_find_reclaim_client(name, nn); + if (crp) { + if (princhash.len && crp->cr_princhash.len =3D=3D 0) { + void *pdata =3D kmemdup(princhash.data, princhash.len, + GFP_KERNEL); + if (pdata) { + /* + * crp is already linked into reclaim_str_hashtbl[] + * and may be examined concurrently by + * nfsd4_cld_check_v2(). Publish .data before .len + * with release semantics so any reader that + * observes a non-zero len via the paired + * smp_load_acquire() also observes the new + * data pointer. + */ + WRITE_ONCE(crp->cr_princhash.data, pdata); + smp_store_release(&crp->cr_princhash.len, + princhash.len); + } else { + dprintk("%s: failed to allocate memory for princhash.data!\n", + __func__); + return NULL; + } + } + return crp; + } + name.data =3D kmemdup(name.data, name.len, GFP_KERNEL); if (!name.data) { dprintk("%s: failed to allocate memory for name.data!\n", --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B9B8364022; Thu, 28 May 2026 21:55:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005334; cv=none; b=SshIDKYkggbR1NrCjweaaqRtDioEwt/QQB3g031hIOiNz/zDteajuKQvX0IqyCHajfflV6nZuZ5EY1QRMcDaLkAmEeui2m/ZNhgsfNG/qtF5JPea3bFCEd7iWqe8Oax0RpK+7vVmrleihe4p8fNcFdRhsXMJP3hUaMTIZaYZswE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005334; c=relaxed/simple; bh=YAH9aYuQ/asSkIDfru6IiARavtx0MGFCnZ91OnZ6PFc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FNy82WB2m5a/5tyb/77xOHqXVhC+iAIjA5TEjRJEIBewlFkBDan0hdyrod2orljeQ+TGLmH7VVG4tNGQmoxVBLU0Mv1i2aP9xnBjlXjaBOMQ25HEgU8f2QtYzQ0DBzeKSqOQfSlNXeVkHnEruJuMVi/UecaYq4domBhZcQsYJh0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dWwOfy3p; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dWwOfy3p" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 063E11F000E9; Thu, 28 May 2026 21:55:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005333; bh=XweS3kpwFRW8Ff1+y4OnFCCxftQN7f5Y1CuJL5J4wJY=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=dWwOfy3pASJq0nV27PEN0JziH6gmpJ+oxyVjFH1kpX7+dN2ttuLkkDEKNawr1+6Dh 6SfJGaf9/VmgsLImbMoG1EXwQSDAU9ThEDoWYwuVBqXvkXRabv7buu1TY/9qHXC8Gj Lm4/lFJaqYXe1iZUshELPlbstkn1+oJPZE0HKloQrTUlSsZVjpJrp37KYTqhU9dgdO qYM/EnG/gLB4hUZmeLXu3eKc8zdz1w08DlUJxaiG5ngEYCRrH7LOD86TeAiAVLD0se pGIHV0ySsXdyHzJDZKLB82Clt06UK70MgtoavLLQ9MvPJgRKHrCzpulLvGL3m9xjzm 61eA2oYz+ZvyQ== From: Jeff Layton Date: Thu, 28 May 2026 17:55:16 -0400 Subject: [PATCH 05/10] nfsd: gate nfs3 setacl by argp->mask Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-5-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2548; i=jlayton@kernel.org; h=from:subject:message-id; bh=yVYZuP8p+I7kHsmp4bD8/GooOKvKdgjutKo3ZY9ai3c=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnKsJJ7bay0rDB8IbSNdFmWLWnzIkMAgrNvM Tkl9ekbMQWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5ygAKCRAADmhBGVaC FZb1D/9oGuSsOs2UBP0hH3k3DCeMBqnPhfoD/3g8YcwR509bIAVn7o/n7SI21j+1qyO3pPdZYRp A2526jXo1Lb5WsmmP86JpmpaUr9Wbp1qlic3v9R0a7K0hiB4HaOqCCI4Jx0CjAB5kUR4cjr11zq eOjP0WJc+wjNhHWNePbcYyLKqDmR3SMP+GJwccFBRHW9fdMTkZKgWrm4nDVr5HUYsAPquEFEQFD oYS1UGrOY7o18nsds6/jzTw2C52mFoJtkKe9oQx8cjLi2qKdQiBFn8HDw/dorN0ab0/cz2imSK3 cB61XIksY3SH2JcBAmRZJTd0GlCbgnSj5XcEV4E8I78JrpNVMR7DbndezBNz8c08ks/iOFCSegO UC0bV0bWrC7UGZ8LeeldWORyAmcMhgiIHcxGSMC6IqCU9RvJUGt1ykUEvkhhpMCPrIpHN+PV0K9 GywThL/xnsxH9hPkFe0VxoLYdtaJPudNnjx7lbJbp0kNLBTPqFg0JnCOcbLK4drbBCsA+ScGSAx DxlfiG1X2aVFKUkvcBaCbEQmMCOLkdEiODXAC/TVjhVzg3Q+XXClb19L8fBEAdP/rBikzWTeMp1 42c2OcfGyhE4gnafqgaEPRZzrxoDaK9KOYRlcDBlMm7waVBkf+cNeE/YWV+8pGjoIprYjsrOh8J v7Jhu5+ezlSi9iQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason nfsd3_proc_setacl() calls set_posix_acl() unconditionally for both ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT, passing argp->acl_access and argp->acl_default verbatim. The NFSv3 ACL decoder only populates those pointers when the corresponding mask bit is set: nfs3svc_decode_setaclargs() if (args->mask & NFS_ACL) decode into acl_access if (args->mask & NFS_DFACL) decode into acl_default /* otherwise the pointer stays NULL (pc_argzero) */ nfsd3_proc_setacl() set_posix_acl(.., ACL_TYPE_ACCESS, argp->acl_access) set_posix_acl(.., ACL_TYPE_DEFAULT, argp->acl_default) set_posix_acl(idmap, dentry, type, NULL) is the VFS "remove this ACL type" operation. A NULL pointer that means "the client did not send this arm" is therefore indistinguishable from "the client asked to remove this ACL". A SETACL with mask=3DNFS_ACL silently drops the directory's default ACL; mask=3D0 drops both. The sibling nfsd3_proc_getacl() already consults argp->mask before touching each arm; mirror that in setacl. Fix by wrapping each set_posix_acl() call in the matching mask bit check and initializing error to 0 before inode_lock so that a request with neither bit set leaves the on-disk ACLs untouched and returns nfs_ok. The out_drop_lock path and the unconditional posix_acl_release() at out: are preserved; both NULL-tolerate the skipped arms. Fixes: a257cdd0e217 ("[PATCH] NFSD: Add server support for NFSv3 ACLs.") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfsd/nfs3acl.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index e87731380be8..a87f9d7f32be 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c @@ -105,12 +105,17 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqst= p) =20 inode_lock(inode); =20 - error =3D set_posix_acl(&nop_mnt_idmap, fh->fh_dentry, ACL_TYPE_ACCESS, - argp->acl_access); - if (error) - goto out_drop_lock; - error =3D set_posix_acl(&nop_mnt_idmap, fh->fh_dentry, ACL_TYPE_DEFAULT, - argp->acl_default); + error =3D 0; + if (argp->mask & NFS_ACL) { + error =3D set_posix_acl(&nop_mnt_idmap, fh->fh_dentry, + ACL_TYPE_ACCESS, argp->acl_access); + if (error) + goto out_drop_lock; + } + if (argp->mask & NFS_DFACL) { + error =3D set_posix_acl(&nop_mnt_idmap, fh->fh_dentry, + ACL_TYPE_DEFAULT, argp->acl_default); + } =20 out_drop_lock: inode_unlock(inode); --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 100DB367B81; Thu, 28 May 2026 21:55:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005339; cv=none; b=gl0IUQJ/tviowEhiQHdv9myHCVirHVsG4WFmPFIoD3fRAcnsu3EHMia4lMrhHg0+mGoTjK8Pns42o7zDOogub9giM8ww00WebWPgYBl+c3Wv5P/xoYfs3emWr2YmcA9cKrbypMYdbqmubUG9Gj2nrZWmidJzvRUm2spAAHj8Sjo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005339; c=relaxed/simple; bh=mGJVvZo9pTZBX+sMN/JjmrBkf4z2jBAjKn61+R0qI6E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=F1oRJQmP1eeiolqFujqO8Wbl0LJUJFQ6PIOWhZBqZhj23rCxfMCKXKkYhIel0BteHDjtwzF5Xyi/SIj1lac2KioF/rZEzaOJKq3jM6pMCNAcF1C6TTKsK40TBKqBjMO7kJkVLqTqr9N7aM+dEPSMdXAovS+MkmAQ7lksLZl6iFA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SodWuNrt; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SodWuNrt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 847CD1F00A3D; Thu, 28 May 2026 21:55:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005334; bh=kXcChEzVlnxyp0TLNxJmodA24yVV9lKapnt3Z+Taqp8=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=SodWuNrt+p0jGlkC5+Zsp06dRyODq4bp6XGfLz8CYZEtKetdIC7C+4cxoSU1y4r9E hWBbw2WnVKWh/cfTVeqrJ89679N+jE1sbkj9E+HnKi6XMvgRrFN0egp3ZZI86u/82b CJhwH6Vh2n9D5LPdEyuVyPPkpAGwprTteoNQ8FA20lxlMfzO11+WIhCjDt8jXbDXqa EgWMAZGsd398POsk/xsMFzKCI4RdsGpowvZzylNOhN352zND+vq8fm2QP1XNfuPdnY SCVSgSbwpchaO/GYQulHZd1Li7WocxG/Tr8i35PuDr98AHGxTt+xrmz50OZ/JZIpTg F6UrUS+5GgS2Q== From: Jeff Layton Date: Thu, 28 May 2026 17:55:17 -0400 Subject: [PATCH 06/10] NFSD: Enable return of an updated stable_how to NFS clients Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-6-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6219; i=jlayton@kernel.org; h=from:subject:message-id; bh=D2zRN4G1nHhfU/M0zPTKcCcUcIm2L9GJqomla9PCqvI=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnLbYWRie82+AbNz+9KrirVA2dFJKeMRvESg r77+WatiX6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5ywAKCRAADmhBGVaC FVfCEACph1B7Y4nm1fqSJ5PfOq2YosITIwruGzxX/YdwaE6uki8zKDQ5hyyPKYEEQdbVkn2w6PA J9TZ0hh/Mm7uqoYUEEg7JhfijgcBcRxRbnWf8jRTlubjSdsn39HdXYyLCZSqvFeiccoehckRN0i qlXSZ2sp01OZxc8PbpuGLaLoopaEbun9GpKmwVdbSzLpUY9/9WU9a5sdU0WJjyYOjiYgzA8Z0Pt //cL74XYSa8DqmQQ46I/YW0GnKhMDnVD+2UyXtUDjz19Vc1RBH1poF4QmwpzZ6jo/jtPF0TAkjU awI3OvirOr1ajT4pumuLSKaJLJK0AXGn23U+GhFj4zAGiQjXC6QjVoLJd5kTUpXutMh4jQQ9D6/ Mnu6iHuU4tWuyMzZmHB15puKpSIN3/7fRzVtXmq4HwKoGejAKg40f4I/37o3p8FUBpivBfZ4DRl H1CVnHlNbal0bOvMtz59aGdQ0RwBAlConFIC09TQ0DuWq8JhhERO0kESqh2KmnCewG+BJNM18uW tYB0UQkYJkNHg7saOfa3WgW/X5ZafPUBQl0Wnh8+STRZlicjqyEUgEquK3qE9aUnTjCj+xfIdsj 9Yd43pRHHpYbIYeHr1l1cvj0z4LwcWxc7qacwp0j0OyWtz+826gHFMxGLsHSk+TxHc1XgJcO2vI c3xXmKecceU4Esg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chuck Lever In a subsequent patch, nfsd_vfs_write() will promote an UNSTABLE WRITE to be a FILE_SYNC WRITE. This indicates that the client does not need a subsequent COMMIT operation, saving a round trip and allowing the client to dispense with cached dirty data as soon as it receives the server's WRITE response. This patch refactors nfsd_vfs_write() to return a possibly modified stable_how value to its callers. No behavior change is expected. Reviewed-by: NeilBrown Reviewed-by: Jeff Layton Fixes: 3f3503adb332 ("NFSD: Use vfs_iocb_iter_write()") Signed-off-by: Chuck Lever --- fs/nfsd/nfs3proc.c | 2 +- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfsproc.c | 3 ++- fs/nfsd/vfs.c | 11 ++++++----- fs/nfsd/vfs.h | 6 ++++-- fs/nfsd/xdr3.h | 2 +- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index aeda7a802bdf..dd5ac59e87d6 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -236,7 +236,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp) resp->committed =3D argp->stable; resp->status =3D nfsd_write(rqstp, &resp->fh, argp->offset, &argp->payload, &cnt, - resp->committed, resp->verf); + &resp->committed, resp->verf); resp->count =3D cnt; resp->status =3D nfsd3_map_status(resp->status); return rpc_success; diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 5f2b9bfc3a84..ac03f9d89288 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1355,7 +1355,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_comp= ound_state *cstate, write->wr_how_written =3D write->wr_stable_how; status =3D nfsd_vfs_write(rqstp, &cstate->current_fh, nf, write->wr_offset, &write->wr_payload, - &cnt, write->wr_how_written, + &cnt, &write->wr_how_written, (__be32 *)write->wr_verifier.data); nfsd_file_put(nf); =20 diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 8873033d1e82..d0a7316f00a5 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -251,6 +251,7 @@ nfsd_proc_write(struct svc_rqst *rqstp) struct nfsd_writeargs *argp =3D rqstp->rq_argp; struct nfsd_attrstat *resp =3D rqstp->rq_resp; unsigned long cnt =3D argp->len; + u32 committed =3D NFS_DATA_SYNC; =20 dprintk("nfsd: WRITE %s %u bytes at %d\n", SVCFH_fmt(&argp->fh), @@ -258,7 +259,7 @@ nfsd_proc_write(struct svc_rqst *rqstp) =20 fh_copy(&resp->fh, &argp->fh); resp->status =3D nfsd_write(rqstp, &resp->fh, argp->offset, - &argp->payload, &cnt, NFS_DATA_SYNC, NULL); + &argp->payload, &cnt, &committed, NULL); if (resp->status =3D=3D nfs_ok) resp->status =3D fh_getattr(&resp->fh, &resp->stat); else if (resp->status =3D=3D nfserr_jukebox) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 1e89c7ff9493..7f07292d1569 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1414,7 +1414,7 @@ nfsd_direct_write(struct svc_rqst *rqstp, struct svc_= fh *fhp, * @offset: Byte offset of start * @payload: xdr_buf containing the write payload * @cnt: IN: number of bytes to write, OUT: number of bytes actually writt= en - * @stable: An NFS stable_how value + * @stable_how: IN: Client's requested stable_how, OUT: Actual stable_how * @verf: NFS WRITE verifier * * Upon return, caller must invoke fh_put on @fhp. @@ -1426,11 +1426,12 @@ __be32 nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, loff_t offset, const struct xdr_buf *payload, unsigned long *cnt, - int stable, __be32 *verf) + u32 *stable_how, __be32 *verf) { struct nfsd_net *nn =3D net_generic(SVC_NET(rqstp), nfsd_net_id); struct file *file =3D nf->nf_file; struct super_block *sb =3D file_inode(file)->i_sb; + u32 stable =3D *stable_how; struct kiocb kiocb; struct svc_export *exp; struct iov_iter iter; @@ -1609,7 +1610,7 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_f= h *fhp, * @offset: Byte offset of start * @payload: xdr_buf containing the write payload * @cnt: IN: number of bytes to write, OUT: number of bytes actually writt= en - * @stable: An NFS stable_how value + * @stable_how: IN: Client's requested stable_how, OUT: Actual stable_how * @verf: NFS WRITE verifier * * Upon return, caller must invoke fh_put on @fhp. @@ -1619,7 +1620,7 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_f= h *fhp, */ __be32 nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, - const struct xdr_buf *payload, unsigned long *cnt, int stable, + const struct xdr_buf *payload, unsigned long *cnt, u32 *stable_how, __be32 *verf) { struct nfsd_file *nf; @@ -1632,7 +1633,7 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp= , loff_t offset, goto out; =20 err =3D nfsd_vfs_write(rqstp, fhp, nf, offset, payload, cnt, - stable, verf); + stable_how, verf); nfsd_file_put(nf); out: trace_nfsd_write_done(rqstp, fhp, offset, *cnt); diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index e09ea04a51b9..36cd9f6edd8b 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -132,11 +132,13 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_= fh *fhp, u32 *eof); __be32 nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, const struct xdr_buf *payload, - unsigned long *cnt, int stable, __be32 *verf); + unsigned long *cnt, u32 *stable_how, + __be32 *verf); __be32 nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, loff_t offset, const struct xdr_buf *payload, - unsigned long *cnt, int stable, __be32 *verf); + unsigned long *cnt, u32 *stable_how, + __be32 *verf); __be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, char *, int *); __be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *, diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h index a7c9714b0b0e..1ff7b11c397c 100644 --- a/fs/nfsd/xdr3.h +++ b/fs/nfsd/xdr3.h @@ -152,7 +152,7 @@ struct nfsd3_writeres { __be32 status; struct svc_fh fh; unsigned long count; - int committed; + u32 committed; __be32 verf[2]; }; =20 --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 10051367B61; Thu, 28 May 2026 21:55:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005341; cv=none; b=AIBwjNjQqlsBRBYEZKoxZ1mY5BduEbjDVdVVSNdy1va9GPugzMIQ9FEeP0B4iKWIUkTJmL+jNTQm58mL3MocGUuMENQ2+HXNre+GH3S+lZG0xTLOj3zjIwj/kenLA7Cvx9rhah07qKJ3Yq6XP3ICzD+kEf8IG4HgYQYSTXstBm4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005341; c=relaxed/simple; bh=jgYcUIiphYc8dlvt0fojriSWgHKg3YiGXZh7FqNN5XA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CPawOCRk5JmNpTEoFTr1B8TX+5/Sp1dd2pKINEz5ZX4m85VZqeGgCdH3b9lRunRnLijdZZvOg5SHM78fjVf4JuOIQRF/XP3hQ5eM9WBHhKYj9syo7lpxDit0kIv0090zZ1Qo3Rcit48ZRvFn5bibHUQYy/TMMOJ9tSgaj7Sbe3A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Xf0LkbbK; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Xf0LkbbK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0D9B01F00A3E; Thu, 28 May 2026 21:55:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005336; bh=wcZk3CrZ4fiHMhIJQ2nzC7yu+rHDdCAtsGvzEQSLHn8=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Xf0LkbbKRT9M/sfmxF4TR0SLbPdpW+uGYAPNGlpVLovZP4PbI6ZqVlGmtVy9nyIA4 SLlgCaf3eoiwS/pWBrdxaP7rwD/shUFTyeT0UeQd5nC0ytnPjipzmex7XhzBjTGbCg U97KxGgTe7cXXP6omh8aq8ExvFbc6WprZJjWWCtHb1QiQ+is+Mc+KOvDhTPdOGiomh uwkjjxfB7hkWt1Pvg9Vu0p6oiooWO4aylcd1DVWaTVOxrZ7xc2t0arU83kfDZmDZ3L XTKS8M+hTpCITe+uj6yOg8xftBwa+IPVY0/U4lXmQPTbU3xIgCwjYTCW1+7EcF783M EmKMzhNkran8A== From: Jeff Layton Date: Thu, 28 May 2026 17:55:18 -0400 Subject: [PATCH 07/10] NFSD: check truncate permission under inode lock Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-7-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2981; i=jlayton@kernel.org; h=from:subject:message-id; bh=AAlZJXNIsMumJGVH4o3U3ITTLWLG40+qhCg1DeCr/QE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnLUyeTBR8LsM8bq3p47OlijSdiqUwP2TZd/ lXrOZJYLFqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5ywAKCRAADmhBGVaC FZ2TD/wI5YCrGR0FmHEqiTBEINokaWC0GgQvWfWm7ImYyGO8SfaugHDdsk6sim//Xdun+rKui49 o8IK7uJM46d1pW64GnP81x0VQqRVXltmWwN5bKJdNNrDyMJb228ZbyAhLvp1uOYgRkE4A0JFLFH wUENTDexbdeaQe8tq5FVKgGyjikkOYentf9ZMduZHJ+BwQL0ohsYoLK7K0QLwIikYcjXdORDeOl qAzdNe+yWpO6i+j3IZ2HEwMge3/TztcyTNWMh+9shZg332W0+QyEG0tflwbJVA1M3vBJDof/7ou cEky72dnf/nCBtkBIUGtoaH0dV9p1GZz59UDab9xEWl6WJ1NFCOopi2BYOPYIopCRc/I2v5EySq 1xsROyuDKWeXACmqSD3zkSinDUTHekE90kHPAoiI3iLotjXrcklFyCnQ69+NvGHxkMW+fhC8CyJ ztIBl4X8cGqhXDfnBsbgA1yda4cFu9tEj6SF0cVBcQMcCQklK86WpFjwNWLx7yaAp4tQbiNRn3x EFoVC7C2kZFv1Ir4A8ccb8LlxHrJNu5NznB434E1mX9RVkcU0jWFM642rwMxku/xigejA9TVdTZ Sglh39mcovR1KOTBKOGw0X2mbOabLORenne29G8T6OrF0yeMT+aiu0Q/yRlG79ZLyGcZdx+x5Qu ibnXizXlOa3K+Cw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chuck Lever nfsd_setattr() checks whether a size update needs NFSD_MAY_TRUNC before it takes inode_lock(). The comparison uses the file size sampled by that unlocked read, but the actual ATTR_SIZE update is applied later under inode_lock() by notify_change(). This leaves a TOCTOU window for append-only files. If a client sends a SETATTR that does not shrink the file at the time of the unlocked sample, a concurrent append can extend the file before nfsd_setattr() takes inode_lock(). notify_change() then applies a real truncation without the NFSD_MAY_TRUNC check that rejects IS_APPEND(inode). The VFS truncate syscall paths perform their own append-only checks before calling notify_change(), so NFSD must make this decision against the locked size it is about to change. Split the write-count acquisition from the truncation permission check. Keep get_write_access() before the locked setattr work, then recheck whether the requested size is below i_size_read(inode) after inode_lock() has been acquired and before notify_change(ATTR_SIZE). This also avoids the plain unlocked inode->i_size load. Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chuck Lever Signed-off-by: Jeff Layton --- fs/nfsd/vfs.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 7f07292d1569..980217f755b7 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -419,21 +419,22 @@ nfsd_sanitize_attrs(struct inode *inode, struct iattr= *iap) } =20 static __be32 -nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct iattr *iap) +nfsd_may_truncate(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct iattr *iap) { struct inode *inode =3D d_inode(fhp->fh_dentry); =20 - if (iap->ia_size < inode->i_size) { - __be32 err; + if (iap->ia_size >=3D i_size_read(inode)) + return nfs_ok; =20 - err =3D nfsd_permission(&rqstp->rq_cred, - fhp->fh_export, fhp->fh_dentry, - NFSD_MAY_TRUNC | NFSD_MAY_OWNER_OVERRIDE); - if (err) - return err; - } - return nfserrno(get_write_access(inode)); + return nfsd_permission(&rqstp->rq_cred, fhp->fh_export, fhp->fh_dentry, + NFSD_MAY_TRUNC | NFSD_MAY_OWNER_OVERRIDE); +} + +static __be32 +nfsd_get_write_access(struct svc_fh *fhp) +{ + return nfserrno(get_write_access(d_inode(fhp->fh_dentry))); } =20 static int __nfsd_setattr(struct dentry *dentry, struct iattr *iap) @@ -560,12 +561,17 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *f= hp, * setattr call. */ if (size_change) { - err =3D nfsd_get_write_access(rqstp, fhp, iap); + err =3D nfsd_get_write_access(fhp); if (err) return err; } =20 inode_lock(inode); + if (size_change) { + err =3D nfsd_may_truncate(rqstp, fhp, iap); + if (err) + goto out_unlock; + } err =3D fh_fill_pre_attrs(fhp); if (err) goto out_unlock; --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 12EBA367F39; Thu, 28 May 2026 21:55:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005339; cv=none; b=IvpFSUZYHpZgYywH4NC9yeZ7fOqeVIBroBq8aOlPaYhgAXwxpb4qveWFRX4GRt7+FkawX2vJzcFZS0be5tGWk5aF+87pSS9A9UqdZ2FtAZb/BXC4KazPbrOT3mxYK/k5iLDpMGnWlI4EquV4K/rnkLM5xjI0lI/htegx0b3EKF0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005339; c=relaxed/simple; bh=UbQcjF1aflAaonH5RYIn6VQryJ6M+npfRRDLBTJOvg0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r2DYLzQfmvuoISbcmgxQ45+uy4ygT8ZrKshcaHx/vfUBo0MeGKvcvRqsnWgJumQ5KzSKCTHtLhKX+0JaodQhnVQFfli8zzqHhq5EKQUC8r9FHFC2ae9GR8VPL+w5UxdVO/5S/HQl3JDhQhhLTKz6cE80QQXoSzPhcb0yNmfwFOc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NMTxol24; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NMTxol24" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8A4991F00A3A; Thu, 28 May 2026 21:55:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005337; bh=5v+H8BNr/R9YGsFJQjJXGp6wWRKHN8YLFQ2smYTVaEQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=NMTxol24bsAQF3ENt0MYho8Bwinw96mA117TG/8SsojzFCXgigfKA0Wavfxc9dyVb cFLlNQmN+IxkzYu16bG051vRTK5WOf81f55OGY+LZjdqhhvoleCwYAHD6YKw61xqHo laxCkxkz8CxLjfBqmocmjurg3WGUf5gGVCRGiRKRg9C2JXPZ0hpOsZSFo3dY4pjkvU 9XxAKJma5gKD04syaMO3RtWFd6S4ScfrMcVL6k4nO/geUSxhzF2UYTKvg6EKJb7MFO Yp4c22B/Qa4Jdllu4OhXvQYn1SaBuqKI7rSSyEvcw2fBdl+fz9ZUp9yyOh8Lq2Qkpu b93Zl9V9fzQMg== From: Jeff Layton Date: Thu, 28 May 2026 17:55:19 -0400 Subject: [PATCH 08/10] nfsd: fix partial-write detection in nfsd_direct_write Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-8-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2421; i=jlayton@kernel.org; h=from:subject:message-id; bh=1+zAyObpPwUeMrDlZP4+lDrpr9oaGw29ATNniqWkcjE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnLihC8bAm7gQOtVdbQagkPiJZH5sr5Nn16j QQzWPS2HbWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5ywAKCRAADmhBGVaC FZSKD/0e2eczik0V5+94G7F81QBu46AzcLogayiX0UdJ2yaj65QyI9FikD8casBeSv+DaCz6src aW2pWFI6yJ1Vk+OiiWBQ/g69sUBMrK7/c0NSTbnVp6lhPrgnnShZmEHUeovEljuhtySDjAKRqJ5 QZyd8cq5bFaVqt3e6OIEHdVqeREP2qHFSqJLR6AD59VLqG7BS32Pts0BIvI/VBoKMz/GBsDVDSR Igi2hqO249dvYqDefHNH6CfYJp6iIBMih4UePRLro0hqm11uVLgqg914QM39sqLIsMgPH04pV8q Uy68w10t0NZERBy66tW6qycvELyRNVbq/dO7IEC6v5JPqs7/HuW4MUDXCu+7PUl0djXPqvPxkq3 s0s6/Wx9iGwX6i9xY33r13KssRkCcPLhrGmBnHWs5hbWh3X0vUxtrra8TPV43cZFcNvnnIhlBlv UgSxrUN2vm06oJt/SK9S3wiYreQmsC/9YTtYX3n1JFUYR40Bg6d0B75r/RltdW+EjkvEBk1AINX N3g28r4J6Rh3SrTB6km+BEStf8qhuW0VB1KP2lfgKFP9lVXEEqHb8HKyEdBHMVFg1bgtKK1VV+Y S6gJqH3uVgtwms+V1BwlmDLQ5sLZ9YKC+Me6NKCxvDwWXKtS01hKFZK+wjQDWGHetwJ2GG1+gX0 4AeAvwJtalijUYA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason nfsd_direct_write() walks a list of write segments and, after each vfs_iocb_iter_write(), tries to detect a short write so the loop can stop before placing the next segment at a wrong file offset: host_err =3D vfs_iocb_iter_write(file, kiocb, &segments[i].iter); if (host_err < 0) return host_err; *cnt +=3D host_err; if (host_err < segments[i].iter.count) break; /* partial write */ vfs_iocb_iter_write() runs the iter through ->write_iter(), which advances the iter by the number of bytes written. By the time the check runs, segments[i].iter.count is the residual, not the original request length: before write_iter: iter.count =3D=3D original_len after write_iter: iter.count =3D=3D original_len - host_err The condition then reduces to host_err < original_len - host_err, so the break fires only when less than half of the segment was written. Any short write completing between 50% and 99% of the segment slips through; the loop advances to the next segment with kiocb->ki_pos only bumped by the short amount, writing the next segment's payload at the wrong offset and over-reporting *cnt to the NFS client. Snapshot the segment's byte count before the write and compare host_err against that snapshot so any short write breaks the loop. Fixes: 06c5c97293e3 ("NFSD: Implement NFSD_IO_DIRECT for NFS WRITE") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfsd/vfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 980217f755b7..619f252af4d1 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1380,6 +1380,7 @@ nfsd_direct_write(struct svc_rqst *rqstp, struct svc_= fh *fhp, struct file *file =3D nf->nf_file; unsigned int nsegs, i; ssize_t host_err; + size_t expected; =20 nsegs =3D nfsd_write_dio_iters_init(nf, rqstp->rq_bvec, nvecs, kiocb, *cnt, segments); @@ -1401,11 +1402,13 @@ nfsd_direct_write(struct svc_rqst *rqstp, struct sv= c_fh *fhp, kiocb->ki_flags |=3D IOCB_DONTCACHE; } =20 + expected =3D iov_iter_count(&segments[i].iter); + host_err =3D vfs_iocb_iter_write(file, kiocb, &segments[i].iter); if (host_err < 0) return host_err; *cnt +=3D host_err; - if (host_err < segments[i].iter.count) + if (host_err < (ssize_t)expected) break; /* partial write */ } =20 --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 98968368D42; Thu, 28 May 2026 21:55:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005340; cv=none; b=eQqNFfJ1FB5u0ign/75Q3LHFH1hIcr+s2ovGc0jVkxQiOrh652lOxo6c8PnQDNyK2JDf8/a9DbSRpZ2c4ubcfqaj93RqNWlYwsdgXiEgS3fNLAQQ+guRfcr5cvLKsW4X1cT2JRIOyffC3nH8n0er4xILEIMLVRGTLr6neNEGeOg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005340; c=relaxed/simple; bh=tpPyldF1ng/UAup0IEjon7uOB3/Il45nXDpJmy2eEsI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TmsQ+Nt9cB2pgIBlWpIOISDEA8a0k0IABU6r0K6yRGnLb7ROv9SzUTZ/b5+fYQm/wnelUtzxCTnjjgTNldTpo+Vy4bkL0ROZha8vAO9Kms7Lc1pyfdmcRb8IpV1FOSYF+rNTc5o19EXo/wqky0/slmZEGOLCFM0FJVktZys9ZQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BapTHcxX; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BapTHcxX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1364E1F00ACA; Thu, 28 May 2026 21:55:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005339; bh=JryY+lk+CVXnYXPbEYkvEZd9RAwO1QGurng0FR2GFkk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=BapTHcxXNN8XYX88rror0PQxwV2RCVfUBc6kkFrIPz7E6cIv+4P41doDr6EsJ74zg kl5Z2+zfkU65CZURYw6W7fHYmM6svU+vVJBKHTGcdPC9OQ48kZtV4KjySNKxOOHnOu IYB2inuz6hcuYDd6e3Fe7UfyVcmWhwi1wkYIPAaogubxUc+LjFmpyaer32fPYJLDbg ZfIX2+en2WwpLMToHmgi1+UxL/TI+BTMPcS72zMek3koaHJLaJ/QWMDDFfFqRY4KY1 /K2mBvGt2zqYnbtgLHme33h0dUykgS/aXS5DOKzBGwx4u42STWcnyf3juZwnWNB5jJ etACUxBo7tXZg== From: Jeff Layton Date: Thu, 28 May 2026 17:55:20 -0400 Subject: [PATCH 09/10] nfsd: cap decoded POSIX ACL count to bound sort cost Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-9-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1573; i=jlayton@kernel.org; h=from:subject:message-id; bh=DnOXwDcgGRU7CosVARw/tloWNLDBt7bWuhRiCqiYRb0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnLrNmWDEt0F7v/L92MWKqm9U6732ZAwULpH 5FG4+J634mJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5ywAKCRAADmhBGVaC FRS0EACu97meKx3iF96dDwt3L8AQ4VnejoH4F+UlwXdbHsncN7AQHHR7dYtI/suEP5WLeQFSleN M2DXPpoe08RwwVCrBQTS4YQCJDiSIOSvnhNLPCLDbTS8HMNS1gu/B0yWqHR/WYTcNXNH8/CHpmA bpihukXw5kSMZxayi1JQSv3lCKjmrtsSamN/x7EAKx3Idi6usk9sfafY9uVBppPujTW0AJSrn6W bcaEYMV+GinTegqThDQEDla8cwoqacz6xDEQPWS7GMvEw8pzYrtPl4uD0OUODOljhngO8e2DODR HKzsC+JQY1qnckSBczaUSy4DSBNFL35ybTWpHZmdD/6BJPU2dHL7na7TWONhQpMQt9lBgwtHc5v /vNcqkgiM0STRBGkGBY1nVZoqzckqipVPGxlSn2pDV+i6lt7ekHoXoNfYcvOAKuw9a1/1oC2i1B a93lkgxaOR8P52VMcigEpzkWd7wLPD6M8mxm4zju20FQRxGujO4ZReK3gz9bjecmPTyRxuefSoW 48iBjCudY0d49cZaNWeJ50zRKsLKIs8drd0Pa7At9jFxCymS+bV+oJiAZZlp1YEHkq6WAGeMnXu y9ybkzvjX11R/YTvsvwAT+rTZrEBKE05IscaLxw1vH1y2DP1FJ0CGS+agc4bUxuUqIrTdm/hKZe TIBOM2IqfH3eN8g== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason nfsd4_decode_posixacl() reads a u32 entry count off the wire and passes it straight to posix_acl_alloc() and sort_pacl_range(). The latter is an O(n^2) bubble sort, so a client-chosen count drives unbounded CPU in the server's compound processing path. nfsd4_decode_posixacl() xdr_stream_decode_u32(&count) /* uncapped u32 */ posix_acl_alloc(count, GFP_KERNEL) sort_pacl_range(*acl, 0, count - 1) /* O(n^2) bubble sort */ The encoder side in the same file already rejects ACLs whose a_count exceeds NFS_ACL_MAX_ENTRIES, but the decoder introduced in commit 5fc51dfc2eb1 ("NFSD: Add support for XDR decoding POSIX draft ACLs") omitted the symmetric check. Fix by rejecting a wire count greater than NFS_ACL_MAX_ENTRIES with nfserr_resource, before any allocation, so the sort is bounded by NFS_ACL_MAX_ENTRIES^2 comparisons. Fixes: 5fc51dfc2eb1 ("NFSD: Add support for XDR decoding POSIX draft ACLs") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfsd/nfs4xdr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index c6c50c376b23..5469c6c207ba 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -448,6 +448,8 @@ nfsd4_decode_posixacl(struct nfsd4_compoundargs *argp, = struct posix_acl **acl) =20 if (xdr_stream_decode_u32(argp->xdr, &count) < 0) return nfserr_bad_xdr; + if (count > NFS_ACL_MAX_ENTRIES) + return nfserr_resource; =20 *acl =3D posix_acl_alloc(count, GFP_KERNEL); if (*acl =3D=3D NULL) --=20 2.54.0 From nobody Mon Jun 8 14:35:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E5D52367B8C; Thu, 28 May 2026 21:55:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005342; cv=none; b=RQzbfpripX3iwmZVEcpDO8/a9Se2GbLcsByYit/7+RmRQcHZ+GKwtX/V8SCzr9tgVWRCzriWruQilqX8497Ll5AXFw9nuAvCoQIXT9uQXmWe146WbOUhysk9aj395OMhqSUJLCzE0k82FiAlmyHhmesWkWhNUG+q4TCdOYsQcR0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780005342; c=relaxed/simple; bh=14ZvczbnLPmszix02zJpjBn510ZrCpD9uZ8yHxb0h+A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=irYPawnxrLcEmVwujApl1NjI0rY5ImM26kMjBYsgD0kojfUBbb9EmsrfonYO19fWp7d91sjt5FxjRA3BfxBQ654f+ODO0vdHqbz0rJHADD9LuxWDooiDqM+BYDbEQu7CbyqdWC9CAtG9wVjpfdvPV1HBSBLzREbM6fGcprjcoJc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O0thdS0T; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="O0thdS0T" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 901AA1F000E9; Thu, 28 May 2026 21:55:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780005340; bh=6/t4f0OHFqr8Avxv8F1KCmoMLWiMdtXQ8guYxaB+nnc=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=O0thdS0TkMiKTV5OIJvwf6frMukeGG1bIT3owEnQrtT9DXusY4g1A+bzreUc3VBd1 aSsfkgNw8mOZoczIYASdZzCbD7ZX1ZzCiLfxePyagF8QcQaW4nDRh39+2KYKBNYA8s yIqrqY54ZpzdYB8QSQKDBtlyNiDUFcSm9wzBL3JcpjzX5OhCGNl53xlf9kRCQUlk9L buZw/oTYt/93X2dSnYi6XDfUy1yN0pH+9Mp0CQsC5MvGxOHlgWM+DstfjIJHWEUXwM Ql+E6jK4OWmd0h4+OHBvdHKUqV4imcolkHE6CH35gVbV1g9nmkUinT2x+2hEbewjAo 6FC0Uv7wOor7g== From: Jeff Layton Date: Thu, 28 May 2026 17:55:21 -0400 Subject: [PATCH 10/10] nfsd: validate symlink target length in NFSv4 CREATE Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260528-nfsd-fixes-v1-10-e78708eff77d@kernel.org> References: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> In-Reply-To: <20260528-nfsd-fixes-v1-0-e78708eff77d@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , "J. Bruce Fields" , Scott Mayhew , Trond Myklebust , Andreas Gruenbacher , Mike Snitzer , Rick Macklem Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1223; i=jlayton@kernel.org; h=from:subject:message-id; bh=14ZvczbnLPmszix02zJpjBn510ZrCpD9uZ8yHxb0h+A=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqGLnM+6gs3ykB2WslLr7jJHyxmfP7Hp0ovRyjO wBDuwynIAmJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahi5zAAKCRAADmhBGVaC FYk8D/9QaA/L0TFoD0GsRdaA4q3ZgNaceFWDnHqD9PitbZef8wU/185jRhoNN4UM6G2NI5mhB85 lH8cF0XK79z5K3qLEvpasMm6eJmx1sLzrutxWqffADwvcliiOKr4qSpjzsj9i3WAIHzA5c5BD2y c0bGmek6DCs7nB4QaLronjoS16peezdN1Y6WyB94YYfh0DwVGUNzjtjenRzB+uRgv751vStEPcG gDoBD6e2QbaoEHQNylvj+JVfH8hrnmHnuWerCtSrlg9pTtT0OL+Ig8RQ79LZIFgUoDuq9drgZg1 OH1GEiEf3jfWa42jIeujmpQPo5WHIoSHySfhmyriLD6hfLpx4St4vomgxq2wpah8CF4AJ1l6hBa j+J/bcvMgoknVnwz7C/L1rm8Q4fzbMhN/ycWt1Uc2DI8lThxU2WjBf3NqBIxht0J7MO4y2avkrH JiC0GFDWmkqqzda78E7C3WxUDfthwI5a29fbKgdDtuf46pDEgp5NhJpYXYsxkmaAv141D5i5CQY 1UHGjWTKtOEA9+vU6UANauh29uH7649ig0eWFa+CEpJr1rqMs37dsR32ONHWSItO0BL9DgXhBzA SRmR3/ZKI09CDsAbA3bPKeDFig9Z989ZEvyclj3Kn+drVk/KOpUi3ZgSSk+VqA6bUKyVbBUUifM 1eLk1e4vMdzmTDw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 nfsd4_decode_create() accepts an unbounded cr_datalen from the wire for NF4LNK symlink targets, allowing a client to force a kmalloc of up to the RPC-max size (~1 MiB) per COMPOUND op that persists until compound teardown. The VFS rejects oversized targets with ENAMETOOLONG, but the allocation has already occurred. Reject cr_datalen =3D=3D 0 or cr_datalen >=3D PATH_MAX early with nfserr_nametoolong to bound the allocation. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 5469c6c207ba..1f5e49f50f3a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -957,6 +957,10 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, u= nion nfsd4_op_u *u) case NF4LNK: if (xdr_stream_decode_u32(argp->xdr, &create->cr_datalen) < 0) return nfserr_bad_xdr; + if (create->cr_datalen =3D=3D 0) + return nfserr_inval; + if (create->cr_datalen >=3D PATH_MAX) + return nfserr_nametoolong; p =3D xdr_inline_decode(argp->xdr, create->cr_datalen); if (!p) return nfserr_bad_xdr; --=20 2.54.0