From: Sven Eckelmann <[email protected]>

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: [email protected]
Fixes: 33a3bb4a3345 ("batman-adv: throughput meter implementation")
Reported-by: Yuan Tan <[email protected]>
Reported-by: Yifan Wu <[email protected]>
Reported-by: Juefei Pu <[email protected]>
Reported-by: Xin Liu <[email protected]>
Reviewed-by: Yuan Tan <[email protected]>
Signed-off-by: Sven Eckelmann <[email protected]>
Signed-off-by: Simon Wunderlich <[email protected]>
---
 net/batman-adv/tp_meter.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index ca6c3f6374bc5..a3593d104caa5 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);
 }
 
-- 
2.47.3

Reply via email to