summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2026-05-13 09:01:35 +0200
committerSven Eckelmann <sven@narfation.org>2026-05-14 20:01:31 +0200
commit6c65cf23d4c6170fcf5714c32aa64689718cb142 (patch)
tree51494fa924fb8e74ee2433b3b5898d6b1f355408
parent2d8826a2d3657cea66fb0370f9e521575a673871 (diff)
downloadlinux-6c65cf23d4c6170fcf5714c32aa64689718cb142.tar.gz
linux-6c65cf23d4c6170fcf5714c32aa64689718cb142.zip
batman-adv: tp_meter: avoid use of uninit sender vars
batadv_tp_recv_ack() and batadv_tp_stop() are only valid for tp_vars in the BATADV_TP_SENDER role. When called with a BATADV_TP_RECEIVER role, it proceeds to read sender-only members that were never initialized, leading to undefined behavior. This can be triggered when a node that is currently acting as a receiver in an ongoing tp_meter session receives a malicious ACK packet. Guard against this by checking tp_vars->role immediately after the lookup and bailing out if it is not BATADV_TP_SENDER, before any of those members are accessed. Cc: stable@kernel.org Fixes: 33a3bb4a3345 ("batman-adv: throughput meter implementation") Reported-by: Yuan Tan <yuantan098@gmail.com> Reported-by: Yifan Wu <yifanwucs@gmail.com> Reported-by: Juefei Pu <tomapufckgml@gmail.com> Reported-by: Xin Liu <bird@lzu.edu.cn> Reviewed-by: Yuan Tan <yuantan098@gmail.com> Signed-off-by: Sven Eckelmann <sven@narfation.org>
-rw-r--r--net/batman-adv/tp_meter.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index ca6c3f6374bc..a3593d104caa 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -664,6 +664,9 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
if (unlikely(!tp_vars))
return;
+ if (unlikely(tp_vars->role != BATADV_TP_SENDER))
+ goto out;
+
if (unlikely(atomic_read(&tp_vars->sending) == 0))
goto out;
@@ -1101,12 +1104,16 @@ void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
if (!tp_vars) {
batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
"Meter: trying to interrupt an already over connection\n");
- goto out;
+ goto out_put_orig_node;
}
+ if (unlikely(tp_vars->role != BATADV_TP_SENDER))
+ goto out_put_tp_vars;
+
batadv_tp_sender_shutdown(tp_vars, return_value);
+out_put_tp_vars:
batadv_tp_vars_put(tp_vars);
-out:
+out_put_orig_node:
batadv_orig_node_put(orig_node);
}