From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793831824; b=bOzUxtlETUoSlG4RZU1XfooNjbTssTLstbIA3Owgle9UcwlKrKH1baDjNwngXKV2b0y4 zs6/vNdxrUj4/S8vKCWntOnj+cITjzD1qJHWnEVcd4OQJtmcQ+T2KIRxP7A9+2nzAB0KO 9VW89s4erD4tIrL6ykipSzLgDkHO+sz3C7qHjbz6H5LdwTNVgNwHiMbCrMeu+iiA9f0OQ hF0eUGLHZA0C9G6+FBajvlabaZWqDGZIUjeHgCkAhm10xX3JGWhlpG5/hqJ4F4CMlmWTt GtlYRBdzjYyXjOMLt0Mj6991nS9UX3bh6TR5zXlYf84niet1su+oChBmOEB2a1jLAIA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793831824; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=8H0XHm2dd8/7BnzjqxZIFLZbZHbPRsLIhrjEWDDKWyM=; b=0doslRneduf9rW8Y/3AE5HzwtEy7mwXhvEIAdu3ZLVmj3bEVtW9YDH8FrJ1PPLrpAXvW wk5ypxmQo1IY+0XpNDBR+lJHO6bEWFcRSMaNuFzJyqK8uAGpId348lGdV0FVRYCcJiaui GGyDd/RyeYsXBelMRWjExTGvOORZQycsbLLigG9gsBFMlDKG/REPlYcqpmX/+wU3po/ai Zw6D1jC84jVsBfQW7ihlqcENcbALFQrQsdr7CdkhahcTxHqTC5xXTVs1fGJIZCydvWLZq v4YRFN9U1/KHFHeZQhLADfNCwQXVbkPodPDpgd36/C92hP+decVnDy9b95vIigkErrQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=uHS4ih2T; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 355AA606A873; Wed, 4 Nov 2026 22:37:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=uHS4ih2T Received: by smtp.kernel.org (Postfix) with ESMTPSA id BDDB41F000C1; Wed, 4 Nov 2026 22:37:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1793831824; bh=8H0XHm2dd8/7BnzjqxZIFLZbZHbPRsLIhrjEWDDKWyM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=uHS4ih2TtamOJ4RjHarmfUdf31kAPB+1qx2ZDWagh/mUsQ96obMIIrk7EOmUTEk8W CH2IyrR8fWK8pIm9gQxk+nkcHNcFpbOnwOPXsTozzpm1zKCA0Dt5GoCvsUpgIZZohk mAgc+G1/64BhmWoedTaTUWpgpRGP9fCZ1wrIfbjo= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Farhad Alemi , Chuck Lever Subject: [PATCH 6.18 0889/1005] NFSD: Dont complete a cld upcall the daemon has not read Date: Wed, 4 Nov 2026 16:10:22 -0500 Message-ID: <20261104211108.124518564@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104211043.516122098@linuxfoundation.org> References: <20261104211043.516122098@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Chuck Lever commit 7f4bf851aca4e18940ebf2bddf4ba6783802ee81 upstream. cld_pipe_downcall() matches a reply to its upcall on the xid alone. A write that arrives before the daemon has read that upcall completes __cld_pipe_upcall() while its struct rpc_pipe_msg is still queued on the pipe. The waiter returns, its stack frame goes away, and the pipe keeps a list_head that points into it. The next rpc_queue_upcall() walks that pointer: BUG: KASAN: vmalloc-out-of-bounds in __list_add_valid_or_report Read of size 8 at addr ffffc90007027950 by task syz.0.96/13066 __list_add_valid_or_report+0x6a/0x130 rpc_queue_upcall cld_pipe_upcall nfsd4_cld_grace_start nfsd4_cld_tracking_init The pipe is mode 0600 in rpc_pipefs, so the trigger is a broken or hostile nfsdcld rather than an unprivileged task. Record whether the daemon has consumed the whole message and complete only when it has. cld_pipe_destroy_msg() runs on every path by which the pipe releases a message, so it can maintain that flag under cn_lock. nfsdcld sends its -EINPROGRESS downcalls only after reading the upcall, so the new check does not break the GraceStart record stream. Fixes: f3f8014862d8 ("nfsd: add the infrastructure to handle the cld upcall") Cc: stable@vger.kernel.org Reported-by: Farhad Alemi Closes: https://lore.kernel.org/linux-nfs/CA+0ovCjVF58WLeen2ctdzHyWUASAAW3Y=Yjihyq0pFApYawtDg@mail.gmail.com/ Link: https://patch.msgid.link/20260901-alemi-v2-1-e163f94a3a6e@kernel.org Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs4recover.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -709,6 +709,8 @@ struct cld_upcall { struct list_head cu_list; struct cld_net *cu_net; struct completion cu_done; + /* daemon has read the whole upcall; protected by cn_lock */ + bool cu_inflight; union { struct cld_msg_hdr cu_hdr; struct cld_msg cu_msg; @@ -869,6 +871,13 @@ cld_pipe_downcall(struct file *filp, con spin_lock(&cn->cn_lock); list_for_each_entry(tmp, &cn->cn_list, cu_list) { if (get_unaligned(&tmp->cu_u.cu_hdr.cm_xid) == xid) { + /* + * Completing now would return the waiter + * while its message is still queued on the + * pipe. + */ + if (!tmp->cu_inflight) + break; cup = tmp; if (status != -EINPROGRESS) list_del_init(&cup->cu_list); @@ -877,9 +886,9 @@ cld_pipe_downcall(struct file *filp, con } spin_unlock(&cn->cn_lock); - /* couldn't find upcall? */ + /* no upcall to complete? */ if (!cup) { - dprintk("%s: couldn't find upcall -- xid=%u\n", __func__, xid); + dprintk("%s: no completable upcall -- xid=%u\n", __func__, xid); return -EINVAL; } @@ -899,8 +908,16 @@ cld_pipe_destroy_msg(struct rpc_pipe_msg struct cld_msg *cmsg = msg->data; struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u.cu_msg); + struct cld_net *cn = cup->cu_net; + + /* + * errno >= 0 means the daemon read the whole message and a + * downcall will complete the upcall. + */ + spin_lock(&cn->cn_lock); + cup->cu_inflight = msg->errno >= 0; + spin_unlock(&cn->cn_lock); - /* errno >= 0 means we got a downcall */ if (msg->errno >= 0) return;