From nobody Mon Jun 8 04:12:11 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 8A8F63672B1; Tue, 2 Jun 2026 16:23: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=1780417410; cv=none; b=spdEVcOGMc3c1vsHFx3h06C2YERiFT49fibzaI4mtSt/wr1HNDZ+5ufPoYeglTSohCqKP2LSa1zj3XLZF2MtRTK6YHHDWtnqU/k23IMVhEX7wbXC3JG7GOpCIjYw5Y40hSp8d/H2xFzAFC/d8yP2H14MtJDYvMgI56UrAIDHiFE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417410; c=relaxed/simple; bh=8gmVfN3NJAp5KEcLS1LfYVQdzKCLVErpphQJ2oZvgRc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=m8XI5sKXXAppUnT5u+c9tvLWYL6zwLPGmkeIYyo6+b3c1ECurmxWs2hiGFPUHlEBsYt3hvUss99YIxG+Lw95gVHWukYp4DpJ2Min08sIBaRGyAIehGXUT/dOrAzBvDJ+TzKjbW8fvKDufGvjdR+AUDmGtkap1Mb+zOlD/51W73Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Rk6rteS7; 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="Rk6rteS7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D054E1F0089A; Tue, 2 Jun 2026 16:23:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417409; bh=RL0SDFOGPEfr5cBoJJZ1vB2wDljK98S1sH8InkqDb60=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Rk6rteS7JEbcuZa6EiITg1q0KOSeNJrabLyCriRrAMrB44+i7DkyAX3gi75IyGJ1l 1gKifr7BSB3A5qv1sfByT4MAZzwpDb1KSxvzcnaqE4ek/hOA3uClaAUKBxrSiCQzNZ tCr2aZGL0u5ton43ntbGP1pApRmiUnhmEdLKUmIve0aTpYQ5m+VUNjYAhpYt4zYavY XuCr3OKYbc1TljqF32BdTmQM1oR4p55QhwrhsyeoHr43z6KxH9SNeHsFktXlL3JdxP dcPyjVrB8TNYcwVWlt+jr3t72OBjfUIx0TmggEG3PYb8Yb8r9UFsfITMfhZifmTWdv gPEP5RZVY1Bww== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:13 -0400 Subject: [PATCH v2 1/9] 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: <20260602-nfsd-testing-v2-1-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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=1858; i=jlayton@kernel.org; h=from:subject:message-id; bh=8gmVfN3NJAp5KEcLS1LfYVQdzKCLVErpphQJ2oZvgRc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN8myL5xm+TtumeR50TKFtNaKBYLMhTOgiNt hy2fj+OybeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfAAKCRAADmhBGVaC FerAEAC1XGeX5v9BcT7lZaVu3i0b40fZdmmzM530cXn4RsKS0Q8X/sECpX4sIJpboTtLiq8NkVG TYlKKA5holp4fQvdIpfXDbyzRehZE/4K/mlbVMfaMngppWsFofzRlCxO++e71LE2carqD8W3ZTh 1numu9CKqb63ShiiG0wtePyGNzr4mlaea4fWWxQeJNB/Kcnl+scdXVWEPKqeXDI4dha+UlgLVT2 U3mh6rI2Ihm6eun96OFpIIwlNFcDbwoI2a0hMpkRYt0QdElFxeLmgdmXRbvUw0n37GP3BYFM7Vw wt8Rd4tIYZDeEX4AiUUO5WNyQmiEcFjpxYJc0U2oH+sbjJ6PzChJ6Xi6v8mYiNIPR2z+S58b+/o DEGt148y+e520cR4Wm+3K8Nkn2C4tssh2LicyeksRaIkRsEL2/DE5UNVi1LTCqOKuxwBd1runnH oNGywgMBvjzsDfW9By2hlO85XKPs6KWYxjxEWe2RQONeJlbaLHZFH5AF5/hxFiMfrexcerJpVn6 27JbAvw/ob07idTxGMrzjLFyzixSyHRvpcuFxGxJBYhqTACly7qJIxOYNVvpSzeRRvDHcki0zYG YrcYSa71XPT/hD7GY+cNubGhzZZqJPK+hm/1aHdb2n4cExollNOqI1uwkEvcuvJB2BZljYcfqEQ 1A3WOtq9UbPb9zA== 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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 487a1f62ce15..6680e9e1e5b4 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -6686,8 +6686,10 @@ void nfsd4_release_compoundargs(struct svc_rqst *rqs= tp) struct nfsd4_compoundargs *args =3D rqstp->rq_argp; =20 if (args->ops !=3D args->iops) { - vfree(args->ops); + void *old_ops =3D args->ops; + args->ops =3D args->iops; + kvfree_rcu_mightsleep(old_ops); } while (args->to_free) { struct svcxdr_tmpbuf *tb =3D args->to_free; --=20 2.54.0 From nobody Mon Jun 8 04:12:11 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 4260E363C64; Tue, 2 Jun 2026 16:23: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=1780417414; cv=none; b=Sr1/dsYHX0FYo12okT+ZGiSmg683ol1uxfHhzlg7ygjdQAfPW0y2a8Ufjr5ACP3w0vd45g/GpasxQPecxhsVFcH35i6IS+VhNxq2Cz8IiZOcUYyKNjaohL8lSshX40uViRcCOq0N+3NfmDYLL8gbzgxVxgVfJv3gPvaP8sm5kDY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417414; 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=WBgg2G/L9SUWSOaEUl1lEyKkNyWi7D9U6u8onPW8X/1KqfX/8jXDA4gcLpu42iHjwoMWSuEUqxvFQX8rxjtRF2TUpdsgU/oa+/4HOjzH+6+ZlwCkKZWmSaEAQPswWTHvwKB6VNvKBIWbxqcwsnaC/zWgAufUKeAbcohK+LKaHOk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VXST6N4P; 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="VXST6N4P" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 772FD1F00893; Tue, 2 Jun 2026 16:23:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417410; bh=guAkVFVqRYjiojYXLWG1CxAWJyMoK1eDqsYRwZSIzfk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=VXST6N4Pd14NHrtuMnsroOuRUU4QgE4hIWwEYYJz+wgQ7yzzFPsVrzWTNXdb1rSNO Ix2xj/En1YcwEt6QFF1ZPj/H7KbW+FBw2SqvkBGLfIyOGAyl0MD3c8zumKghsFXUH3 rZG18zpdM/IIm/VxtbRtHu9gDtcrnVbdyyD4ZPXLXV3uyMj/odN4RoSi8KLG0/ZTpp Y6VVW9nmNrWP5s6bRkC0p/seNzOGui7F3yIDjoB08ApXuApmiQDYqm5DreIyhsAOaO cIbh2OFp4DE4Y9x8yGuc485cKP1jZYxZeDbnAR628A6ToH5pUaCcH6C8Bz68EvIl2U lv8TGW8lbfSNg== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:14 -0400 Subject: [PATCH v2 2/9] 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: <20260602-nfsd-testing-v2-2-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN8jYObmlJIuR+vccAF0vTzzCfqI6Aran/9s cTqqn1o2TWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfAAKCRAADmhBGVaC FTPIEACrXrlwt4vPofjbpQG+LsZmOOIiwKyNX32C8ilD9dR4Fl1oIw6xOwO0WwcPc6jarE2jgOw NKHp935GCUNTJuXHXw84fzCEwXJK2UVPQH+SXUmlSXwwWQB02qXCFy669XSvfqQ1uuOKCw4z0Nn aAfYpGJC6a1VlLOwQUxhZevTIal9df0hJdxDFQ1RsqdOxSIIDs/z/w03ugv17BesCfE0F7/Xi0D xt7UVbj0Pt1u5UJJDSZQ1QZHWiR0MERJAq7n1VSlvkE348ikp99Cp+hQCb0J0ofB4txN/PuQfTc QWkb4fiUeIsmgnJrPJsHF4bT5IzEQwu2qF0Zff9v1o2ptLh4JPVnvp2uaQ0rtYr41+NdrnhcAAI 6GMYi6q7lOR7WSRrFccEBRSpKByntA7MXp3usOcJ1RTKdDwYPrMup03vSnj4e7cfkWk/jaFYWxR eY4fl3mvFuvdLu6iGluoTr549BeuBk3yCF98CNqe3Y08YsMMdx2ceJHJZpzERc6AIhm72tE10rC RGAseKaUvk+vVmWRY/LgmlBxEBjDOaiioc7rJYEGOvUy6kXSPdGv4Jw+MDqQ0pFJMiWiq5HeXND PIYh/hI017+8G1F3eRmnu1K7L3uwtbFTU267L5Cs/bEIwYD55IiDRuJxSe5TxjT5yXutyEruVWS 3zFIgscVIC41l7A== 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 04:12:11 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 C847536828D; Tue, 2 Jun 2026 16:23: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=1780417416; cv=none; b=Rh/5PFDA/ywedLaFRku9ik0/te/7sEyTtVhhNFMWNgMrte/9SQPhE4otP3WSSrT6L1WkLmmeq+rPFHozO71WgCnmYCKGxr0QIfoOyybrIAVPAdRkv7fnv1UnH4T5HwYhcdnpfU/t4Vi84Ib9feXJustsJ+5fYDh1mdLL31y9lgs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417416; 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=tfItsq1qLyEFW9Zi742FxxVw4aYXM0R9eZ0zGTzgqMtwsPOaH0n5X12dWVriVlpuw+YpvgKAdP5ndCnFJmhNQ97+x/EkQdGvtq6S4/rXrxLBc/WH/YNTnUITTfvFEF2Tv0XV6D2ML56MuZdoFsr/joOpLlE5gLKX7rvEG7ecj28= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ovR+DRSc; 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="ovR+DRSc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1FA131F00898; Tue, 2 Jun 2026 16:23:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417412; bh=jO/o2PhsFYiMTNYvyXUl1epDYlP6z+nKUYpcM7iOoL8=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=ovR+DRScbD9G9x/gHC1An4K83HnEXmo2WG6wNTfldbVu0WfFSDGXBRHsqUSX40Lng W78kxVq3ef7UQvErI9q7q70OsSnyW3XrH362qOU9jcb/DhagNu2e848prTexXDVEr2 UcQXBDHdBU77Xqe8azXpNw3eAsJX3b4/TNWXr0tA8RhzjE5GiX0oND1Wx4Vz6Q1QLH xP2aPhltiB88EcEppH8n6Pp07nbOMlepmnggimg4q7xAJF1APBztli8gFvEWODJ80I ouWjlWPFD4vcVY+nbzY2BsYqRNVVZbI5fKNs+xrxWl6MICOukOMs0+NyAUvuCr0l6C YNeJFjC9GXc5Q== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:15 -0400 Subject: [PATCH v2 3/9] 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: <20260602-nfsd-testing-v2-3-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN8/ppH6UYhAfQxpRuM39wzZRACc6ota6s3p ZrhR0LFJ++JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfAAKCRAADmhBGVaC FZdoD/9swTNdkPgL1db5t9qt+HZNU/4YFPe5FdTcK9Iqlpb6Pbc2WEqYPv0sUU/45KWKi4Uciaj LS9BAoJN8csJaTE41hmjnYxI3wlcyKseBO7g7v3WQTTmegn5uTXwckVXdcwy1ZbSkDgIW7mKZow UzqEsbfwZ6cCqJp9d9nbdtt+SMifktVjJ9CeLJAHELf1NGXQyOAmuwcMI/mRsZLIOkLpP6H9Mb1 q1zNzNc7qWlDnBdiVTOgFGuHCwz5RcyrTYXnjB4uN5TwaBKmhVYCB1N8kqT6OSGodccMqaErHEn PNupLFJ5MXlbyn9WfNm3oZmLoTNJHDNJ+MtiGIcbFju6a2OEaTR1V8/9MJxMxh5rxTKnaOY5NVZ 87TTNTTBpXXPk6BdRcEUrQwtk1AUsAFRwBo3TlyM5G/ANpNuVpPvimHbi4NNHy0jggB0K/eTTDA rjV0WWzN6aQTR03UGJ/xjfYUtJcnxF8TllPUiqFBR6XNP1r+rKQ7x89Rhg5B0H7X/RMQBZ8lHz2 Z706a5Y7UwHZLBbfc5H5Aym1kqIbq2ZfihURUS/T1s5s6sY5kd4jqUY0W4LPGiKXBC2gQCZzHAu E18vhOsGLNH6ppdGO4V0oFNoSdihz6dUXbI3reCGTofGERmE6L3F2qe9u9HYTyrIuDzSpIwE98l v2iTEWCuL9ljAXg== 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 04:12:11 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 289A4368D72; Tue, 2 Jun 2026 16:23: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=1780417417; cv=none; b=SwhezT8IBF0G+0HxVqT2GTBD/byUCdj2SuHciVZZnTQkbsjbELQECKdPt+TPv6TRDO5oHA3ySjHJEUKAqel5/k78zbracPJi5zrjCxQinCAUwIZTmlaw+i6XuKn91KVhMWN0o5Z+WHMo4aR6xRM7xfnrYwnQnR3Gcbs1DVaNOZA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417417; c=relaxed/simple; bh=5GmFOsoGsxUoKK42L6oIuiqD2T2yto1PqXZGDDjnR7g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EnNNeAozazXQOEKPb+y8FhszKHpYqxlzi13TsJabfCd/35X21PaPTTVjD/knOz6Af2XCPGaExf/Sz3zuLk1yQB3WV5BkP42oNyc3osnKBjNELuJ2RZug5CCy348+6zKVPXybB4x4rpU9SnYZofDNXURi/+7jwCcPcqXPzK7lda0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H2JxTnCo; 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="H2JxTnCo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BBBFF1F0089A; Tue, 2 Jun 2026 16:23:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417414; bh=GQSR5xDyG6bHaFaZRpDiOp0QGRNuyvccZonIX15jpMg=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=H2JxTnCoGu8WX+wzc0MAVusSiHpKZHuXbdUz+08I7y2B7kAsXI3hjFHxVc8S+oqiT iS9lS9HvSFzAWRQnkeqU1ZQNAEsjvCkth2rCmES53i3z3nL2FY8ucFagOj7vke10+G T6OA2lgSr+XrBpkc3huUHx0ZnZGm0Ewd8U3FITbU8TjkPSYa9A3cLEq6G+kCYuctpF MoEIERYQZP2BsEW7ipZu2ThDMvAhVDs0D7oxyoGPNq8dRP+c1Ib8r6vlXkwdfJaAiC exr4wp/5AV1yQWGibVY9qUbxaxnwNhJVzLm69yu4aSq7jQkmv6etg0LrFxBLyln2b+ 2SCVprRijCsUw== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:16 -0400 Subject: [PATCH v2 4/9] 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: <20260602-nfsd-testing-v2-4-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN80PjCqEUxeONFLfla8q+g3gzpvZ0XzwiXZ YUbBiG0RlCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfAAKCRAADmhBGVaC FZRMEACFfDgjU5J1YrmZbXO8B9Lv+beB3Er7RfTK/OvPCmJLNeo1j6f96yUQiZwtPy8njX9nVeV OfF9u7fKHzxh5oDZV0LIQ7eDxCU5X4u7XcejqYzMlHfrGZe8A5KBgC0XUGeBsv1J4znB2h3t5st oDgs+hbEpC6rrhLgbKufoJPiSiJBv+iu5Cvt/gJLvLNNtTvMgQLCtBgNGuj9hfkm253xZ0tA1l2 7qmJ9hnqUvxobl1l/XiFLEhs3RrbTZ2sEE/Y3Pu1sEgAZwR6Hxudn15evvzXYB+G3WO0+0J37Mq 8bZTiIsjDRw41MIsyxTFuXk1AUXOkrSKr9nBohkXjn45gZNhYLGRyTeCFdCXQ3gmRq5FyQ74gEU p/I3gQOIyxB//XvI4/hjmD8Gv1UarOS1Mbsn42mZj8VMIEpCeSj58BCDdSXz/SEPOhM0r3OzUhG IW+VRXryh43Kw99olGhPZQXtgCci7mbIvJO+oRdmjBjH46y5QJgjcXCJfIGJSA2ZPug2KXwJyso JunBN6DRxF8jwC0ZSekhJbjCrXqJEyPXYkdmT5b0zuNkglTtIe5F2SsjrtqXklIa4VpcBjQY84+ XZMZ0trkDk9wvTd+AhBLQMWvD3NLp5FAVesM65A+xgjzj1h2eRUG9HnGUhn2txCs1Tq+Yiy8Jh8 xTdtamK2xhe0Slw== 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 04:12:11 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 28916368D68; Tue, 2 Jun 2026 16:23:35 +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=1780417418; cv=none; b=iJXx1lu5nkSwgurizD5lWBK/856Y+1XFV97D4kVq1s21NVVH2vS5SEUTRAR0G8Bxcz7rZ4gElBPX9Y3i0JULMs/uas/5Iw5hGYeZae40e6bwNmXE3XkWJ9tG7JuBFxzLbGxDMf6x43V7+Hn8TCInRp/egvb33nCXhYHYydkvKEo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417418; c=relaxed/simple; bh=JnC/2ourKTNHmtFxJc84B3W+7hBsSIk7VRR8Jv40pdw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=D9UzU0EhMSUzRTchjo0FapipSb/1LHnCKRWzVE3m1byFNGirBmy5h7n6nmek9Nni9RCNRFxeai1thcSTuMBdk1zlEaQYH1KbROYex/BCeerDhg+HY0Dgh5Rlp6+q4/Gw2PPSDJq1GLHTNEqDobh7NltzN5n+ZkEl/Z5aYXnDMgM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fiHMbtkA; 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="fiHMbtkA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 639911F00899; Tue, 2 Jun 2026 16:23:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417415; bh=uur/XWzh2Vx/jw0lVJDfyL9NUFvYWLGaQ9j78hmG7V0=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=fiHMbtkAna/B0G7SV9/ZISiNnyuV3hE7ZDu+CdnJ+mRn5o2ghk6+CLalDIF9OSxf6 SZcK/0BsAdProamayUCi+1SQNU2G5crRO/3rhZFWPgmCmEHGlzUxWqpsDVXzfJ38+n LnMQUHneZM3oeQSLCc8CAkxHsHp1aG0lMWAlcfXYMu1UF6edCtsM3HyvCd8LVUspAw TdyBN/LbrGVGyE6wVlya8oMA9KopLHLabyUqs9go0JraKOJDQmaG8qbPjorE5QSbmd aVfjsd0X6zZ5cPBvTpV4rA4mEaN28NnlL8FnMofwXcWZP2Hta0PTCO01+3aCKKazlT eYam4Wt4jOOIA== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:17 -0400 Subject: [PATCH v2 5/9] 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: <20260602-nfsd-testing-v2-5-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN8P5WCvyacmiPr2qKwynKs91UiKOlNuPuAu uGmqeXoElWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfAAKCRAADmhBGVaC FaKiD/sFOExLv8pQqzSE5crQTwY+JB5qVnvXSvR56vjNl0itIHvDYNexNw6i7//FkzhMjJRJCX6 /aHW0VQugrY4dgtxe7SAZBNkTk73Qpz9ZSQTBu3gOCDXNxtbByyG0sdbn2L8Js64sQF1QsJr8b5 nAj21uzuKp+fzHyE4kpmAvFqxmHHoUZQXoSwJeasMSjr/ISCuM+iMsCemNm4JFLNde6kdtPNhY1 f8Uu3kjJKewEYOx/ZLDfKZGC8bwTICOmSFfK2xFX4AlaCjk4wKOmTIWly6gt5Qgn0yktOBKTCDz hDjofPv+YpypqOS/kKfSVOaBM9zwSIEttQhoJxT1V+uZfPrYRY38WiYJy89JR+/OXaDiLvksttA m89YknBXqxX5WYw9UkxbwZHbI4Xk+Mg8zkbKuLzy1aYFgm7N6kVW/5eeDVBBgpWLK7UmB6hm8MG oAkJhcqo0Z+tYFfJoYBLQtsznlUooAjuVNhPQ6cfrxXnx/BE3eNZL6jkMVq53LqJd2/P6KWsyrs o3hHV76KBBg17fdbERQBmZB7gfrw7G1S1DseCUes5B2lRt13IlWB+TdpmoY71oTpKjxCe5if/II m8EEOGhgBuEH4Mf5PmieR714wtNSHJyVnCDifaN+KFXqAfBD3MDxuLgHRyQC0m6Qr6zrmbgI/Js pslTGFGhRXWtiYA== 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 04:12:11 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 80318369D7A; Tue, 2 Jun 2026 16:23: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=1780417418; cv=none; b=dOqhgKKxNy85odP6AtCeiPk0pfMN7cYkihZGT3MqOjtImNQlexSpjXaiXG6fmE02sZJuqXpi9WbIV5tIGw/6ZK2vGZBEskXdszakXNTLfaQbh+oQyLK5JQB+OxqS2v7X/sdkzlWb9emX9+x4ZGRGVURWBUqCC0P8YwdNDE2Qwpk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417418; c=relaxed/simple; bh=zmfzxfk6E0NbX309OavYex7lV0fRj09UZiXgnfOIGqM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MyVSI0FLqtonVLZT8tcwSrwKjt4rTMXyYS3TxPHIGB80owPF1leb7Q2ySh2bj/jtp0SXQ+PdZquZYBvvDQgEoz+vVvD7fXka/QAZJqXHyn6Fu6+pYlKMRjSjZWF/F4C2rcPzOqiTymjT2XXAHTk7WR3VoyVZUvPHq1sHve6r/xw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WApEpuG2; 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="WApEpuG2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0B7891F00893; Tue, 2 Jun 2026 16:23:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417417; bh=2O6E87EFPiFCpLU6dL+tj802BACuDUrciFMJJtwN128=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=WApEpuG2kpQH+3g5gz9BQZuzjXoAyrm6uW5uNP71aKwB+mE+LQWUrzr3w7c+d5CBp bfqoorzRzA/N8dvDSAEYJEfsBABPXhwG6xoRxYLmKI4mj6ASrKlR0S4mJ+jCTE+ub+ C4Lx/n9ZrqJw4GgYN06wvsVOg/zFwZZe/fh1oe+crCGiM5sleyVh8XyGc/jgcYnJa8 7zpijlSsLTBDzrm5VQikvdMsEgVDxiAD1AZv08kijllpT8fXrzQ49gHI8b7Qla+SDf oMwCxMEAhQznlMdXm+W5eTQZ6sp6E9zZrdUbeVQOVVCZUBNjKOmZPGgL2N/7YYp/Qr Es//2sjXEDj9w== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:18 -0400 Subject: [PATCH v2 6/9] 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: <20260602-nfsd-testing-v2-6-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN9+kUEmdxA5gopCujscY/qGgB1FYy/Mwuqx s094P0OfoeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfQAKCRAADmhBGVaC FVORD/9ZDlkB7pdQqehQclYxSJzTPWDU1YQEDCdaEpGwisL5qJc+dCZfAQcyCSnOi0dyVkGqLik 6xiQZltFMQkbo88EY8Vu90hT1WPt22a9BYlKHNtKFStNrSDcvfKugc35XepdKGV7WtNkhbwLd0U 6xqaN0T/gscUWJNJIc5VbWpU7aaEKgES39pwMjnMa4T5llPdN2T6HdMR4xeec2C3Q052HaGnfEB f2roieebpxIHZRR/9wWYQk4ywaapHtzb+ao8eyQljNF8qjbRXMO2RhVneFAvGodI6x3gUgWQiCE iPsMITAjkVuegUcR95Z6M93KcFPF6qUAdiguscuGtcJpXIW7Iz72uWrmY+3g6/Tag4UuCJYRc4K UG9wj4/XZj40j073NiPLmGlYrmQYf8oYiYZ573tACiKyoJ8McVRd47s+orYirkb4aTRCg2oPZWh qwgjeDs5fKnHGIc146BtPmP/H9ZSRvuvmLtm8Q/5XlIFaGwkC5jouejmiGId8FO+Lc2rlZv1hHJ vW4+3KKeiqFe6hksvtZpoHN9KVRAPY59IJln2EgNprz3qq+9nvZdUA+PHb7Bdy5EXHxmLPxff2v JL946p3ZsRzEI+YY5AQAoS6kvIJJSxU6xItCfk/dEzjussz2xjQsRkph9B7DDXwYu10HpZwoLcz flikthgu0RQaH+A== 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 04:12:11 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 281F336EA80; Tue, 2 Jun 2026 16:23: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=1780417420; cv=none; b=gqPzLacRYwB03FSs6ZVva61Q5N2GMTNIqaQhoQ5J3yKawn1GozKo4b0V8TpTuC1W2Qg9KJnSZ+bbq9AXy7Hzvw0nq+ZNXas5b36g40FqxJPd+0Q5a6wt2XJG8X/a6Ww8nYb3mLTy5DuH+1g+uaiNA9bRp3mYXcj0gUpdQFXFdV4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417420; c=relaxed/simple; bh=4p1CVpcJ+A7EaLxF7Um3E6hVGg91UNafTKWuimRUO5E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=srQ2BKdu1VjVMp15WipSeGgOQuSOTyG77NzT4DczH/gXojJGynJi9luXG/XWj95g7jtmA0Dai7xZYF9Xez7BfAnP/WUZ2yTkc/Tu+ShD7sV1dbzuPK4xKuhakKiqHyoStA67PmU0vVHSXQgQFvsFcam0Meu3klMjreaNopM0wxE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aAlssH8L; 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="aAlssH8L" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A8A931F0089A; Tue, 2 Jun 2026 16:23:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417419; bh=gnQV3veSdBsU4Xt2Zlss8tJxAFnNE9xWCwOd+DHr7Rw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=aAlssH8LwQ6xX5Z7xnLY7egyOHVw1flxv6DyXKmokpWdRCQ2goYuNExdSSzzTfQOQ 9AD+xIDeEpXY3oEEKjJFz/tSTiNnZqZMxELS+7Cfdnvihgt7AzHeifGx8BaVutIXFg /WCYKfVplLwN2VvNxzrZJEZgJXTLrrJBo+BEomxHSex7ePzdDMhgZkTZXBI484z270 q3IJeaL0X+UGn7VZz2vkdHLuZqJ+zHfSNGcOe6LiZvLh0AsiRHu7WjKGpvqrL7sdHo yS9SgBd+VhuzOugmHrZN8bninYowqPFqiku2p71KePY5CdZaRcGZaH9y3vyu2x0cjX pu76TXVN5+3ag== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:19 -0400 Subject: [PATCH v2 7/9] 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: <20260602-nfsd-testing-v2-7-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN9gB2TyepAZU4ISMLzdxfx/D8MAUA7rAd7v huJFjZ9Ih+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfQAKCRAADmhBGVaC FR5GD/9y6r8qo76cG3i3OOWAy33nfqUJgau2+KBc7unQEGIgvCvBFtiBpbNYG8j+7vChgPskjEB cAzhu98QyE9vWRX6zqNzzKaVlPoDphplPoq6t4MDvk4XYdnFyySiB5RDqnyk7lEyOi64dfNe4G/ 9f78Bt5pBLU5OzI9IZbRJn79CYht3COanPSAN26j/XPMDkoCc9erZ8LdbLVdsUnCo2vDPy9mSKr S87vxTlYDSzlelnqZfnok7Kz+0S1n3JZNkN/8BqBpw0RefrFlQtBOloieZ3/fySsvc45F2LnTC8 wqqQ0dd2U+cco79KmfoA/sEZSk+LLUqRc9oD6GgdaT59HYnNB68Koa7SvPU3+j3E7FCkxtttSCg f+mdyr6Q+/I1WOlP1O/d/hIl39ekQNw/YLM0PAHeMsYxLOxVgdbfdpwuYYerIdluU+T2DFZOKvw NXoIA+f3RYEEbKn+KBY7y6Mmx/cmBI0fSaLFYqV9Z/D4YfKUymnR08D4sbWAkFqg9HbsAnrZZXi 24lpHeq0LQDxAjDIB6Nm2E7/4cRNdlquGYVDxyLGD2E1aMOkzp2q9P5iwZ49fo4QSxgaARjq6rw 4cKYYKdTt7e3yRyDizuBM9JWl2O/0likmxp2I0uBUO8yZYy1S6E/s3/AXskq+0jMwWE5El++q8E 073yfecz/WRZFdg== 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 04:12:11 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 C4DB4371CF5; Tue, 2 Jun 2026 16:23: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=1780417422; cv=none; b=LK0JpESQS5MzK+K4EbCjmngaaoxPpK9GlJtNUdWzjF2IjHZlbTa5+URY8EXFedqM++DNkaHEnUnAj7lDyE5IIUMSgalv/jl6N7HG6i9gx+Ek9DlGVfpbPNaTZSzbIRITwK5w7YrEiuNCvZ4V7BWwQMsiegQhsaCFmrevt0Ahrsk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417422; c=relaxed/simple; bh=2jtYqYJliW0HX+tQbmsi0nWIHbXBjKvAtlZaq9fORZw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EPKtushgI1/txE1f/USljubWH+o7W0M9JarPOeP4hNpYtxQY+PzND4FBHex0Q1A+NHo0d5elZNm68bjn3gMFauptFDJnYqkFFGJ7Ft4I7gQ1AFMQMSQMP/s31CSrrN/SiCncfp/nTx4gxAMBDr9ATVufObJr5nBFa/yCEXi3zHU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=G0bzexoV; 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="G0bzexoV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 50A001F00899; Tue, 2 Jun 2026 16:23:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417420; bh=doETAbbXlih2TgtqnyiZ2/x7ee9FFTG5PiGNE64Nszw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=G0bzexoViK1Qs3oxLWv+sxBY+Hg3elL965qKaPhJMvlT0qxgVrPV10jyIPTqGBTZg tUTLv4xQYEOQBgVgOninD98YROqcJynk85UutzTR7GX+KOvyl3Aymk/JAI2Tgph3Hn d9pVQ6ieGxXZB+tS3GQBrZbA8khJmXZQLA6dNsKJwEbhy0pjuolavOLLUQ+ia2/XfV XsAxA+dfCiZTwOmoMHBlFFI4Ga8NvIjBG7fEvAxe2Ypo/CGZAbjFn3ezj3svdO3nyf rZ08/oMjTAsKHInY8bhgqF8iRg69aQy2+sPb4b1SYiMNYmopRgu/9nDwTaYJ4WDEC2 Eg69AoyofaGXA== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:20 -0400 Subject: [PATCH v2 8/9] nfsd: hold net namespace reference for delayed-dispose nfsd_files 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: <20260602-nfsd-testing-v2-8-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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=6658; i=jlayton@kernel.org; h=from:subject:message-id; bh=2jtYqYJliW0HX+tQbmsi0nWIHbXBjKvAtlZaq9fORZw=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN9/l7mYJsrhcmgP199d6d35qwkABOIEg4K3 HEL0EW2HvyJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfQAKCRAADmhBGVaC FfuAEADAW8yzUikfxcgRlZfi30/bjzcoJOo87KSD5Yscic+xWi6XVoA6WGJyyzTKULE3f5m8cq6 wEN9al4OU5w9pmDRxVCq5V1I+DBEwedwo/KqCtXAjeK096ZWvuduTD6XFheh/qFzv7ddrLEVrqi /XTRACs/otAgHzSo7Kgbu8sFr3RpcbxJw2ZpFqv2P4cUY9qCMsXaJSmIJPe6R1JWLZAgVsbXQ1b SkLLbzVNgBRcKrfFTbnxg8Tt33u1mV6tsArZzzPdRt0w6XYgAaDC3R0Vm4/o3mADp5hmXoXRIk9 Jrtim3axqOrUAeXxD7hf1eNB2+DJfd9IUs3wjMDn7W4/JGbhUWLOcagBNebWeaoBjRLMBOjs2d+ vOURrYOdhAjGZACX4vVfEeWsnuvjQLdarzD4AAV2a6nlEkdCgah007MLTktYrg73/cRyaJqF2g9 Vzj/qM09U9y3ZNWZylXelQMqbhZrm4BHrEH9kZDP/z84MalXltm8/pyorryXsUAQ4s5awuT9Gxc MHszBgeVvQJrD5aYU2EjXEdpPANOcO7GtvFqWu9HbXFGPamku93Va3131FGlpLPtky7Vis4C9ej svYpBTAjyl3Db7W6NB9SfqxALLDjzWCbAN9JOaUJ6tLNo+MzDwWVH+QMq6NBUyo9EUnT7uYuF/s +yGqkcOUzt+zeEA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Take a net-namespace reference in nfsd_file_dispose_list_delayed() (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, ...). Only files entering the delayed-dispose path need the net reference; files freed synchronously (non-GC stateful opens, purge, direct put) are always freed while the net namespace is still alive, so they skip get_net()/put_net() entirely. A new NFSD_FILE_NET_HELD flag tracks whether a given nfsd_file holds a net reference. Because nfsd_file_free() may now call 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 | 34 ++++++++++++++++++++++++++-------- fs/nfsd/filecache.h | 3 ++- fs/nfsd/localio.c | 4 ++-- include/linux/nfslocalio.h | 9 ++------- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 03f01a0beced..957fe57be063 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -295,6 +295,9 @@ nfsd_file_free(struct nfsd_file *nf) if (WARN_ON_ONCE(!list_empty(&nf->nf_lru))) return; =20 + if (test_bit(NFSD_FILE_NET_HELD, &nf->nf_flags)) + put_net(nf->nf_net); + call_rcu(&nf->nf_rcu, nfsd_file_slab_free); } =20 @@ -375,24 +378,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 /** @@ -433,9 +440,20 @@ nfsd_file_dispose_list_delayed(struct list_head *dispo= se) 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_net *nn; struct svc_serv *serv; =20 + /* + * Pin the net namespace so nf_net stays valid while the + * file sits on the per-net dispose list. Callers (the GC + * worker, shrinker, and fsnotify callbacks) always run + * before nfsd_net_exit(), so nf_net is still live here. + * The matching put_net() is in nfsd_file_free(). + */ + get_net(nf->nf_net); + set_bit(NFSD_FILE_NET_HELD, &nf->nf_flags); + + nn =3D net_generic(nf->nf_net, nfsd_net_id); spin_lock(&nn->fcache_dispose_lock); list_move_tail(&nf->nf_gc, &nn->fcache_dispose_list); spin_unlock(&nn->fcache_dispose_lock); diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h index 683b6437cacc..7ae3c0ea0a2a 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -45,6 +45,7 @@ struct nfsd_file { #define NFSD_FILE_REFERENCED (2) #define NFSD_FILE_GC (3) #define NFSD_FILE_RECENT (4) +#define NFSD_FILE_NET_HELD (5) unsigned long nf_flags; refcount_t nf_ref; unsigned char nf_may; @@ -66,7 +67,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 From nobody Mon Jun 8 04:12:11 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 B3647372EF7; Tue, 2 Jun 2026 16:23:42 +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=1780417423; cv=none; b=IMbacN2p5MlZbqU5NCjRtpaXOaNUk2ETJaUarPwk16l814ezBf371+Qm7bPqH8F6KfbcDKGIsuobc11XuRBF8KI9rFJRoCCOSrT6s+NWAedYHarVEqR3YUbwFvIBIE1/n3JsIhvbJ5Ql/5AukjIAvgZbC7LZPzDCpp7Mn0PGsSY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780417423; c=relaxed/simple; bh=+Ubre8QpYtKO3e9ex0dIdwJtPoz/vECXWGeLxuVlxiI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rKu0wN+II3KwJ1FowtoGRCz1MUD6mQtwU6Z2f4vufqMknuShs6og9WIrLK2sc9C3xH1ma6Ef7xrBtIXqm9xtXXYUJIKXi6yyX4DZ6AWJjhaLLmT2wBXDkp2G3fkfdi3SSKuR4tpmyWb+TbavqqOeCBfP0uWVL1CXD86LcQciGqI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TaokMivu; 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="TaokMivu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ED2F21F00893; Tue, 2 Jun 2026 16:23:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780417422; bh=y9cLzj44jng+XH860E6rPj8qhAmptMmQLurtzyF05hU=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=TaokMivu3eYc5yfD+kd6thL/ab8BUq62D03Ppud6M9xLilOs+f5vkwuqUvAG2GXtF ekIuiSIUxBjNTmq3sDaZTl0doV6XjHf2ELZYr8QqOxjuYsfPt5PWiCETuclWP/g8yl ZCAfB41VBPoykwBcCCqGe84aZ2+or+2cT9wcPiyZ/emc1v5l1zMegJ/b3iBa/Ksc83 +6GpXndEWlnoBdkRSO5lFSzUULWw25RQh4/g6bbdxXUvLOnQSuZubP+Mvs3xISPw4w JU1whZboZ5ga0fudRIZzRNUti+i208GEZowWdp+PgI01bFTDdyc4j03MvkUECJ4zf7 dNV2NdeDD7llw== From: Jeff Layton Date: Tue, 02 Jun 2026 12:23:21 -0400 Subject: [PATCH v2 9/9] nfsd: unify cleanups in nfsd_cross_mnt() exits 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: <20260602-nfsd-testing-v2-9-e4ea62e3cd5c@kernel.org> References: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> In-Reply-To: <20260602-nfsd-testing-v2-0-e4ea62e3cd5c@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Lorenzo Bianconi , Anna Schumaker , Trond Myklebust , Anna Schumaker , Mike Snitzer Cc: Al Viro , 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=1895; i=jlayton@kernel.org; h=from:subject:message-id; bh=CuryIm7jNoF/fQtSYpxyaGIXD7K43W0WNnJiGRZWj+c=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqHwN9AIYtNwy3QGSFjrUHLhTHcyz6ToKXVC1VB 4HdVhBdhxSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCah8DfQAKCRAADmhBGVaC Fd0cEACJb6oEd9Cwr6EJQ0UOJiRLZsDF5lzsi2rvkjXl7zpwzPpuojv3H4BOvZkSyHuM3Cp6+Be xf5yGVQRPzNROJRVWHFWNYvcmT8NJjrAIowbddWCDY72TOI/QfXh/jpWESmGDCOGn+QfBit43HX e6pnERBoxCn1LVQsOaGO0+6RW15SKLBjqPLaCWQJXrgIn9XfF5+mU1d00Y9qS93Jwec+GnXNk49 eNhY3G1bKM/9Pr6ju7Kk8oG5J+95lygu/p6TcnCiPkqm3uVgR3PzejBM8CWXnAjf4s3v3ictBF7 9YV5MkeSeo8LjTKQhz80p3nX4D3+9HRSq5cdJqT5C58IzFuWH8zlhK65N+PK0/pRhL4mQFtBlHq ki/oXhAxrfJa64xMcIXlCG3JkYWXumPwT873PQQgdfVtohqjl4eEee72dMPIdnycRIjczsmepyS YLJpqlph705awEqn2ML9V2RmlKjtMi2XnKTqT2eEa8p4Bm+R1aVH6K4D35i+lpQJsPC2frotKkx CqC0JUS9cdc11llezkp8xMSiwsiymWCUIpkhgGO4PzTMnS+5mN4r2KTOi45uf5G3Xai3eimT0EY /ImDHTuEl90ZkHLXdb84ixinaBvdtxsrhsvLDCCMhHntcMkVuqoZXRb0ipMiUsn5p12Y/XGRHd7 DEvg/PIwFL33Aiw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 From: Al Viro Instead of having a separate path_put() on each failure exit, as well as on the normal path, let's move all of those past the point where these codepaths join. We want to keep the ordering between path_put() and exp_put(), so move that one as well. Signed-off-by: Al Viro Signed-off-by: Jeff Layton --- fs/nfsd/vfs.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 95ce15440492..cfac0cc4207c 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -137,20 +137,19 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry = **dpp, follow_flags =3D LOOKUP_AUTOMOUNT; =20 err =3D follow_down(&path, follow_flags); - if (err < 0) { - path_put(&path); + if (err < 0) goto out; - } + if (path.mnt =3D=3D exp->ex_path.mnt && path.dentry =3D=3D dentry && nfsd_mountpoint(dentry, exp) =3D=3D 2) { /* This is only a mountpoint in some other namespace */ - path_put(&path); goto out; } =20 exp2 =3D rqst_exp_get_by_name(rqstp, &path); if (IS_ERR(exp2)) { err =3D PTR_ERR(exp2); + exp2 =3D NULL; /* * We normally allow NFS clients to continue * "underneath" a mountpoint that is not exported. @@ -160,10 +159,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry *= *dpp, */ if (err =3D=3D -ENOENT && !(exp->ex_flags & NFSEXP_V4ROOT)) err =3D 0; - path_put(&path); - goto out; - } - if (nfsd_v4client(rqstp) || + } else if (nfsd_v4client(rqstp) || (exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) { /* successfully crossed mount point */ /* @@ -177,9 +173,10 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry *= *dpp, *expp =3D exp2; exp2 =3D exp; } - path_put(&path); - exp_put(exp2); out: + path_put(&path); + if (exp2) + exp_put(exp2); return err; } =20 --=20 2.54.0