Archive-only list for patches
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Bernard Pidoux <bernard.f6bvp@gmail.com>
Subject: [PATCH 7.0 30/49] rose: dont free fd-owned sockets when reaping in the heartbeat
Date: Thu, 25 Jun 2026 14:03:42 +0100	[thread overview]
Message-ID: <20260625125641.763042674@linuxfoundation.org> (raw)
In-Reply-To: <20260625125637.527552689@linuxfoundation.org>

7.0-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit 56576518920edd7b6c3479477d8d490fe2ebdaaa upstream.

The heartbeat reaps orphaned ROSE sockets after their bound device goes
down. A socket still attached to a struct socket (sk->sk_socket != NULL --
e.g. an incoming connection an fpad client has accepted and kept open) is
owned by that userspace fd: rose_release() frees it on close(). Freeing it
from the heartbeat left the fd dangling, so the eventual close() touched
freed memory -- slab-use-after-free in rose_release().

Reap only sockets with sk->sk_socket == NULL (unaccepted incoming
connections and post-close orphans). For an fd-owned socket whose device
went down, disconnect it and fall through to the switch so close() does
the teardown. Also release the neighbour reference held by orphaned
incoming sockets before tearing them down.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_timer.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

--- a/net/rose/rose_timer.c
+++ b/net/rose/rose_timer.c
@@ -126,13 +126,68 @@ static void rose_heartbeat_expiry(struct
 		sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ/20);
 		goto out;
 	}
+
+	/* The bound device went down while we still hold a reference on it.
+	 * This catches the narrow race where rose_loopback_timer() created a
+	 * socket in the window after rose_kill_by_device()'s NETDEV_DOWN sweep
+	 * but before rose_insert_socket() -- leaving a STATE_3 socket that no
+	 * other branch reaps.  A down device means the link is dead, so tear
+	 * the socket down regardless of state.  rose_destroy_socket() releases
+	 * the held netdev reference (rose->device still set).
+	 */
+	if (rose->device && !netif_running(rose->device)) {
+		if (rose->neighbour) {
+			rose_neigh_put(rose->neighbour);
+			rose->neighbour = NULL;
+		}
+		rose_disconnect(sk, ENETDOWN, -1, -1);
+
+		/* Only reap the socket if userspace no longer holds it.  A socket
+		 * still attached to a struct socket (sk->sk_socket != NULL -- e.g.
+		 * a connection an fpad client has accepted and kept open) is owned
+		 * by that fd: rose_release() will destroy it on close().  Dropping
+		 * the last reference here leaves the open fd dangling, so the
+		 * eventual close() touches freed memory -> slab-use-after-free in
+		 * rose_release().  Unaccepted incoming sockets and post-close
+		 * orphans have sk->sk_socket == NULL and stay safe to reap here.
+		 */
+		if (!sk->sk_socket) {
+			sock_set_flag(sk, SOCK_DESTROY);
+			bh_unlock_sock(sk);
+			rose_destroy_socket(sk);
+			sock_put(sk);
+			return;
+		}
+
+		/* Owned by userspace: the link is down and the socket is now
+		 * disconnected (rose_disconnect() moved it to STATE_0).  Fall
+		 * through to the switch, which re-arms the heartbeat; the close()
+		 * will tear the socket down. */
+	}
+
 	switch (rose->state) {
 	case ROSE_STATE_0:
 		/* Destroy any orphaned STATE_0 socket: either explicitly
 		 * flagged SOCK_DESTROY, or SOCK_DEAD (covers both unaccepted
 		 * incoming connections and listening sockets whose link died).
 		 */
-		if (sock_flag(sk, SOCK_DESTROY) || sock_flag(sk, SOCK_DEAD)) {
+		if ((sock_flag(sk, SOCK_DESTROY) || sock_flag(sk, SOCK_DEAD)) &&
+		    !sk->sk_socket) {
+			/* Reap only orphaned sockets (sk->sk_socket == NULL).  A
+			 * socket still owned by a userspace fd reaches here via the
+			 * STATE_2 device-gone branch, which sets SOCK_DESTROY without
+			 * knowing about the fd; freeing it would race rose_release()
+			 * at close() -> use-after-free.  Leave it for close().
+			 *
+			 * Orphaned incoming sockets (rose_rx_call_request) hold a
+			 * neighbour reference; release it before teardown, as the
+			 * STATE_2 and device-down branches do.  rose_destroy_socket()
+			 * does not drop it.
+			 */
+			if (rose->neighbour) {
+				rose_neigh_put(rose->neighbour);
+				rose->neighbour = NULL;
+			}
 			bh_unlock_sock(sk);
 			rose_destroy_socket(sk);
 			sock_put(sk);



  parent reply	other threads:[~2026-06-25 13:10 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-25 13:03 [PATCH 7.0 00/49] 7.0.14-rc1 review Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 01/49] io_uring/net: Avoid msghdr on op_connect/op_bind async data Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 02/49] arm64/entry: Fix arm64-specific rseq brokenness Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 03/49] lockd: fix TEST handling when not all permissions are available Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 04/49] firmware: exynos-acpm: Count number of commands in acpm_xfer Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 05/49] firmware: exynos-acpm: Count acpm_xfer buffers with __counted_by_ptr Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 06/49] firmware: samsung: acpm: Fix cross-thread RX length corruption Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 07/49] firmware: samsung: acpm: Fix false timeouts and Use-After-Free in polling Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 08/49] firmware: samsung: acpm: Fix missing LKMM barriers in sequence allocator Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 09/49] fuse: re-lock request before replacing page cache folio Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 10/49] Revert "NFSD: Defer sub-object cleanup in export put callbacks" Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 11/49] RDMA/bnxt_re: zero shared page before exposing to userspace Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 12/49] bpf: Fix NULL pointer dereference in bpf_sk_storage_clone and diag paths Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 13/49] i2c: stub: Reject I2C block transfers with invalid length Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 14/49] net: qualcomm: rmnet: fix endpoint use-after-free in rmnet_dellink() Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 15/49] agp/amd64: Fix broken error propagation in agp_amd64_probe() Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 16/49] rose: fix dev_put() leak in rose_loopback_timer() Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 17/49] rose: hold loopback neighbour reference across timer callback Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 18/49] rose: fix race between loopback timer and module removal Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 19/49] rose: clear neighbour pointer after rose_neigh_put() in state machines Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 20/49] rose: guard rose_neigh_put() against NULL in timer expiry Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 21/49] rose: fix netdev double-hold in rose_rx_call_request() Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 22/49] rose: fix notifier unregistered too early in rose_exit() Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 23/49] rose: set SOCK_DESTROY in rose_kill_by_device() for prompt cleanup Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 24/49] rose: disconnect orphaned STATE_2 sockets when device is gone Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 25/49] rose: fix netdev double-hold in rose_make_new() Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 26/49] rose: release netdev ref and destroy orphaned incoming sockets Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 27/49] rose: drop CALL_REQUEST in loopback timer when device is not running Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 28/49] rose: cancel neighbour timers in rose_neigh_put() before freeing Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 29/49] rose: clear neighbour pointer in rose_kill_by_device() Greg Kroah-Hartman
