<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/net/rose, branch v6.18.37</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v6.18.37</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v6.18.37'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-06-27T10:06:48+00:00</updated>
<entry>
<title>rose: don't free fd-owned sockets when reaping in the heartbeat</title>
<updated>2026-06-27T10:06:48+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-31T13:41:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=9477cbc5107a8dc31d54f199338449358621d569'/>
<id>urn:sha1:9477cbc5107a8dc31d54f199338449358621d569</id>
<content type='text'>
commit 56576518920edd7b6c3479477d8d490fe2ebdaaa upstream.

The heartbeat reaps orphaned ROSE sockets after their bound device goes
down. A socket still attached to a struct socket (sk-&gt;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-&gt;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 &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: clear neighbour pointer in rose_kill_by_device()</title>
<updated>2026-06-27T10:06:48+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-31T13:41:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=395b6573b389f44473b68285a36020a37a4025c2'/>
<id>urn:sha1:395b6573b389f44473b68285a36020a37a4025c2</id>
<content type='text'>
commit 606e42d195b467480d4d405f8814c48d1651a76a upstream.

rose_kill_by_device() drops the neighbour reference but leaves
rose-&gt;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-&gt;neighbour = NULL after the put, restoring the invariant.

Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: drop CALL_REQUEST in loopback timer when device is not running</title>
<updated>2026-06-27T10:06:48+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-28T18:20:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c31a0fa15a4b4c07130ca5bd1ac222b2541ab011'/>
<id>urn:sha1:c31a0fa15a4b4c07130ca5bd1ac222b2541ab011</id>
<content type='text'>
commit cf5567a2652e44866eae8987dff4c1ea507680df upstream.

When ax25stop brings down rose0 while the loopback timer has pending
CALL_REQUEST frames, rose_loopback_timer() calls rose_dev_get() and
finds the device still registered (unregister_netdevice waits for
refs to drop), then calls rose_rx_call_request() which takes a
netdev_hold() for the new socket.

But NETDEV_DOWN fires only once: rose_kill_by_device() already ran
before this timer tick, so the new socket is never cleaned up.  The
stuck reference prevents unregister_netdevice from completing, and the
orphan socket's timers eventually fire on freed memory (KASAN
slab-use-after-free in __run_timers).

The kernel clears IFF_UP via dev_close() before sending NETDEV_DOWN,
so checking netif_running() after rose_dev_get() is sufficient: if the
device is no longer running, the CALL_REQUEST is silently dropped and
no socket is created.  This closes the race without touching the
module-exit path (which already stops the timer via loopback_stopping).

Tested: unregister_netdevice completes immediately after ax25stop with
active loopback connections; no ref_tracker warnings, no KASAN.

Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: release netdev ref and destroy orphaned incoming sockets</title>
<updated>2026-06-27T10:06:48+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-28T17:38:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=74cbe94c913a4a3e069c0a82d8185586f0c37976'/>
<id>urn:sha1:74cbe94c913a4a3e069c0a82d8185586f0c37976</id>
<content type='text'>
commit df12be096302d2c947388acc25764456c7f18cc1 upstream.

Two related cleanup gaps left the module unremovable after a loopback
session:

1. rose_destroy_socket() did not release the device reference.  When
   an unaccepted incoming socket (created by rose_rx_call_request()) is
   destroyed via rose_heartbeat_expiry(), it is removed from rose_list
   before rose_kill_by_device() can find it, so the netdev_hold() taken
   in rose_rx_call_request() was never matched by netdev_put().  Add the
   release at the top of rose_destroy_socket() guarded by a NULL check
   so that rose_release() and rose_kill_by_device(), which already call
   netdev_put() and set device = NULL, are not affected.

2. rose_heartbeat_expiry() STATE_0 cleanup required TCP_LISTEN in
   addition to SOCK_DEAD.  Unaccepted incoming sockets are
   TCP_ESTABLISHED, so the condition was never true and those sockets
   lingered forever, holding the module use count above zero and
   blocking rmmod.  Drop the TCP_LISTEN restriction: any STATE_0 +
   SOCK_DEAD socket is orphaned and should be destroyed.

