summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2026-06-02 16:51:42 +0200
committerSven Eckelmann <sven@narfation.org>2026-06-03 08:02:20 +0200
commit15ccbf685222274f5add1387af58c2a41a95f81e (patch)
treeeea401c0ac2e052cc8c50343353d5c571eca8157
parentf54c85ed42a1b27a516cf2a4728f5a612b799e07 (diff)
downloadlinux-15ccbf685222274f5add1387af58c2a41a95f81e.tar.gz
linux-15ccbf685222274f5add1387af58c2a41a95f81e.zip
batman-adv: tp_meter: add only finished tp_vars to lists
When the receiver variables (aka "session") are initialized, then they are added to the list of sessions before the timer is set up. A RCU protected reader could therefore find the entry and run mod_setup before batadv_tp_init_recv() finished the timer initialization. The same is true for batadv_tp_start(), which must first initialize the finish_work and the test_length to avoid a similar problem. Cc: stable@kernel.org Fixes: 33a3bb4a3345 ("batman-adv: throughput meter implementation") Signed-off-by: Sven Eckelmann <sven@narfation.org>
-rw-r--r--net/batman-adv/tp_meter.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index 3d3d06c88e1c..5498cdc972e9 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -1096,21 +1096,21 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
tp_vars->prerandom_offset = 0;
spin_lock_init(&tp_vars->prerandom_lock);
- kref_get(&tp_vars->refcount);
- hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
- spin_unlock_bh(&bat_priv->tp_list_lock);
-
tp_vars->test_length = test_length;
if (!tp_vars->test_length)
tp_vars->test_length = BATADV_TP_DEF_TEST_LENGTH;
+ /* init work item for finished tp tests */
+ INIT_DELAYED_WORK(&tp_vars->finish_work, batadv_tp_sender_finish);
+
+ kref_get(&tp_vars->refcount);
+ hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
+ spin_unlock_bh(&bat_priv->tp_list_lock);
+
batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
"Meter: starting throughput meter towards %pM (length=%ums)\n",
dst, test_length);
- /* init work item for finished tp tests */
- INIT_DELAYED_WORK(&tp_vars->finish_work, batadv_tp_sender_finish);
-
/* start tp kthread. This way the write() call issued from userspace can
* happily return and avoid to block
*/
@@ -1430,10 +1430,10 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,
INIT_LIST_HEAD(&tp_vars->unacked_list);
kref_get(&tp_vars->refcount);
- hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
+ timer_setup(&tp_vars->timer, batadv_tp_receiver_shutdown, 0);
kref_get(&tp_vars->refcount);
- timer_setup(&tp_vars->timer, batadv_tp_receiver_shutdown, 0);
+ hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
batadv_tp_reset_receiver_timer(tp_vars);