2026-06-25 13:03 ` Greg Kroah-Hartman [this message]
2026-06-25 13:03 ` [PATCH 7.0 31/49] net: export netif_open for self_test usage Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 32/49] net: net_failover: Fix the deadlock in slave register Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 33/49] iio: light: veml6075: add bounds check to veml6075_it_ms index Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 34/49] iio: adc: ti-ads1298: add bounds check to pga_settings index Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 35/49] Input: rmi4 - fix register descriptor address calculation Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 36/49] Input: rmi4 - refactor register descriptor parsing Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 37/49] Input: rmi4 - fix type overflow in register counts Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 38/49] Input: rmi4 - fix num_subpackets overflow in register descriptor Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 39/49] Input: rmi4 - fix memory leak in rmi_set_attn_data() Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 40/49] Input: rmi4 - iterative IRQ handler Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 41/49] Input: rmi4 - fix bit count in bitmap_copy() Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 42/49] crypto: qat - remove unused character device and IOCTLs Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 43/49] vc_screen: fix null-ptr-deref in vcs_notifier() during concurrent vcs_write Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 44/49] serial: qcom_geni: Fix RX DMA stall when SE_DMA_RX_LEN_IN is zero Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 45/49] serial: 8250_dw: unregister 8250 port if clk_notifier_register() fails Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 46/49] drivers/base/memory: set mem->altmap after successful device registration Greg Kroah-Hartman
2026-06-25 13:03 ` [PATCH 7.0 47/49] ksmbd: reject non-VALID session in compound request branch Greg Kroah-Hartman
2026-06-25 13:04 ` [PATCH 7.0 48/49] media: vidtv: fix NULL pointer dereference in vidtv_mux_push_si Greg Kroah-Hartman
2026-06-25 13:04 ` [PATCH 7.0 49/49] virtiofs: fix UAF on submount umount Greg Kroah-Hartman
2026-06-25 13:44 ` [PATCH 7.0 00/49] 7.0.14-rc1 review Florian Fainelli
2026-06-25 15:27 ` Brett A C Sheffield
2026-06-25 17:30 ` Justin Forbes
2026-06-25 18:06 ` Peter Schneider
2026-06-25 23:58 ` Shuah Khan
2026-06-26  5:05 ` Ron Economos
2026-06-26 10:54 ` Miguel Ojeda
2026-06-26 11:24 ` Dileep malepu
2026-06-26 11:25 ` Pavel Machek
2026-06-26 11:44   ` Pavel Machek
2026-06-26 13:16 ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260625125641.763042674@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=bernard.f6bvp@gmail.com \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox