[PATCH batadv v2] batman-adv: fix tp_meter counter underflow during shutdown
Sven Eckelmann <[email protected]>
| Newsgroups | org.open-mesh.lists.batman |
|---|---|
| Message-ID | <20260511-tp-sending-underflow-atomic-v2-1-894f7f45d3ca@narfation.org> |
From: Luxiao Xu <[email protected]> batadv_tp_sender_shutdown() unconditionally decrements the "sending" atomic counter. If multiple paths (e.g. timeout, user cancel, and normal finish) call this function, the counter can underflow to -1. Since the sender logic treats any non-zero value as "still sending", a negative value causes the sender kthread to loop indefinitely. This leads to a use-after-free when the interface is removed while the zombie thread is still active. Fix this by using atomic_xchg() to ensure the counter only transitions from 1 to 0 once. Fixes: 33a3bb4a3345 ("batman-adv: throughput meter implementation") Cc: [email protected] Reported-by: Yuan Tan <[email protected]> Reported-by: Yifan Wu <[email protected]> Reported-by: Juefei Pu <[email protected]> Reported-by: Xin Liu <[email protected]> Signed-off-by: Luxiao Xu <[email protected]> Signed-off-by: Ren Wei <[email protected]> [sven: added missing change in batadv_tp_send] Signed-off-by: Sven Eckelmann <[email protected]> --- Changes in v2: - added missing atomic_dec_and_test -> atomic_xchg change in batadv_tp_send - Link to v1: https://patch.msgid.link/df73e607bda0c84b22d64d80f8ac887190242baf.1778118303.git.rakukuip@gmail.com --- net/batman-adv/tp_meter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 759ae923..ed9f7e98 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -452,7 +452,7 @@ static void batadv_tp_sender_end(struct batadv_priv *bat_priv, static void batadv_tp_sender_shutdown(struct batadv_tp_vars *tp_vars, enum batadv_tp_meter_reason reason) { - if (!atomic_dec_and_test(&tp_vars->sending)) + if (atomic_xchg(&tp_vars->sending, 0) != 1) return; tp_vars->reason = reason; @@ -886,7 +886,7 @@ static int batadv_tp_send(void *arg) "Meter: %s() cannot send packets (%d)\n", __func__, err); /* ensure nobody else tries to stop the thread now */ - if (atomic_dec_and_test(&tp_vars->sending)) + if (atomic_xchg(&tp_vars->sending, 0) == 1) tp_vars->reason = err; break; } --- base-commit: f876964b732393119a036ff1ce7a1c94290b09ed change-id: 20260511-tp-sending-underflow-atomic-53841058fcdf Best regards, -- Sven Eckelmann <[email protected]>