Together with the earlier rose_make_new() double-hold fix these three
patches allow clean rmmod after loopback sessions.

Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: fix netdev double-hold in rose_make_new()</title>
<updated>2026-06-27T10:06:48+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-28T17:11:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c794d35f73a7bc3d77224ccc6395c26f49f51752'/>
<id>urn:sha1:c794d35f73a7bc3d77224ccc6395c26f49f51752</id>
<content type='text'>
commit b9fb21ceb4f0d043767a1eba60786ec84809033b upstream.

rose_make_new() copies orose-&gt;device from the listener socket and calls
netdev_hold(), storing the tracker in rose-&gt;dev_tracker.  The only
caller, rose_rx_call_request(), then overwrites both make_rose-&gt;device
and make_rose-&gt;dev_tracker with a fresh netdev_hold() for the actual
incoming-call device.

This orphans the tracker allocated by rose_make_new(): it remains in
the device's refcount_tracker list but no pointer exists to free it
via netdev_put().  The result is one spurious outstanding reference per
accepted CALL_REQUEST, visible at rmmod time as:

  ref_tracker: netdev@X has 2/2 users at
      rose_rx_call_request+0xba3/0x1d50 [rose]
      rose_loopback_timer+0x3eb/0x670 [rose]

The second entry is the orphaned tracker from rose_make_new(); the
first is the correctly-managed socket reference from rose_rx_call_request().

Fix: initialise rose-&gt;device to NULL in rose_make_new() and let
rose_rx_call_request() -- the sole caller -- assign the correct device
and take the sole netdev_hold() as it already does.

Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: disconnect orphaned STATE_2 sockets when device is gone</title>
<updated>2026-06-27T10:06:48+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-28T15:38:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ce27bcdd857a98c9069703a209cbe7fc4c2587ba'/>
<id>urn:sha1:ce27bcdd857a98c9069703a209cbe7fc4c2587ba</id>
<content type='text'>
commit d4f4cf9f09a3f5fafa8f09110a7c1b5d10f2f261 upstream.

When ax25stop brings down ROSE interfaces, sockets in ROSE_STATE_2
(awaiting CLEAR CONFIRM) whose device pointer is already NULL are not
reached by rose_kill_by_device() and wait for T3 (up to 180s) before
self-cleaning via rose_timer_expiry().  This keeps the rose module
usecount at 1, blocking rmmod for the full T3 duration.

In rose_heartbeat_expiry(), detect ROSE_STATE_2 sockets with no device,
cancel T3, release the neighbour reference, and call rose_disconnect()
+ sock_set_flag(SOCK_DESTROY).  The next heartbeat tick (&lt;=5s) then
destroys the socket via the existing ROSE_STATE_0/SOCK_DESTROY path,
allowing clean module unload within 10s instead of up to 180s.

Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: set SOCK_DESTROY in rose_kill_by_device() for prompt cleanup</title>
<updated>2026-06-27T10:06:48+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-27T12:11:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ab849a6972c99e8a83ca92fbe463d782118e39f8'/>
<id>urn:sha1:ab849a6972c99e8a83ca92fbe463d782118e39f8</id>
<content type='text'>
commit 741a4863ad570889c75f7a8e404567d8f3e46335 upstream.

When rose_kill_by_device() is called (via NETDEV_DOWN on module exit
or interface removal), it calls rose_disconnect() which transitions
sockets to ROSE_STATE_0 and sets SOCK_DEAD.  However,
rose_heartbeat_expiry() only calls rose_destroy_socket() at
ROSE_STATE_0 if SOCK_DESTROY is set -- the SOCK_DEAD path is reserved
for TCP_LISTEN sockets.  Without SOCK_DESTROY, orphaned sockets in
ROSE_STATE_2 (clearing) loop indefinitely in the heartbeat without
ever being freed, keeping the module use-count elevated and blocking
modprobe -r rose until the T1 timer (up to 200 s) expires.

