From nobody Mon Jun 8 05:24:54 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 E7A633DEAE4; Mon, 1 Jun 2026 17:31:29 +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=1780335090; cv=none; b=UfeUaqPxZ5bOMKUALV7bECmZ1O6gZGYabn8MJtv68UOdKj5Mt3d0pIRmt2bOxUOSwvd8C3h3wimUoCIyjgbCh6OV12Bms/NXyKOP9MjJ6buoLEYZL1QSiky792xPvOvlrapwLN8DktBjACYeoWeMsDJa1PELiVYLp+s0T3c0eBA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780335090; c=relaxed/simple; bh=0kn14y4Zr87QdMm2kllBabws/iLsYCS38BAXri0J95A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LjaJMYrn1+A5i7eCa6/q3xfbpNE5GUxs7id6aRZHzPl1a7dOZfcSpAd/hWAgyiwflNzYle0aD0Cv8yelBJ2RL8s5JkmSATtygInPKlr0oOBevvp4d4fi8YREI27gcFyJEaa1H1UTx/9IS4g1IO3Og6Z6Pd/4pIO45ppEEnWr2BI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lMIWPc35; 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="lMIWPc35" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45E411F00899; Mon, 1 Jun 2026 17:31:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780335089; bh=spc3yZf0Leo44+aaUSe7k7gMiOCmlyn5q55vzDzy5s8=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=lMIWPc35DZWsaKICIWnV9gaFGUwu4frTyFKtHqbrDoiTRajzx5gc+At/LyjZtCqpi 2vObCQqa+ge5z4NXoqc5snk4bsfPNfRyB1PpOX4QCeZJCo4BVm1leCi1AliYMqcuUB v6xHjc8Y9x1uq3r1TqqO7560RoioDGRWzLtVCCGggdMOnR5AM1ZgFXhE+Im+DtzSCD Mylv/zYsKXORG6F12sRTLEU+y80JQq5WM1jdDIarqlE82+Th+3qjG/ZBnb/EjRpmPu F1z0OJtZaTL5TLPB+hxUUHGdgU0CrdvQMGk2BAnCJ5bYD5liV+X1fdCk0DBuW2VadI +KVVm+R7S+1TQ== From: Jeff Layton Date: Mon, 01 Jun 2026 13:31:04 -0400 Subject: [PATCH 1/8] nfsd: defer vfree of compound ops to fix rpc_status UAF 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: <20260601-nfsd-testing-v1-1-d0f61e536df8@kernel.org> References: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> In-Reply-To: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Trond Myklebust , Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1776; i=jlayton@kernel.org; h=from:subject:message-id; bh=0kn14y4Zr87QdMm2kllBabws/iLsYCS38BAXri0J95A=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHcHssIaCyGwFe2fkEINzHR6l8k/8ejW4bxxyW jqlxQSwy/6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah3B7AAKCRAADmhBGVaC FUt5EACZSFZp7IeB60L+mfiGpu0vBXp15OALCSLfq6NxnhK1B3JQI/S+fK4FqWg/lSrMxebXFma dr96NQxll+9XtIjip8+mf01tYXMaHlTb06IcStnyR1NJLHzWfirf+gcbsAsEMhNkloUN2FcY//V s9//o4GaBakY2kd/4tjp+eLea6oeWnEkW7IPMqf1VThdHJ2QU6WaDkhogv4hMZHw8D4DjzM2yYw X87ArBqNWET2DuGd2RGkf1h5b/aoMyhR5u0ciXxwL+Rnn/qVf6TCjrH+SjKGS3ZjSsDyVk1+f2l TYJajAZ5J6TXuoPLOoKf9bYRnFfse6qI0ohsuAzp4TIJeykSX1DKsHxKbDPecU6ZHAHJ72wbrBa RyitH/89RvzdDmDFfk9edy1poCnw/EAtVk+IQnpJxIS9jhowiqVRANGtalu8/GF2l9ZHC/P+LAY RBXXhe4DcllWA5rFvB7F3C881HOrue8CjJ9IfrtBpZZQvHE/oM5ZpDJba5S085yIThcnXPIGcdj C+DqZxw6ggFUHNZpYRLf+Eoyh+QOBUiJZ5zXurUyulgNzlzAjljOCdJDTf2KicOtJ+BydQTlKQd PSlWWq7Vxor4+n15z7JCNIEw1zYY+uf3G4kFmzBlKplvN9V9XKLkY2MBuFKauK+S+U4YwZxs2B/ ApzaFwrITTYvz7A== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The rpc_status netlink dumpit walks every in-flight svc_rqst under rcu_read_lock and, for NFSv4 requests, reads opnums out of args->ops[]. But args->ops is a separate vmalloc buffer freed synchronously by vfree() in nfsd4_release_compoundargs() at the end of every compound. The dumpit's rcu_read_lock pins the svc_rqst struct itself (freed via kfree_rcu), but nothing defers the vfree of the ops buffer across the RCU grace period. A concurrent compound completion can therefore free the buffer while the dumpit is reading it =E2=80=94 a use-after-free on vmalloc memory. The trailing seqcount recheck (smp_load_acquire of rq_status_counter) cannot undo a load that already retired against freed memory. Fix by replacing vfree(args->ops) with kvfree_rcu_mightsleep(), which defers the free until after an RCU grace period. This makes the existing rcu_read_lock in the dumpit sufficient to protect the read. The tradeoff is that completed compound ops buffers (up to 200 * sizeof(struct nfsd4_op)) persist in memory slightly longer, across one grace period, before being reclaimed. Fixes: bd9d6a3efa97 ("NFSD: add rpc_status netlink support") Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 487a1f62ce15..90272241dacc 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -6686,7 +6686,7 @@ void nfsd4_release_compoundargs(struct svc_rqst *rqst= p) struct nfsd4_compoundargs *args =3D rqstp->rq_argp; =20 if (args->ops !=3D args->iops) { - vfree(args->ops); + kvfree_rcu_mightsleep(args->ops); args->ops =3D args->iops; } while (args->to_free) { --=20 2.54.0 From nobody Mon Jun 8 05:24:54 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 8C3E83DE427; Mon, 1 Jun 2026 17:31: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=1780335092; cv=none; b=HtP66G4f6tXVI48QSpJ+xEyieQ69z0dwxv6bOYYieWRdzBUxmW3Wh4EU+TBQ1KQEdhWfT2CHY6YJ8f1IuCUovPWAjJKifv+zJKVN8aWbk2gPtWXI0xLx8Kjsc1PFvV+SDylzo3LGqRY0ktCcYh0Q2HHMeEVC3K+56YRTku6FdWM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780335092; c=relaxed/simple; bh=Z4Sa04OPguVVMhb/R/j+wi8hB7rLuPo3U1Pzf+0g9+0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=s3lUT/JgdieBoTeqvb3BTsXLzmUx2j9hT76HLAdiSQt3o5JY/YgIpr3vAgcVqkTvewSLNcdmUn0BzBNmxCk3+EV2MMStwYDbY+mKt2/gQrXXYTrE0wDSMf6XAD/ACZoV2V2n8abnprRj75qxMP+7vTQqroKV4b9pYD/6Nvw+Zlg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OwqVH3TN; 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="OwqVH3TN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D3D461F0089A; Mon, 1 Jun 2026 17:31:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780335091; bh=guAkVFVqRYjiojYXLWG1CxAWJyMoK1eDqsYRwZSIzfk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=OwqVH3TNSybSqPdQHqLv/T4nZDNIWtukr8D/heDIaobzHcq2EgTnaIwSm1LFaQnmg rMvJ/S0o2x+TIf+eAY7qkUrFwlr68KjV8Mn30sVqnxbn9+cUl9cEOp3PglzngXuQZG sK0A1I1Qop9i8HMYwF0Uq2RtyFPcHhTTORPgZJHpfTgEmBeI7RqJKy8e8rLPxOlAGh 465QHvesDRFgvEDPPK3ZwE2dLPjuKirfK5B5mKvsD6z5/dNxgaXRLuk+1TwiWkdaih S3PzTK6hBqK2UUhEwavR7zGZNcyoOVcc1r5vAHB21tWeQ1cbiAlHeUReQJEzDFkPSB IRBuOJ2Q5vPGQ== From: Jeff Layton Date: Mon, 01 Jun 2026 13:31:05 -0400 Subject: [PATCH 2/8] nfsd: hold rcu across localio cmpxchg retry 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: <20260601-nfsd-testing-v1-2-d0f61e536df8@kernel.org> References: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> In-Reply-To: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Trond Myklebust , Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2871; i=jlayton@kernel.org; h=from:subject:message-id; bh=jhosRCdsgV6tnLgxdUeYl40e/QY6nryL/Up0X7W5E1U=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHcHsalO2+YDzIwJkenGGyCsjupUPONoMWKa8m G6LiYq2ZhaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah3B7AAKCRAADmhBGVaC FaCgD/4/oYOTTjXT/VBZNGPCdowG/75XvmyT0jFIMEyt/lP+1zI9ZMFqREPe8pFM72aI8xlY0z8 s9wG3M+OMO8OwRavd5615G3FvPz6I1EsZsnNsdG/d8Mq4ua0VK3r2KoUuMpAar119b7c+HChtFY BXeXEmvToHEUQR042Q2dDF6ruz10N+yW/WyLQ6wUz2GCawy9QPvInVJsTY/PBi+qwpQNNkJqTkM 2PhoEAXKCVEECzKvDsleSs5QGdeIGXZjG/tSP1M1yQPm7CDN0X9TRv+pkOHAY6wsdD7AFEgbV4A Fi4iQ7O9HXOp3cehsc53MbyV9U5z4bXcz3wqTl+8FYHVjeTEP+L0h3Vr/HGlLHvP1fNhDc5W434 u/iV3kdMbqbhKxrvf4q7exSHEbm8P5SBS+sgWuW/wHVqKyQ2ijVoBNr37EiaYc66NCcDlrc0bRX 6dkoyCly0zsdPoMYZIWrl1p6Vlj2zkMPBd9ZEM8XPFuf8TxphR8C1jMWUSz+EuK2oK/R6n5JyHF rWIErPKrz7lPheaG4IoPss/T1+tJ/SNk/82B+aDeAoDL7LxJ2QFRvX6ukn/2Dgcmoeqn4vZn03S 08aWD8JhF9ylX2yj/Yr/wfPHx5x0B3IqExBZSv8Kj30vICOoIXqki1E8+hvbVJEw+H1a1jbSaC1 WdBbVZ/9yD5PVmQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason nfsd_file objects are freed via call_rcu (filecache.c:296), and nfsd_file_slab is created without SLAB_TYPESAFE_BY_RCU (KMEM_CACHE(nfsd_file, 0) at filecache.c:789), so the slab page backing a freed nfsd_file becomes freely reclaimable once the RCU grace period elapses. The again: retry block in nfsd_open_local_fh() loads a pointer with cmpxchg and then calls nfsd_file_get(new) (which is refcount_inc_not_zero) without holding rcu_read_lock. The sole caller nfs_open_local_fh() drops rcu_read_lock before invoking this helper, so no outer reader-side critical section covers the load. CPU 0 (nfsd_open_local_fh) CPU 1 (nfsd_file_put_local) ----- ----- new =3D cmpxchg(pnf, NULL, ...) nf =3D xchg(pnf, NULL) nfsd_file_put(nf) last ref -> call_rcu() /* grace period elapses; slab page recycled */ nfsd_file_get(new) refcount_inc_not_zero(&new->nf_ref) /* operates on recycled memory */ A non-zero word at the nf_ref offset of the recycled object makes the refcount bump appear to succeed, and the caller then dereferences new->nf_net and new->nf_file out of freed memory. Fix by taking rcu_read_lock() immediately before the cmpxchg and releasing it on all three exits of the if (new) block: the goto-again retry, the lost-race cleanup path, and the install-succeeded path. nfsd_file_put() and nfsd_net_put() stay outside the RCU section so they remain free to block. Fixes: e6f7e1487ab5 ("nfs_localio: simplify interface to nfsd for getting n= fsd_file") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfsd/localio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c index be710d809a3b..c3eb0557b3e1 100644 --- a/fs/nfsd/localio.c +++ b/fs/nfsd/localio.c @@ -97,11 +97,15 @@ nfsd_open_local_fh(struct net *net, struct auth_domain = *dom, } nfsd_file_get(localio); again: + rcu_read_lock(); new =3D unrcu_pointer(cmpxchg(pnf, NULL, RCU_INITIALIZER(localio))); if (new) { /* Some other thread installed an nfsd_file */ - if (nfsd_file_get(new) =3D=3D NULL) + if (nfsd_file_get(new) =3D=3D NULL) { + rcu_read_unlock(); goto again; + } + rcu_read_unlock(); /* * Drop the ref we were going to install (both file and * net) and the one we were going to return (only file). @@ -110,6 +114,8 @@ nfsd_open_local_fh(struct net *net, struct auth_domain = *dom, nfsd_net_put(net); nfsd_file_put(localio); localio =3D new; + } else { + rcu_read_unlock(); } } else nfsd_net_put(net); --=20 2.54.0 From nobody Mon Jun 8 05:24:54 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 E4AF63E0224; Mon, 1 Jun 2026 17:31:32 +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=1780335094; cv=none; b=ZwrnNTksl5WOlO3diNQ2gZkJkMQ2NF8rajRgXiDKm4uZEJkJGHH6oLw88FJHu0vLhwwIntWtvhmXVcrdFgj9K12lJuBAUx1Y5Cp9Tlqs7P01hGhkgbwZ9Ur6Cxh7B099o7yL9LjmHLHPdh7Ah5RWS98uTu845/IUjeX2ZNwZPf0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780335094; c=relaxed/simple; bh=RNvYl4X9h5aArUfk9p/ctbid7hq3/VtVP+wffu34sME=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gaLPSNt59lr1snTsIEs86pHgKT4rCh18QRgWV1pjqNKpgmJKizA3p93KgYo6GJDvZd8WP5eagg22d+w8JoopkrLDKBW6RSSEiNlJ55dDjexhZPS91Q4ibZ5Vo2n5ja+zMY6YnekqVa+IpkCdXj8PGF67o0vkpuGenZCKyHBgpms= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k621h1VR; 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="k621h1VR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6D9421F00898; Mon, 1 Jun 2026 17:31:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780335092; bh=jO/o2PhsFYiMTNYvyXUl1epDYlP6z+nKUYpcM7iOoL8=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=k621h1VRbgCSrfJ1J+mt6BPm3ckz1GFqTvJrTNdRBc4rxZJnoBMYxSJWcX1dwTm7v UhVCgODJh02uq9E6Wn+wY/X5Yp9hYiMfYvnCvvXIY2y360Qhu8KQ0eiYLOr/6r2U+N cnPXDMC27o/dd4asSW+D2W71nl7evOMHSHd0h0fKCNdnUiWq35aco/2/Dpk78nVkWH ScMkSe6WY8xHtluVG3t2N5It6VCbecHn54v0z2ozRrgAWTSZNPkKYgwckCowt3XQOE yNpR1ZH+IfWoxkEG3179Lcks+ElXVXQBFXC9eWQe/UQKVAJImdThX+I45wPfJfFV3S 6I/cA6PBW/ZAw== From: Jeff Layton Date: Mon, 01 Jun 2026 13:31:06 -0400 Subject: [PATCH 3/8] nfs/localio: fix ref leak on nfs_uuid_add_file failure 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: <20260601-nfsd-testing-v1-3-d0f61e536df8@kernel.org> References: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> In-Reply-To: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Trond Myklebust , Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2906; i=jlayton@kernel.org; h=from:subject:message-id; bh=SymQrXheMIcvvEyabGknNPPPReS8lNip1GXZKx5s68g=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHcHtOiR3ydI7L7kOyRfXIyMRAhmhHOOZ2HE9K U8IEU6gCoCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah3B7QAKCRAADmhBGVaC FSC1EACT/AyEWsBIrFwkonb+7Lyjh5NX2m1bfklS9i5ci0DC6TRZzN3CuG0RM3g3qfRAIzG0Amd Y6jqPPKzFyBbA5FDBT+Ule0/ShNtXZWVg8YhshusD4OTzjTiyFe70xrC1wycZlb0qg4wYxlmgnb u0XDWdnWvcAbzrl59IkR+DmkMd6DnZxlZSky1dvx1WH68zRpi/TL60ya4kZRM0WAo1WzhSRsZIO OKWPe/nj5mn/oVtSIoIVi19cmo6hAytfXXQ/n0vtJG5qs1lmZduYFIVHKxvF8vSiY0ebzsnlx3k teOZk2guAb+K5cnC6LLqP0V10/7cm17ZkrP8R0d4Q35lAso3kPJCrZ3biZTMk8jQUtBEWR+rNsl Di+fP7eq2XbHz7dlW7/5/BuniHOVLIVPZbmvggqPsqjOteXAxQF6lTcxNq+ye5tMo7nJHdcWgXT 3A3SSlqYyVKxdp1VYiOHGgsI0rSF/t5IAv1thm2kS/9D75nnIAOTCQ/itlGAsTxtNC9K8BqgjaG PPHNZBihE1EbouY+g2NH/tnJMXV6mHnXyvKWT1lx7HdD6dA8oYgoH+/7vlUfqyD1mkGdcUDEqmx kxvj3rhhnyUAjtUAvkOq1i75CFh7eGFsam7m/XxEFYIhOafVu1+JP9YsZZS6HCyuoIZAXeXpDHo ZVkce6mezQDFRkw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason When nfs_uuid_add_file() races with nfs_uuid_put() tearing down uuid->net, it returns -ENXIO without publishing nfl->nfs_uuid via rcu_assign_pointer(). nfs_open_local_fh() then enters its error branch and only releases the slot pair plus its own entry-time net ref, while the close path is a no-op: nfs_close_local_fh() nfs_uuid =3D rcu_dereference(nfl->nfs_uuid); if (!nfs_uuid) { rcu_read_unlock(); return; } /* always */ nfsd_open_local_fh() returns localio holding a caller-owned +1 nfsd_file reference (from nfsd_file_get() after nfsd_file_acquire_local()) and an entry-time nfsd_net reference (from its first nfsd_net_try_get()) embedded as nf->nf_net. Both are leaked on the failure path, pinning one nfsd_file (and the underlying struct file, dentry, inode) and one nfsd_net_ref per occurrence, which blocks nfsd_net and netns teardown. Fix by releasing the caller-owned file ref and its net ref through the existing helper, using a stack-local RCU pointer so the helper can xchg it out, then returning -ENXIO so callers do not dereference a localio whose slot has been cleared: struct nfsd_file __rcu *tmp =3D RCU_INITIALIZER(localio); nfs_to_nfsd_file_put_local(pnf); nfs_to_nfsd_file_put_local(&tmp); localio =3D ERR_PTR(-ENXIO); The trailing nfs_to_nfsd_net_put(net) continues to release the outer net ref, so all three nfsd_net_try_get() increments are balanced on the error branch. Fixes: fdd015de7679 ("NFS/localio: nfs_uuid_put() fix races with nfs_open/c= lose_local_fh()") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfs_common/nfslocalio.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index dd715cdb6c04..a3c1c5c2764a 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -292,8 +292,20 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, localio =3D nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt, cred, nfs_fh, pnf, fmode); if (!IS_ERR(localio) && nfs_uuid_add_file(uuid, nfl) < 0) { - /* Delete the cached file when racing with nfs_uuid_put() */ + /* + * Delete the cached file when racing with nfs_uuid_put(). + * Since nfl->nfs_uuid was never published via + * rcu_assign_pointer(), nfs_close_local_fh() will early-return + * and cannot clean up after us. Drop the slot pair, then drop + * the caller-owned nfsd_file ref (+1) and the entry-time + * nfsd_net ref carried via nf->nf_net, and return -ENXIO so + * the caller never dereferences the now-cleared localio. + */ + struct nfsd_file __rcu *tmp =3D RCU_INITIALIZER(localio); + nfs_to_nfsd_file_put_local(pnf); + nfs_to_nfsd_file_put_local(&tmp); + localio =3D ERR_PTR(-ENXIO); } nfs_to_nfsd_net_put(net); =20 --=20 2.54.0 From nobody Mon Jun 8 05:24:54 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 ACB5A3E0C42; Mon, 1 Jun 2026 17:31: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=1780335095; cv=none; b=hmfKTu2dC4cCcYMqitQF/m3fop6wK9IgWx/NUYn26QklF1cWCqLXjZzLKSiCUkfR/gBA6RmjYeRSuZMa7pjUEbuVDqjsHvtz1m9pvvT4tpZkuTHQnOPSOnZ6yIMPZucttfQe4syAMylWyn4Q0cK/bga6mD78zYnh9TcQCWbAPVA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780335095; c=relaxed/simple; bh=5GmFOsoGsxUoKK42L6oIuiqD2T2yto1PqXZGDDjnR7g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Nd4CA9oxsBqFiH0wEweo0wxYggi6/n7NNHX9iZHqfNR5bBe1cDLAz79v59vZIVmqQK0ExJA+yGE7kSnLOWrLs2+tZXkC8KNuLlTiPV8jn3f3PeOeEuflEf5qA0WxKtini51B3AWUrcUOmMvfbjmJQrxskzR8k5Df9D6OXv386S8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UJrUSmMT; 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="UJrUSmMT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0700F1F00893; Mon, 1 Jun 2026 17:31:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780335094; bh=GQSR5xDyG6bHaFaZRpDiOp0QGRNuyvccZonIX15jpMg=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=UJrUSmMTbgX5vjmmB0TMWWhHt3dOImZF2zlIrjq2+6arFOSlI+DHZWbiaIVUtHazp DLNigXQ52asbaBWqxRUX3e3L5efXklre29C6WhueO0V5vxr1C4gRV0PRtCpcj7+mao P9TtiRKypUdsf6FY/drHB8+B4pbnuXcbBh3mAUskKhXRLwcepxw1JTXmfmcrl4o9Pm VXUxWzy1BrEDLNGhQuyq7+/EgzSz1hk6nxejQuFMWI1bTaZ88+oqR40RhmRX36ANpD 4umWW/aX1kyN1ejRaGGOstefofGrCCmrr94bfjRvs0OvgAurH36hqGGIrfSuElZVm0 d9UQ4erjHY4+A== From: Jeff Layton Date: Mon, 01 Jun 2026 13:31:07 -0400 Subject: [PATCH 4/8] nfsd: guard nfsd_serv deref in nfsd_file_net_dispose 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: <20260601-nfsd-testing-v1-4-d0f61e536df8@kernel.org> References: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> In-Reply-To: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Trond Myklebust , Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2274; i=jlayton@kernel.org; h=from:subject:message-id; bh=Dxlhw3GNlHUspVC5P+k7IYi9cq5Erg9fOpoK54g/QOM=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHcHt43NoZF6LGaAsByvhk4q6Xx0KVytLMpLYg HBzLKbrrCWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah3B7QAKCRAADmhBGVaC FXQTEACLhpPcbqoAkVAEQWuar545tpMSLjaEkFJSdmqG6Qss3K88SN0lSvfgSvGXw81E5S0gYVy 7djv7RXwuwy2gJJkL6qd1cPFBijAoPmaGVNBJqs7HuYDOy3h1Y6WSTIQU3+y8Wmz7Cbgwl/j7Ls sZDEFdmRgKTxj4OhmAxcqRRbQ6hT6do+qYCgiArQguyu4f3kXMnDvh5gCZYo5MgEpV77r5IjfjA Sb3DxYXc7KfE+r0hb3ewch703Wqbdn8zI1TK6WJ7EX8/HTIisqWnmv1/pENSfQmHU35l79jnO0m f1obJ8AWXGSpp4eryIjw373KLXpAluWRr9AzLWGOvhNy6tnQBMcy4eJaCILYTHnfcu1kck1zVft HgvlYcgnQqyfRL+FXOlGo0EiwgA8QJTVgALNs96gz8H8xUFs++UM6uauR5EFsWthXZwtcocrGBn AYKHAgAlXrqmGQ+T+J279qUEnLEVo5VufplGC9PsSjEbvqn+SPu356WwPrkqn2v4MDm0JnVnZx+ 68JCz6/qSo9BBmCAHczTo+K453PRWQlB864c9dGdi8wY8nzwIp0cQXRMx/cIkX7LROM8gtoixDh jw1GAB5q4idcbrzDRX6Tn3dH7h2KmE8ZCOpwM9XGB176ZiQNacs/teSmmfsjUEZm0Q47L33ijBN FEY/XvikSqhL0qw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Chris Mason nfsd_file_net_dispose() is the consumer side of l->freeme: the nfsd service thread loop calls it to drain entries that the filecache garbage collector and shrinker append via nfsd_file_dispose_list_delayed(). During per-net teardown, nn->nfsd_serv is cleared before the filecache laundrette is shut down, so the service thread can still run a dispose pass that finds more than eight entries on l->freeme and dereferences a NULL svc_serv: nfsd service thread loop nfsd_file_net_dispose(nn) if (!list_empty(&l->freeme)) { ... svc_wake_up(nn->nfsd_serv); /* nn->nfsd_serv =3D=3D NULL */ } The sibling helper nfsd_file_dispose_list_delayed() already documents this ordering and caches nn->nfsd_serv into a local before testing it for NULL. nfsd_file_net_dispose() was introduced with the same raw svc_wake_up(nn->nfsd_serv) call and never picked up the guard. Fix by loading nn->nfsd_serv into a local svc_serv pointer and only calling svc_wake_up() when it is non-NULL, matching the pattern in nfsd_file_dispose_list_delayed(). Fixes: ffb402596147 ("nfsd: Don't leave work of closing files to a work que= ue") Assisted-by: kres:claude-opus-4-7 Signed-off-by: Chris Mason --- fs/nfsd/filecache.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 2f0d4de779af..1e2e1f89216e 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -474,11 +474,20 @@ void nfsd_file_net_dispose(struct nfsd_net *nn) for (i =3D 0; i < 8 && !list_empty(&l->freeme); i++) list_move(l->freeme.next, &dispose); spin_unlock(&l->lock); - if (!list_empty(&l->freeme)) - /* Wake up another thread to share the work + if (!list_empty(&l->freeme)) { + /* + * Wake up another thread to share the work * *before* doing any actual disposing. + * + * The filecache laundrette is shut down after + * the nn->nfsd_serv pointer is cleared, but + * before the svc_serv is freed. */ - svc_wake_up(nn->nfsd_serv); + struct svc_serv *serv =3D nn->nfsd_serv; + + if (serv) + svc_wake_up(serv); + } nfsd_file_dispose_list(&dispose); } } --=20 2.54.0 From nobody Mon Jun 8 05:24:54 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 59BB33E1220; Mon, 1 Jun 2026 17:31: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=1780335098; cv=none; b=IFisKgVAbE85cgNmNi0cyj7V8wXzGIVURpHm3fHoT1dfdpt8fTYN05CBlVTb7/b3iUEdxGZRyyx1pBqlWo2Mf4cqiTeaC61tX+f/gdHuDjv5M9Dew525H33t1il0p+V0V5TwGIWca9velBxYf+01RhIXIPOsuU5wcqDT/ArCUCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780335098; c=relaxed/simple; bh=JnC/2ourKTNHmtFxJc84B3W+7hBsSIk7VRR8Jv40pdw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qJVjSjtYmUvHTG/SWpvYoWnVynPDa85BBmTCo4hQqouUdsRyCPqOZyAgcUcuhL1HhcQwB2PZja2kFiQvA7E2xSOb9tzANaLO6OCbW0E2Tqv7Qu6uDm7FKsetCmtd6HuB8kbyUryFbF+RG8xxJQGrXw3HaL+aL84v6MoTJWOQX7s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PL3Ji+2c; 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="PL3Ji+2c" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 960D01F0089F; Mon, 1 Jun 2026 17:31:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780335095; bh=uur/XWzh2Vx/jw0lVJDfyL9NUFvYWLGaQ9j78hmG7V0=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=PL3Ji+2cmlVuCJgcRc8lbuSO/cuo+jRdw+cKcKTK2VNEggFVdFUtz5a4v0P6LP01D 4v4BrSfABHB/zcoF7lWa+lXlRMsaMl2h2AYxHp1sUwrkX47yjIhur6bzJyJ+j9ebwJ r4wQIUVDQOzsU9yzAG6kkLVSZOxn5iO49Wci/OCTaolFADpK/0TUPxSzLRz4TjYIgy 4T+3QZPZqRTRXs1/htAUZTatqE2ZrEwFGpv9v8Oj8/TC6bMF073aDqbzXyvx6v1ZuM b/GPS0gyHLnApyiM5l1uFSJ11caP4svPTe0r1FC/xqsfO2LdLbBLBsAuz5FP+qSSvC Qac37Eg63mrgQ== From: Jeff Layton Date: Mon, 01 Jun 2026 13:31:08 -0400 Subject: [PATCH 5/8] nfsd: widen nfsd_genl_rqstp address fields to sockaddr_storage 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: <20260601-nfsd-testing-v1-5-d0f61e536df8@kernel.org> References: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> In-Reply-To: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Trond Myklebust , Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2906; i=jlayton@kernel.org; h=from:subject:message-id; bh=JnC/2ourKTNHmtFxJc84B3W+7hBsSIk7VRR8Jv40pdw=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHcHtDmYuK3PLc28OyHqlC4tSmKX1mbr7USr8R 5cMgerWasuJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah3B7QAKCRAADmhBGVaC Fe8OEACO9lA4XHsK7txI0+STT7trKALWXTxuWP05EsHpnGcE1CNIsA6K0nRNyFAPshVD4j+QKgV 4gLaxbr0UGsDOqjDpYzC3RT5LscSK4IW0PsGOZ7zvKGc1UN5ZC2g1jgA/hYp3vqojEZsh8k6IB6 JClKaPFoAoZeu+tfiKqr7fY5WNLzhVzp3x2AFakqZODDWekRX2Dmz8ngwbciqZg7E2woUub/0UM ah0Ai4lTg1M8hC7KW974Bj8AXuXk+M7qUTauo08JHYMbXv65PGwftH3kuLqp2DshubtMtcMv0AZ lGjIGTEQD+jUN8wlXGpnTzn4NuRVjc/OLn6j4nEeGygSgHdCW17wFPZ0sjISNSytLQ1/5kEf/Ys YPUbR2LexJUNi7psyqipPomZ83NB5vtIwJTwPyKaYAgLS6pvE73HcSxYM/FGxSpvt9av2Ksy4s9 HlGQ/ejmZaTH0xKV2dk4VYm7aGD3IGR+Z2TB6x44BpnCwXPugYOFdpKs88PtcP2Pyk/iBLWOgy0 pMV0uE4YShxEtH06TnIwSmj8FvrrvfF4vFspeDD1Myn0MWCZDHGjYjzuH4oRWqrTMW8QNzaLyGI vq3TFClZvfy9LP+D0CGPTi6rT5zhyKnu0XHEu8wL9KWeQcndnHEnkWEsffsiUh3t94Yd/2gSOW+ GTE3eiiuk4s6W2g== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 struct nfsd_genl_rqstp declares rq_daddr and rq_saddr as plain "struct sockaddr" (16 bytes). When an IPv6 NFS client is connected, nfsd_genl_rpc_status_compose_msg() casts these fields to "struct sockaddr_in6 *" (28 bytes) and reads sin6_addr at offset 8..24, which extends 8 bytes past the end of the 16-byte sockaddr field into the adjacent rq_flags member. The 16-byte nla_put_in6_addr then ships 8 bytes of truncated IPv6 address followed by 8 bytes of rq_flags to userspace via the NFSD_A_RPC_STATUS_SADDR6/DADDR6 netlink attributes. This is reachable by any unprivileged process in the network namespace because NFSD_CMD_RPC_STATUS_GET uses GENL_CMD_CAP_DUMP without GENL_ADMIN_PERM. Fix by widening rq_daddr and rq_saddr to struct sockaddr_storage so the IPv6 casts operate within bounds, copying sizeof(struct sockaddr_storage) bytes in the memcpy calls so the full address is captured, and zero-initializing the genl_rqstp stack variable to prevent leaking uninitialized tail bytes through netlink. Fixes: bd9d6a3efa97 ("NFSD: add rpc_status netlink support") Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Jeff Layton --- fs/nfsd/nfsctl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 92f65ca6f667..6fee49a7787f 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1414,8 +1414,8 @@ static int create_proc_exports_entry(void) unsigned int nfsd_net_id; =20 struct nfsd_genl_rqstp { - struct sockaddr rq_daddr; - struct sockaddr rq_saddr; + struct sockaddr_storage rq_daddr; + struct sockaddr_storage rq_saddr; unsigned long rq_flags; ktime_t rq_stime; __be32 rq_xid; @@ -1450,7 +1450,7 @@ static int nfsd_genl_rpc_status_compose_msg(struct sk= _buff *skb, NFSD_A_RPC_STATUS_PAD)) return -ENOBUFS; =20 - switch (genl_rqstp->rq_saddr.sa_family) { + switch (genl_rqstp->rq_saddr.ss_family) { case AF_INET: { const struct sockaddr_in *s_in, *d_in; =20 @@ -1527,7 +1527,7 @@ int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb, list_for_each_entry_rcu(rqstp, &nn->nfsd_serv->sv_pools[i].sp_all_threads, rq_all) { - struct nfsd_genl_rqstp genl_rqstp; + struct nfsd_genl_rqstp genl_rqstp =3D {}; unsigned int status_counter; =20 if (rqstp_index++ < cb->args[1]) /* already consumed */ @@ -1551,9 +1551,9 @@ int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb, genl_rqstp.rq_stime =3D rqstp->rq_stime; genl_rqstp.rq_opcnt =3D 0; memcpy(&genl_rqstp.rq_daddr, svc_daddr(rqstp), - sizeof(struct sockaddr)); + sizeof(struct sockaddr_storage)); memcpy(&genl_rqstp.rq_saddr, svc_addr(rqstp), - sizeof(struct sockaddr)); + sizeof(struct sockaddr_storage)); =20 #ifdef CONFIG_NFSD_V4 if (rqstp->rq_vers =3D=3D NFS4_VERSION && --=20 2.54.0 From nobody Mon Jun 8 05:24:54 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 A90283DFC60; Mon, 1 Jun 2026 17:31: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=1780335099; cv=none; b=S8tXf7ZmP/Gojmy0mE/2N1fZUoPkPuDCmM6lbfQm1andGdl4q7G0XshaTMnYBBnjy3aKQmqInxxxt80nR4AV2NfYT3e9qAcHyJ//rQlJ4SIygkyYH8R1hedOiRep2lhS7kLKxM1z4tthXnXCVLdtKEwTs8VuDTrNAljHFtFMEhA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780335099; c=relaxed/simple; bh=zmfzxfk6E0NbX309OavYex7lV0fRj09UZiXgnfOIGqM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=thoLJFeUaiebWLk8KxyHo0BZcMpoXlFySOvLq78mBceN+QzBf+7NaTe+LE/j6H3hpnGF3jeyS7WLrPGyAJCRf+dfNtH1DjEIi+eqt+tmD94xGelRq8eHKeJ/mQsYImCl2jV6yQTwTXUvRdukO1q6qKCtWSyYBl+OTI6jzip2Bi4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BAAgfVSs; 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="BAAgfVSs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2FF341F00899; Mon, 1 Jun 2026 17:31:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780335097; bh=2O6E87EFPiFCpLU6dL+tj802BACuDUrciFMJJtwN128=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=BAAgfVSsvwHiyeXP+Swdei/79sg1TV5FmAamBfHPrqxLKlR+O5A/X8eRSRlxquZO+ FFDTKGxxw+5T0oLetsgxODlNjCRpZRpHb4NnRr9OpK3f1HRhte94sKTva7Eid+kiqF 0fxRdwPRHzM5PLX2W+AWaUTzJqWPTajWDoxVN/FLD5E1Mm49hx+LZLL7FziNcGNIaA PEM2JhQ7vbuT+cCt1sFWo6+67tDXgCRfBei8a/WB5RFJBYXvmZQG6DILyJKkAGfhNH XjiVcYc98rtNDPLmDpYPbjMYeKGuR0Sm+Onr4i3ihegdR+fiaWxyZtyD+FTVe1W5Tg CMsv38RePdW0g== From: Jeff Layton Date: Mon, 01 Jun 2026 13:31:09 -0400 Subject: [PATCH 6/8] nfsd: fix refcount leak in nfsd_file_lru_add on insertion failure 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: <20260601-nfsd-testing-v1-6-d0f61e536df8@kernel.org> References: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> In-Reply-To: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Trond Myklebust , Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2151; i=jlayton@kernel.org; h=from:subject:message-id; bh=zmfzxfk6E0NbX309OavYex7lV0fRj09UZiXgnfOIGqM=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHcHtFpWxy1DFN8/H6b26a17Ha9Tz6KSmwvv9I sMOFcLepCiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah3B7QAKCRAADmhBGVaC FVmXD/9em0S3Yot1zwTSk93Y3k9KSB9DGYKpgf9g98Z24vowt6Mx7vf3HdJkfuBcBdZlRFGRMId ihB1IMV+0tl3eREUufW5XLNw4MCqLc5+7TjzGauV1XdQnr7Rg8AJnsJMOxbibf8zrPIMfetvHLf VyrkMxSgqroFoMm9oXCtjSgGz2J/RM8edE/QADuNlJ8MRVzwTBV3IqfUJlQL8NUn3Ue/MpS1pPL q7aCdPWFK+NEjJi+v8KtFzY619OyiEzuj97jIVfBSQzx7TKK0X6KPdboiLQkbF5t5LegfpS6Ln/ osHC6KYZaknuVnQKbQ31rMlBz0TjovCzGW15b81M6T0bUFliRYSYtBZSKKEHunHSmPxnQeEFfc2 /MSKAAWIp13wGXiglCdNDoNOz5MKCjWRjMlinS/z4cAzDN/9+N6ZEoV8ONTsUbZHH2ama2RNGI7 7LEl5lY0+gcuacQTcYkZN3HIvMVTvcSIKAMc7cNyGroi4YvCslk/A12dobt1lAvb/f0bHJ1BanE 4SGdQlkvKZB1yL3gc/QWD49ytkuz3Rtg904poLe8sp9U+3zeTkl6Yx0y/1VT9BEKT+E2k9Symtw CzqYKvtANRm8L6mln2WOapX/RfQVwnEnApODLmQeeLv7epRpLMpWMWq/gMvwpKquqtW3athK+BR JrwRVKusOtW+SSw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 nfsd_file_lru_add() unconditionally increments nf_ref before attempting to insert the nfsd_file into the LRU via list_lru_add_obj(). If the insertion fails (the item is already linked), the incremented reference is never released, permanently inflating the refcount. The LRU shrinker callback (nfsd_file_lru_cb) uses refcount_dec_if_one() to reclaim entries, which requires nf_ref =3D=3D 1. An inflated refcount therefore blocks eviction of the affected file cache entry for the lifetime of the nfsd instance. While this failure path is currently unreachable -- the sole caller in nfsd_file_do_acquire() operates on freshly-allocated objects that cannot already be on the LRU -- it represents a latent bug that would become exploitable if a future change adds another call site or alters the PENDING protocol. Fix this by: - Adding a compensating refcount_dec() on the failure path. Bare refcount_dec (rather than nfsd_file_put) is correct here because the caller in nfsd_file_do_acquire still holds its own construction reference, so the count goes from 2 back to 1 without risk of reaching zero. - Changing WARN_ON(1) to WARN_ON_ONCE(1) to prevent log flooding if this path is ever hit repeatedly. - Returning early on failure to skip the unnecessary call to nfsd_file_schedule_laundrette(), since no entry was added to the LRU. Fixes: 56221b42d717 ("nfsd: filecache: don't repeatedly add/remove files on= the lru list") Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 1e2e1f89216e..d5b917e40d62 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -330,8 +330,11 @@ static void nfsd_file_lru_add(struct nfsd_file *nf) refcount_inc(&nf->nf_ref); if (list_lru_add_obj(&nfsd_file_lru, &nf->nf_lru)) trace_nfsd_file_lru_add(nf); - else - WARN_ON(1); + else { + refcount_dec(&nf->nf_ref); + WARN_ON_ONCE(1); + return; + } nfsd_file_schedule_laundrette(); } =20 --=20 2.54.0 From nobody Mon Jun 8 05:24:54 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 533DA3E1CFF; Mon, 1 Jun 2026 17:31: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=1780335102; cv=none; b=FktZVFO8FJof1403h9PlpPQGpc1iZnj5Tq8KMecGlq/BjeMb0Wl4sVKapTweiX47Vs3+HrlHsuTBwOKAAzlm+9T5ZnS/j4cY5yJNlAhNhoASLz5riTQQyYAIWgG9IeDHRn8VrEEng5ajM6BU6AIsfD6V1gOizAKFSTqomXlNd+g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780335102; c=relaxed/simple; bh=4p1CVpcJ+A7EaLxF7Um3E6hVGg91UNafTKWuimRUO5E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eGgB6GDy8v3qRTvw+bDuWYaG8lBTKcFBB85Iv1NvSC/ZGTFuXwxHscaqo0DeAPvivZrKFfBbLARe8YzVeHyqEC2vVzvdGgzIaQinPI0MLzZw3IhtTIb0f9gUbNXLxe3J1pS+ZuAzJy+RDuiWtNf1InRucU3alNEooruqESiPXok= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=W1vSvm8M; 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="W1vSvm8M" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BC30C1F00893; Mon, 1 Jun 2026 17:31:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780335099; bh=gnQV3veSdBsU4Xt2Zlss8tJxAFnNE9xWCwOd+DHr7Rw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=W1vSvm8Mm8Fnevr7Bu3VXDEu6aFyW1kuFH9RBp7WWB182RWAlqs+2REavfZ0RpQFs tZ7cCJD5JxxiHdI8UbufIu1JDmKJeu8AoFn24Jw09O4t4b+Rq2IRXfdsUcsOcXW7FS PMWeKOq0Lz5Uq+ZXEesZHrg+e/Zi9wt31sy/34lme1yNGsC5v4sMAYeIdj+QBkbuAX zZ/viwNi+gX41VHed7y233+X9FLcP1lz7arLVRfRv6K5+0Kv6SxjJf2U9BrGp7gwd/ M2BZ468aT/oIKryv4GLZkfDIQrSDNNytU2HM/mONe2ue+2CWhCTFgiis0qh0pOeD0h SfWJ4lWaPy85w== From: Jeff Layton Date: Mon, 01 Jun 2026 13:31:10 -0400 Subject: [PATCH 7/8] nfsd: fix fcache_disposal UAF by inlining dispose state into nfsd_net 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: <20260601-nfsd-testing-v1-7-d0f61e536df8@kernel.org> References: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> In-Reply-To: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Trond Myklebust , Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6986; i=jlayton@kernel.org; h=from:subject:message-id; bh=4p1CVpcJ+A7EaLxF7Um3E6hVGg91UNafTKWuimRUO5E=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHcHuINLISbfd6jtwuO+loWcL3cgebUogZTbHu 7yiEOXbdNOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah3B7gAKCRAADmhBGVaC FV4SEACmQquRkQrqsHqn8U2lX1iKU5zMLITyoVnOgZT0wY5tzvTFaUaWNwjQtihCT3/S5nfI7gA zHU0ADJ/dzII9dhEnXuGEtUP9qDOoxXHIOJN3POB8L8W8eeCJ+tUJ/dC1DhECBdgoVaT31rNFGc 9waCyQp7MZ3vaOZ8CpRahNnkg5BOTVH7vZP6QW6I7+U0ba4nCDn0lv6hCfGoFKk3AaKnBeYCyBO KHrYJJx4Eh+W3KEbMe4158nS9KBvGyppr71WnNJTz7JUSzfSIw+hiSjvE5s8cZQvJHXiRpY2SW6 Z/GiNM3Swiy9qGTnACDAsBgl4XObGLqFgeyl+N9iSyNWcsBvZx7RJUFCBgfRu2FCatkXK/LtC+I afcbK5Fox4/onpMaC2DUIj96i0cNj+3RDX8/rQF/YOfJkHZkQBl8gRVSWqbg41ODRUcpLd2gnMd xtnK+QYFQAdgMalnMb+xWvY3DVFdOv0T5hvdKXVKvKJXd1WFlP0QSxdDxjAACXffnPnxSH12G0M KHR/+dWaYQsxv6lIBJnjqsTJ5duRvrMVlhp9YGMzdPffZP7fCKtWQchH8kwZpcMexSWCptEISwn ExWQ0cfkncrzo1HR/EtZVA6wmJdtHurTqbQfJjkq4jcr6PTmeqqtsxKFFdppZ7V9D5ha6zCxswH 3ojQYvbAaDE3uhg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 nfsd_file_dispose_list_delayed() defers fput() to nfsd service threads via a per-net freeme queue, preventing the shrinker and GC worker from bearing the cost of closing files (see ffb402596147). However, the queue lives in a separately-allocated struct nfsd_fcache_disposal that is freed by nfsd_free_fcache_disposal_net() during per-net teardown. The global shrinker, laundrette, and fsnotify callbacks can still be inside nfsd_file_dispose_list_delayed() dereferencing that pointer, causing a use-after-free. Inline the spinlock and freeme list directly into struct nfsd_net (as fcache_dispose_lock and fcache_dispose_list), eliminating the separately allocated struct nfsd_fcache_disposal entirely. These fields now have the same lifetime as the net namespace itself, so there is no dangling pointer to chase. nfsd_file_cache_start_net() now just initializes the inline fields and cannot fail due to allocation. nfsd_file_cache_shutdown_net() drains the inline list directly instead of freeing a separate struct. The alloc/free helpers are removed. Fixes: 1463b38e7cf3 ("NFSD: simplify per-net file cache management") Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 90 +++++++++++++------------------------------------= ---- fs/nfsd/netns.h | 3 +- 2 files changed, 24 insertions(+), 69 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index d5b917e40d62..03f01a0beced 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -62,11 +62,6 @@ static DEFINE_PER_CPU(unsigned long, nfsd_file_releases); static DEFINE_PER_CPU(unsigned long, nfsd_file_total_age); static DEFINE_PER_CPU(unsigned long, nfsd_file_evictions); =20 -struct nfsd_fcache_disposal { - spinlock_t lock; - struct list_head freeme; -}; - static struct kmem_cache *nfsd_file_slab; static struct kmem_cache *nfsd_file_mark_slab; static struct list_lru nfsd_file_lru; @@ -425,31 +420,26 @@ nfsd_file_dispose_list(struct list_head *dispose) } =20 /** - * nfsd_file_dispose_list_delayed - move list of dead files to net's freem= e list + * nfsd_file_dispose_list_delayed - queue dead files for disposal by nfsd = threads * @dispose: list of nfsd_files to be disposed * - * Transfers each file to the "freeme" list for its nfsd_net, to eventually - * be disposed of by the per-net garbage collector. + * Transfers each file to the per-net freeme list in its nfsd_net and wakes + * an nfsd thread to do the actual close. This keeps the cost of fput() + * in the nfsd threads rather than in the shrinker or GC worker. */ static void nfsd_file_dispose_list_delayed(struct list_head *dispose) { - while(!list_empty(dispose)) { + while (!list_empty(dispose)) { struct nfsd_file *nf =3D list_first_entry(dispose, struct nfsd_file, nf_gc); struct nfsd_net *nn =3D net_generic(nf->nf_net, nfsd_net_id); - struct nfsd_fcache_disposal *l =3D nn->fcache_disposal; struct svc_serv *serv; =20 - spin_lock(&l->lock); - list_move_tail(&nf->nf_gc, &l->freeme); - spin_unlock(&l->lock); + spin_lock(&nn->fcache_dispose_lock); + list_move_tail(&nf->nf_gc, &nn->fcache_dispose_list); + spin_unlock(&nn->fcache_dispose_lock); =20 - /* - * The filecache laundrette is shut down after the - * nn->nfsd_serv pointer is cleared, but before the - * svc_serv is freed. - */ serv =3D nn->nfsd_serv; if (serv) svc_wake_up(serv); @@ -467,25 +457,15 @@ nfsd_file_dispose_list_delayed(struct list_head *disp= ose) */ void nfsd_file_net_dispose(struct nfsd_net *nn) { - struct nfsd_fcache_disposal *l =3D nn->fcache_disposal; - - if (!list_empty(&l->freeme)) { + if (!list_empty(&nn->fcache_dispose_list)) { LIST_HEAD(dispose); int i; =20 - spin_lock(&l->lock); - for (i =3D 0; i < 8 && !list_empty(&l->freeme); i++) - list_move(l->freeme.next, &dispose); - spin_unlock(&l->lock); - if (!list_empty(&l->freeme)) { - /* - * Wake up another thread to share the work - * *before* doing any actual disposing. - * - * The filecache laundrette is shut down after - * the nn->nfsd_serv pointer is cleared, but - * before the svc_serv is freed. - */ + spin_lock(&nn->fcache_dispose_lock); + for (i =3D 0; i < 8 && !list_empty(&nn->fcache_dispose_list); i++) + list_move(nn->fcache_dispose_list.next, &dispose); + spin_unlock(&nn->fcache_dispose_lock); + if (!list_empty(&nn->fcache_dispose_list)) { struct svc_serv *serv =3D nn->nfsd_serv; =20 if (serv) @@ -701,11 +681,11 @@ nfsd_file_queue_for_close(struct inode *inode, struct= list_head *dispose) } =20 /** - * nfsd_file_close_inode - attempt a delayed close of a nfsd_file + * nfsd_file_close_inode - attempt a deferred close of a nfsd_file * @inode: inode of the file to attempt to remove * * Close out any open nfsd_files that can be reaped for @inode. The - * actual freeing is deferred to the dispose_list_delayed infrastructure. + * actual freeing is deferred to the nfsd service threads. * * This is used by the fsnotify callbacks and setlease notifier. */ @@ -990,42 +970,14 @@ __nfsd_file_cache_purge(struct net *net) nfsd_file_dispose_list(&dispose); } =20 -static struct nfsd_fcache_disposal * -nfsd_alloc_fcache_disposal(void) -{ - struct nfsd_fcache_disposal *l; - - l =3D kmalloc_obj(*l); - if (!l) - return NULL; - spin_lock_init(&l->lock); - INIT_LIST_HEAD(&l->freeme); - return l; -} - -static void -nfsd_free_fcache_disposal(struct nfsd_fcache_disposal *l) -{ - nfsd_file_dispose_list(&l->freeme); - kfree(l); -} - -static void -nfsd_free_fcache_disposal_net(struct net *net) -{ - struct nfsd_net *nn =3D net_generic(net, nfsd_net_id); - struct nfsd_fcache_disposal *l =3D nn->fcache_disposal; - - nfsd_free_fcache_disposal(l); -} - int nfsd_file_cache_start_net(struct net *net) { struct nfsd_net *nn =3D net_generic(net, nfsd_net_id); =20 - nn->fcache_disposal =3D nfsd_alloc_fcache_disposal(); - return nn->fcache_disposal ? 0 : -ENOMEM; + spin_lock_init(&nn->fcache_dispose_lock); + INIT_LIST_HEAD(&nn->fcache_dispose_list); + return 0; } =20 /** @@ -1044,8 +996,10 @@ nfsd_file_cache_purge(struct net *net) void nfsd_file_cache_shutdown_net(struct net *net) { + struct nfsd_net *nn =3D net_generic(net, nfsd_net_id); + nfsd_file_cache_purge(net); - nfsd_free_fcache_disposal_net(net); + nfsd_file_dispose_list(&nn->fcache_dispose_list); } =20 void diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index f6b8b340bf8e..5c33c96da28e 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -216,7 +216,8 @@ struct nfsd_net { /* utsname taken from the process that starts the server */ char nfsd_name[UNX_MAXNODENAME+1]; =20 - struct nfsd_fcache_disposal *fcache_disposal; + spinlock_t fcache_dispose_lock; + struct list_head fcache_dispose_list; =20 siphash_key_t siphash_key; =20 --=20 2.54.0 From nobody Mon Jun 8 05:24:54 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 290BA3E2759; Mon, 1 Jun 2026 17:31: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=1780335102; cv=none; b=Akmzrg6JeqX45z3/yOjsKSEfDPLqiHTKpoyirb+jW5LwYKkiXeucBvxDelB76MdwlHvX/h/C3duBExD7WJ+RTMkIZO2KbYpKbsOVe3I3VYavjfdqsQqHba5AeU/O0AaWTnfyfSANOVCz89R1+wRdn3ozLTblGMB1alJPGjfse/U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780335102; c=relaxed/simple; bh=QyeWtrI9A+N6rR9y0AS2o40h2YkNvdZeQ3dRpIReu1k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uApwScskgU3p37Q3AvI4ARv1CZc1X+0sasZrGdmNniv/UtwG3n6Ux1JqqYHjlsC3AQugU8G4Ih3ci4nfZY6s7EFfKPj+VARUSO1havzH+yEZWJxlvKC0uz9+daSuaBix5dDVnnm0mn9pdv0T2CdmQC+paZu6nJcScxxXf8X8nfs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=j51RBHbT; 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="j51RBHbT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 551821F00898; Mon, 1 Jun 2026 17:31:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780335100; bh=XNSuSbNi8UDp/7y3bhjNC73fcr/uNxJx2hhHh8HNntY=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=j51RBHbTM6kcTigQUJ6mBVN7Xy6q+m6jNseFI8N1ZqaPE0PsCg5NzXwzoFFdNqJVk qvtlB0YjlIc0KkEzN9JybKZfltpNHEZa6KISdxY8+Mi70ODS4Bi+sMJKNRuwIQtO53 bUks1JoyRmazfh7ieHWu93pxnytKclxWwscm9wBbbTswmy0dek0NQJ45rYs7NCrTm+ tBze8w0CYe3F/ignvnB1vkOKMO/eGGD9kF7DuLc307+NI+AhRQ4K2GfaPVS3WRFUTv ngymbSVNtB4McN4OjJV72Mj0KrctWKcnUKX3fQLkL03fprPdbdx0lsTWDEO6KoW0hO m28f9eGYyRKxQ== From: Jeff Layton Date: Mon, 01 Jun 2026 13:31:11 -0400 Subject: [PATCH 8/8] nfsd: hold net namespace reference in nfsd_file 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: <20260601-nfsd-testing-v1-8-d0f61e536df8@kernel.org> References: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> In-Reply-To: <20260601-nfsd-testing-v1-0-d0f61e536df8@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Chris Mason , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Trond Myklebust , Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5494; i=jlayton@kernel.org; h=from:subject:message-id; bh=QyeWtrI9A+N6rR9y0AS2o40h2YkNvdZeQ3dRpIReu1k=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHcHuJOrDgY3fPYgMsvWgT/AMvQGdeZLKUNYWX 32HKMaCeRaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah3B7gAKCRAADmhBGVaC FeFZEACjOAsAp1c+2d46AbgnCTrR+CXooIc0Fl5DufK+NI7y+Pjta06E+MwWvWfNqHj1AMw/v/o RY39ae6hefBhOnZtajOsIF3jE4MFCyeBvilcS90HxEEW2ooxGZFh9S38+w9ns0klxtWRl34qlMn yNEKb2QmrSN6BvUMJcg/UuoYxfLNwzhh0SvecVyDIQUMVhdgKZCQ2c3V13obsPDc4rA8lJ5kVXc 1GgFUxhYeYwTEuhAg6wIzkJoiPTECIC9LN8w47M4xaHIJL/SpeE6w9jXREv5TYLiUq7dy6daYVU wxlqSFj/iqr8759Yawc4ZW5wPNSzMQhQlg7vTd7fuNp/Fdl4LWXztj/pEFIA92MGEKSNeXC82CO GF2HM0I53anZAXYifTfOZLhVg46wwd8HxckSq9CdA+zMT6TDpsX9JU1svX9QU3JTFgqRTwmXZQM t+ddUEPgLxZxbeip4BPv4cKo8XWUdCSpdsstWsuHroPtvqHFIQH8UAM9GeAGu8gqGT5tgpjbbkM MEW+r3Xh5WkRm/xFHuAS6cviK8CZJ7Mng+S0/PPoMU7Y+yR30GuBqm6UYq2IzYbAvQxO7+/BTLn w14ajliE1kuDtvpIQOpBGU2iK82DUZr3VuRJYwPLJdiFKnIldnBeRL5xAOxppsbJduvZkIq5gxg Bnr07ApVxuACWmg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Take a net-namespace reference in nfsd_file_alloc() (get_net) and release it in nfsd_file_free() (put_net), so that nf_net is always valid for files that the GC or shrinker has isolated from the hash table and LRU -- which __nfsd_file_cache_purge() cannot see. Without this, nf_net can dangle for in-flight files whose net namespace is torn down concurrently, causing a use-after-free when nfsd_file_dispose_list_delayed() calls net_generic(nf->nf_net, ...). Because nfsd_file_free() now calls put_net(nf->nf_net), the old nfsd_file_put_local() pattern of returning nf->nf_net after nfsd_file_put() is unsafe -- put_net() could theoretically drop the last net namespace reference, leaving the returned pointer stale. Fix this by moving the nfsd_net_put() call into nfsd_file_put_local() itself, before the nfsd_file_put() that may trigger nfsd_file_free(). The function now returns void and the caller no longer needs to handle the net reference. Fixes: 43fd953fa7e2 ("nfsd: simplify the delayed disposal list code") Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 22 ++++++++++++++-------- fs/nfsd/filecache.h | 2 +- fs/nfsd/localio.c | 4 ++-- include/linux/nfslocalio.h | 9 ++------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 03f01a0beced..6f75df344091 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -221,7 +221,7 @@ nfsd_file_alloc(struct net *net, struct inode *inode, u= nsigned char need, nf->nf_birthtime =3D ktime_get(); nf->nf_file =3D NULL; nf->nf_cred =3D get_current_cred(); - nf->nf_net =3D net; + nf->nf_net =3D get_net(net); nf->nf_flags =3D want_gc ? BIT(NFSD_FILE_HASHED) | BIT(NFSD_FILE_PENDING) | BIT(NFSD_FILE_GC) : BIT(NFSD_FILE_HASHED) | BIT(NFSD_FILE_PENDING); @@ -295,6 +295,8 @@ nfsd_file_free(struct nfsd_file *nf) if (WARN_ON_ONCE(!list_empty(&nf->nf_lru))) return; =20 + put_net(nf->nf_net); + call_rcu(&nf->nf_rcu, nfsd_file_slab_free); } =20 @@ -375,24 +377,28 @@ nfsd_file_put(struct nfsd_file *nf) } =20 /** - * nfsd_file_put_local - put nfsd_file reference and arm nfsd_net_put in c= aller + * nfsd_file_put_local - put nfsd_file reference and release nfsd_net ref * @pnf: nfsd_file of which to put the reference * - * First save the associated net to return to caller, then put - * the reference of the nfsd_file. + * Drops both the nfsd_file reference and the associated nfsd_net + * reference. The nfsd_net ref is released before the file ref so + * that put_net() inside nfsd_file_free() cannot drop the last net + * namespace reference while the caller still needs it. */ -struct net * +void nfsd_file_put_local(struct nfsd_file __rcu **pnf) { struct nfsd_file *nf; - struct net *net =3D NULL; =20 nf =3D unrcu_pointer(xchg(pnf, NULL)); if (nf) { - net =3D nf->nf_net; + struct net *net =3D nf->nf_net; + + rcu_read_lock(); + nfsd_net_put(net); + rcu_read_unlock(); nfsd_file_put(nf); } - return net; } =20 /** diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h index 683b6437cacc..88e397176c48 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -66,7 +66,7 @@ void nfsd_file_cache_shutdown(void); int nfsd_file_cache_start_net(struct net *net); void nfsd_file_cache_shutdown_net(struct net *net); void nfsd_file_put(struct nfsd_file *nf); -struct net *nfsd_file_put_local(struct nfsd_file __rcu **nf); +void nfsd_file_put_local(struct nfsd_file __rcu **nf); struct nfsd_file *nfsd_file_get(struct nfsd_file *nf); struct file *nfsd_file_file(struct nfsd_file *nf); void nfsd_file_close_inode_sync(struct inode *inode); diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c index c3eb0557b3e1..e3295bae75a4 100644 --- a/fs/nfsd/localio.c +++ b/fs/nfsd/localio.c @@ -40,8 +40,8 @@ * avoid all the NFS overhead with reads, writes and commits. * * On successful return, returned nfsd_file will have its nf_net member - * set. Caller (NFS client) is responsible for calling nfsd_net_put and - * nfsd_file_put (via nfs_to_nfsd_file_put_local). + * set. Caller (NFS client) is responsible for calling nfsd_file_put + * (via nfs_to_nfsd_file_put_local), which also releases the nfsd_net ref. */ static struct nfsd_file * nfsd_open_local_fh(struct net *net, struct auth_domain *dom, diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index 3d91043254e6..7267a69092d1 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -62,7 +62,7 @@ struct nfsd_localio_operations { const struct nfs_fh *, struct nfsd_file __rcu **pnf, const fmode_t); - struct net *(*nfsd_file_put_local)(struct nfsd_file __rcu **); + void (*nfsd_file_put_local)(struct nfsd_file __rcu **); struct file *(*nfsd_file_file)(struct nfsd_file *); void (*nfsd_file_dio_alignment)(struct nfsd_file *, u32 *, u32 *, u32 *); @@ -96,12 +96,7 @@ static inline void nfs_to_nfsd_file_put_local(struct nfs= d_file __rcu **localio) * must prevent nfsd shutdown from completing as nfs_close_local_fh() * does by blocking the nfs_uuid from being finally put. */ - struct net *net; - - net =3D nfs_to->nfsd_file_put_local(localio); - - if (net) - nfs_to_nfsd_net_put(net); + nfs_to->nfsd_file_put_local(localio); } =20 #else /* CONFIG_NFS_LOCALIO */ --=20 2.54.0