[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]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.