summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-06-27 11:06:50 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-06-27 11:06:50 +0100
commitf657f1a475c7ab8aa116fd7bc8a6dba693d379ae (patch)
treea78e9483a0442006a01d667fd016898f6dfadd73 /include/net
parent962d275461ceb4a7e588a46067437acfaebb6377 (diff)
parent0c503cf3dde2e53614f05261ece12f9d3d4c3c20 (diff)
Merge v6.18.37linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/rose.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/include/net/rose.h b/include/net/rose.h
index 2b5491bbf39a..95d1f9c582dc 100644
--- a/include/net/rose.h
+++ b/include/net/rose.h
@@ -160,6 +160,18 @@ static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
{
if (refcount_dec_and_test(&rose_neigh->use)) {
+ /* We are dropping the last reference, so we are about to free the
+ * neighbour. Its timers may still be armed -- t0timer in particular
+ * re-arms itself in rose_t0timer_expiry(). rose_remove_neigh()
+ * cancels them before its own put, but callers that drop the final
+ * reference without first calling rose_remove_neigh() (the socket
+ * heartbeat reaping path) would otherwise kfree() a neighbour with a
+ * live timer -> use-after-free. timer_delete_sync() (not the async
+ * variant) is required: it waits out a concurrently running handler
+ * and loops until the self-rearming timer stays stopped.
+ */
+ timer_delete_sync(&rose_neigh->ftimer);
+ timer_delete_sync(&rose_neigh->t0timer);
if (rose_neigh->ax25)
ax25_cb_put(rose_neigh->ax25);
kfree(rose_neigh->digipeat);