]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
batman-adv: bla: annotate lasttime access with READ/WRITE_ONCE
authorSven Eckelmann <sven@narfation.org>
Tue, 26 May 2026 19:50:51 +0000 (21:50 +0200)
committerSven Eckelmann <sven@narfation.org>
Wed, 3 Jun 2026 06:25:11 +0000 (08:25 +0200)
The lasttime field for claim, backbone_gw, and loopdetect tracks the
jiffies value of the most recent activity and is used to detect timeouts.
These accesses are not consistently protected by a lock, so
READ_ONCE/WRITE_ONCE must be used to prevent data races caused by compiler
optimizations.

Cc: stable@kernel.org
Fixes: 23721387c409 ("batman-adv: add basic bridge loop avoidance code")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
net/batman-adv/bridge_loop_avoidance.c

index 87d6b11161e4aeabcda02fc81b175c9a19b15df0..0461f11227d06b50802b8d30a4809d615a4b9ca4 100644 (file)
@@ -513,7 +513,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, const u8 *orig,
                return NULL;
 
        entry->vid = vid;
-       entry->lasttime = jiffies;
+       WRITE_ONCE(entry->lasttime, jiffies);
        entry->crc = BATADV_BLA_CRC_INIT;
        entry->bat_priv = bat_priv;
        spin_lock_init(&entry->crc_lock);
@@ -581,7 +581,7 @@ batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
        if (unlikely(!backbone_gw))
                return;
 
-       backbone_gw->lasttime = jiffies;
+       WRITE_ONCE(backbone_gw->lasttime, jiffies);
        batadv_backbone_gw_put(backbone_gw);
 }
 
@@ -715,7 +715,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
                ether_addr_copy(claim->addr, mac);
                spin_lock_init(&claim->backbone_lock);
                claim->vid = vid;
-               claim->lasttime = jiffies;
+               WRITE_ONCE(claim->lasttime, jiffies);
                kref_get(&backbone_gw->refcount);
                claim->backbone_gw = backbone_gw;
                kref_init(&claim->refcount);
@@ -737,7 +737,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
                        return;
                }
        } else {
-               claim->lasttime = jiffies;
+               WRITE_ONCE(claim->lasttime, jiffies);
                if (claim->backbone_gw == backbone_gw)
                        /* no need to register a new backbone */
                        goto claim_free_ref;
@@ -770,7 +770,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
        spin_lock_bh(&backbone_gw->crc_lock);
        backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
        spin_unlock_bh(&backbone_gw->crc_lock);
-       backbone_gw->lasttime = jiffies;
+       WRITE_ONCE(backbone_gw->lasttime, jiffies);
 
 claim_free_ref:
        batadv_claim_put(claim);
@@ -859,7 +859,7 @@ static bool batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,
                return true;
 
        /* handle as ANNOUNCE frame */
-       backbone_gw->lasttime = jiffies;
+       WRITE_ONCE(backbone_gw->lasttime, jiffies);
        crc = ntohs(*((__force __be16 *)(&an_addr[4])));
 
        batadv_dbg(BATADV_DBG_BLA, bat_priv,
@@ -1254,7 +1254,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
                                                  head, hash_entry) {
                                if (now)
                                        goto purge_now;
-                               if (!batadv_has_timed_out(backbone_gw->lasttime,
+                               if (!batadv_has_timed_out(READ_ONCE(backbone_gw->lasttime),
                                                          BATADV_BLA_BACKBONE_TIMEOUT))
                                        continue;
 
@@ -1335,7 +1335,7 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
                                                primary_if->net_dev->dev_addr))
                                goto skip;
 
-                       if (!batadv_has_timed_out(claim->lasttime,
+                       if (!batadv_has_timed_out(READ_ONCE(claim->lasttime),
                                                  BATADV_BLA_CLAIM_TIMEOUT))
                                goto skip;
 
@@ -1495,7 +1495,7 @@ static void batadv_bla_periodic_work(struct work_struct *work)
                eth_random_addr(bat_priv->bla.loopdetect_addr);
                bat_priv->bla.loopdetect_addr[0] = 0xba;
                bat_priv->bla.loopdetect_addr[1] = 0xbe;
-               bat_priv->bla.loopdetect_lasttime = jiffies;
+               WRITE_ONCE(bat_priv->bla.loopdetect_lasttime, jiffies);
                atomic_set(&bat_priv->bla.loopdetect_next,
                           BATADV_BLA_LOOPDETECT_PERIODS);
 
@@ -1516,7 +1516,7 @@ static void batadv_bla_periodic_work(struct work_struct *work)
                                                primary_if->net_dev->dev_addr))
                                continue;
 
-                       backbone_gw->lasttime = jiffies;
+                       WRITE_ONCE(backbone_gw->lasttime, jiffies);
 
                        batadv_bla_send_announce(bat_priv, backbone_gw);
                        if (send_loopdetect)
@@ -1900,7 +1900,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
        /* If the packet came too late, don't forward it on the mesh
         * but don't consider that as loop. It might be a coincidence.
         */
-       if (batadv_has_timed_out(bat_priv->bla.loopdetect_lasttime,
+       if (batadv_has_timed_out(READ_ONCE(bat_priv->bla.loopdetect_lasttime),
                                 BATADV_BLA_LOOPDETECT_TIMEOUT))
                return true;
 
@@ -2015,7 +2015,7 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
 
        if (own_claim) {
                /* ... allow it in any case */
-               claim->lasttime = jiffies;
+               WRITE_ONCE(claim->lasttime, jiffies);
                goto allow;
        }
 
@@ -2117,7 +2117,7 @@ bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
                /* if yes, the client has roamed and we have
                 * to unclaim it.
                 */
-               if (batadv_has_timed_out(claim->lasttime, 100)) {
+               if (batadv_has_timed_out(READ_ONCE(claim->lasttime), 100)) {
                        /* only unclaim if the last claim entry is
                         * older than 100 ms to make sure we really
                         * have a roaming client here.
@@ -2362,7 +2362,7 @@ batadv_bla_backbone_dump_entry(struct sk_buff *msg, u32 portid,
        backbone_crc = backbone_gw->crc;
        spin_unlock_bh(&backbone_gw->crc_lock);
 
-       msecs = jiffies_to_msecs(jiffies - backbone_gw->lasttime);
+       msecs = jiffies_to_msecs(jiffies - READ_ONCE(backbone_gw->lasttime));
 
        if (is_own)
                if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) {