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=1794590152; b=QXHNDfLTO/03cHRlTspRgTjDcKTqxsyBtpd5R8IcPnSM5phe6OyunX/90c20SdCVR/iq b3V8lucGQUcoqAblrl/CFrTTUVa0M3x/fDBFOInkJX0QwFFO9ZNsN40e65lZPZi50yp/G +jXbt7jsqRlQNxw1Gseei2PxMgEzwzsBDN1MM97LlowjXty7FXmAs28rTgynYyKerb8bY tyCXz7+bUk07ZIsNuctaXiXZOadbZ5646Tm1iOWKn0Dgmuj85cQU2QWA8oldEb757IVn1 XLIwyj1ctXUrg6LwARHR1nuR+gnUZbEYVSUvlcKMsGhUcfZoRaXEsTWMyNjDgyc/AaQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794590152; 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=LvjIeViM9FaGebNSw/EbmLRYqRP1X+fHWq8iUYNNuYs=; b=A/J/+iFMdHWRQ1smpxGHPoiZqtkcZfguiY+r3S76RmzkhRisSuBwEu5+s0KnRDBUX9F/ 841hVAZhVgQNHHgU+nnfiOOU4DEMNJm/NEwG/FBbrmIWyF+j5+msF+u3JiTSrA27YKf10 7Lpt2ue6RONBRmBWFUrvBc0fMNvPrykMQ10gMnfwZg0bXDuKztFHFNKS9m003M8BU7dfW ng07qnVVYLrCvzN/Nuo/D/itry3TGWxDVcP25cYgXVw7RCswFLKi9WojBfFTDzQwWJxEb 2GCN7Pmgidge1nyHewPhjPLB6QcbQZt4Jn0KrWZ9VT9zcR3+e4sXRoUS9dyk/5o/3Kw== 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=pJ5YKhFe; 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 00245606A8BC; Fri, 13 Nov 2026 17:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=pJ5YKhFe Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C5571F000C4; Fri, 13 Nov 2026 17:15:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794590151; bh=LvjIeViM9FaGebNSw/EbmLRYqRP1X+fHWq8iUYNNuYs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=pJ5YKhFeyYaoHnwyjBnK2V39mR/vuI+yCZ5tKgOAtTugVQVfMrb1PZAAjqeMz+7qX M+fNuPHseOCSOQrOspUUCSZaQCyRZorkSLrXdoIRMXAobC2Jh4+aO42MIHSACX1QHK kz0BKqv5YIlWPAYtbPYYo2VUl9k9C9sgsJmFJPFI= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Bernard Pidoux , Sasha Levin Subject: [PATCH 6.18 139/686] rose: hold the listener while a Call Request is queued on it Date: Fri, 13 Nov 2026 10:44:32 -0500 Message-ID: <20261113153825.512208126@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261113153820.902362109@linuxfoundation.org> References: <20261113153820.902362109@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org 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: Bernard Pidoux rose_rx_call_request() runs in softirq context for every Call Request addressed to us. It finds the listening socket with rose_find_listener(), which returns it without a reference once rose_list_lock is dropped, then creates the new socket, queues it on the listener's receive queue and wakes the listener up. Nothing stops the process owning the listener from closing it meanwhile: rose_release() destroys a listening socket at once, and the Call Request writes into freed memory. A node daemon that restarts while calls come in does exactly this. Take a reference in rose_find_listener(), lock the listener in rose_rx_call_request() and refuse the call if it has been closed in the meantime. rose_release() marks the socket dead with sock_orphan() before rose_destroy_socket() empties its queue under the socket lock, so a listener found alive once locked will see the new socket on its queue, either in rose_accept() or when it is destroyed. On a QEMU bench with two 4-CPU guests (KASAN, lockdep), six threads on A calling B without a break while B opens a listening socket, keeps it 0 to 30 ms and closes it, for 40 s: before, KASAN reports a slab-use-after-free in rose_rx_call_request() a few seconds in, the socket having been freed by close() on B; with a 20 ms delay after rose_find_listener() the corrupted socket list then panics B in rose_neigh_put(). After, no report in either case, with about 400 calls connected as before. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Bernard Pidoux Assisted-by: Claude:claude-opus-5-5 (cherry picked from commit 8bd85552e2ae1a606eda4b6c096a7e3bd0bcff62) Signed-off-by: Sasha Levin --- net/rose/af_rose.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 614d033410fa3..8d0878cf2b01c 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -278,7 +278,7 @@ static void rose_insert_socket(struct sock *sk) /* * Find a socket that wants to accept the Call Request we just - * received. + * received. A reference is taken on the socket found. */ static struct sock *rose_find_listener(rose_address *addr, ax25_address *call) { @@ -304,6 +304,8 @@ static struct sock *rose_find_listener(rose_address *addr, ax25_address *call) } s = NULL; found: + if (s) + sock_hold(s); spin_unlock_bh(&rose_list_lock); return s; } @@ -1103,12 +1105,31 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros } sk = rose_find_listener(&facilities.source_addr, &facilities.source_call); + if (!sk) { + rose_transmit_clear_request(neigh, lci, ROSE_NETWORK_CONGESTION, 120); + return 0; + } + + /* + * The listener may be closed by rose_release() at any time. It is + * marked dead before rose_destroy_socket() empties its queue, so + * once it is locked a listener that is not dead will see the new + * socket on its queue, either in rose_accept() or when it is + * destroyed. + */ + bh_lock_sock(sk); /* * We can't accept the Call Request. */ - if (sk == NULL || sk_acceptq_is_full(sk) || - (make = rose_make_new(sk)) == NULL) { + if (sock_flag(sk, SOCK_DEAD) || sk->sk_state != TCP_LISTEN || + sk_acceptq_is_full(sk)) + make = NULL; + else + make = rose_make_new(sk); + if (!make) { + bh_unlock_sock(sk); + sock_put(sk); rose_transmit_clear_request(neigh, lci, ROSE_NETWORK_CONGESTION, 120); return 0; } @@ -1164,8 +1185,9 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros rose_start_heartbeat(make); - if (!sock_flag(sk, SOCK_DEAD)) - sk->sk_data_ready(sk); + sk->sk_data_ready(sk); + bh_unlock_sock(sk); + sock_put(sk); return 1; } -- 2.53.0