summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2026-06-26 18:11:06 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-04 13:41:30 +0200
commitda0f5a693b11ea983051be8c260aa3e17a8161be (patch)
tree15a02ecb06fb8763d0be4d9f5e17a36ba017dadb
parentcb01fe90e8f4df5ff84fc72c4de49cd8abd5975e (diff)
downloadlinux-stable-da0f5a693b11ea983051be8c260aa3e17a8161be.tar.gz
linux-stable-da0f5a693b11ea983051be8c260aa3e17a8161be.zip
batman-adv: tp_meter: add only finished tp_vars to lists
commit 15ccbf685222274f5add1387af58c2a41a95f81e upstream. 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> Signed-off-by: Sasha Levin <sashal@kernel.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 089ac7cc9fbe..2bba53fc6da5 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);