summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernard Pidoux <bernard.f6bvp@gmail.com>2026-05-31 15:41:45 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-06-27 11:07:40 +0100
commit4507ce5fec5edd8d2c2d8106cc8e6be0f167793e (patch)
treef5ed2c6866d5738a295fb81e4d99120d1b30b8c5
parent0c7919c4f1767a3402aed4118045d1f7bc72fef5 (diff)
downloadlinux-stable-4507ce5fec5edd8d2c2d8106cc8e6be0f167793e.tar.gz
linux-stable-4507ce5fec5edd8d2c2d8106cc8e6be0f167793e.zip
rose: clear neighbour pointer in rose_kill_by_device()
commit 606e42d195b467480d4d405f8814c48d1651a76a upstream. rose_kill_by_device() drops the neighbour reference but leaves rose->neighbour pointing at it, unlike every other rose_neigh_put() site (see "rose: clear neighbour pointer after rose_neigh_put() in state machines"). The heartbeat STATE_0 reaping path then puts the same neighbour a second time, causing a rose_neigh refcount underflow and a use-after-free. Set rose->neighbour = NULL after the put, restoring the invariant. Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/rose/af_rose.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 81b34b2ddf04..f32344c33a6f 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -216,8 +216,16 @@ start:
* looping forever in ROSE_STATE_0 with no owner.
*/
sock_set_flag(sk, SOCK_DESTROY);
- if (rose->neighbour)
+ if (rose->neighbour) {
rose_neigh_put(rose->neighbour);
+ /* Clear the pointer after dropping the reference, as
+ * every other rose_neigh_put() site does. Otherwise
+ * rose_heartbeat_expiry() (STATE_0 reaping) sees a stale
+ * rose->neighbour and puts it a second time -> rose_neigh
+ * refcount underflow / use-after-free.
+ */
+ rose->neighbour = NULL;
+ }
netdev_put(rose->device, &rose->dev_tracker);
rose->device = NULL;
}