Set SOCK_DESTROY immediately after rose_disconnect() so the heartbeat
destroys the socket at its next tick (within 5 s), allowing clean
module unload.

Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: fix notifier unregistered too early in rose_exit()</title>
<updated>2026-06-27T10:06:47+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-26T13:57:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c98cc00c2d3b17d849e0ba806e5740c7e0b6b138'/>
<id>urn:sha1:c98cc00c2d3b17d849e0ba806e5740c7e0b6b138</id>
<content type='text'>
commit f71a8a1edc14dba746edde38adddd654ba202b4d upstream.

rose_exit() called unregister_netdevice_notifier() before the loop that
calls unregister_netdev() on each ROSE virtual device.  As a result,
the NETDEV_DOWN event fired by unregister_netdev() was never delivered
to rose_device_event(), so rose_kill_by_device() never ran.

Every socket whose rose-&gt;device pointed at a ROSE device therefore kept
its netdev_tracker entry live until free_netdev() destroyed the
ref_tracker_dir, at which point the kernel reported all of them as
leaked references (165 entries in a typical FPAC setup).  Worse, those
sockets retained stale device pointers and live timers that could fire
into freed module text after module unload, causing a silent system
freeze with no kernel panic logged.

Fix by moving unregister_netdevice_notifier() to after the device-
unregistration loop.  unregister_netdev() then delivers NETDEV_DOWN
while the notifier is still registered, rose_kill_by_device() runs for
each device, releases all netdev references held by open sockets, and
calls rose_disconnect() which stops the per-socket timers.

Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: fix netdev double-hold in rose_rx_call_request()</title>
<updated>2026-06-27T10:06:47+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-26T13:57:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=19139026dc1c0a958798fe7b1c26f4cd479b706e'/>
<id>urn:sha1:19139026dc1c0a958798fe7b1c26f4cd479b706e</id>
<content type='text'>
commit c675277c3ba0d2310e0825577d58308c39931e14 upstream.

rose_rx_call_request() used netdev_tracker_alloc() after assigning
make_rose-&gt;device, intending to take ownership of the reference passed
by the caller.  But every caller -- rose_route_frame() and
rose_loopback_timer() -- already calls dev_put() for its own hold after
the function returns, so the socket ended up with a tracker entry
pointing at a reference that had already been released.

The result was spurious refcount_t warnings ("saturated", "decrement
hit 0") on every incoming CALL_REQUEST, leading to refcount corruption
and eventual silent freeze.

Replace netdev_tracker_alloc() with netdev_hold() so that
rose_rx_call_request() acquires its own independent reference.  Each
caller retains its own hold from rose_dev_get() and releases it via
dev_put() as before; socket cleanup releases the socket's separate hold
via netdev_put().

Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>rose: guard rose_neigh_put() against NULL in timer expiry</title>
<updated>2026-06-27T10:06:47+00:00</updated>
<author>
<name>Bernard Pidoux</name>
<email>bernard.f6bvp@gmail.com</email>
</author>
<published>2026-05-16T10:10:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=1d94857c11d607ff68496866c5c90604f1aa1d8a'/>
<id>urn:sha1:1d94857c11d607ff68496866c5c90604f1aa1d8a</id>
<content type='text'>
commit 2b67342c6ff899a0b83359517146a5b7b243af97 upstream.

In rose_timer_expiry(), the ROSE_STATE_2 branch calls
rose_neigh_put(rose-&gt;neighbour) without first checking whether the
pointer is NULL.  After commit 5de7665e0a07 ("net: rose: fix timer
races against user threads") the timer is re-armed when the socket is
owned by a user thread; between the re-arm and the next firing, a
device-down event or concurrent teardown via rose_kill_by_device() can
set rose-&gt;neighbour to NULL, leading to a NULL-pointer dereference
inside rose_neigh_put().

Add a NULL check before the put and clear the pointer afterwards.

Fixes: 5de7665e0a07 ("net: rose: fix timer races against user threads")
Signed-off-by: Bernard Pidoux &lt;bernard.f6bvp@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
</feed>
