From 5f80c363677c6aea0f2fc9a4fe0b5622abd97674 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Tue, 2 Jun 2026 17:20:57 +0200 Subject: [PATCH] batman-adv: tt: sync local and global tvlv preparation return values The batadv_tt_prepare_tvlv_local_data() and batadv_tt_prepare_tvlv_global_data() functions are supposed to work the same - just with different sources for the TT entries. But both handled the return values completely different. The global variant only made sure that the *tt_len parameter was set to 0 and didn't care about the actual return value of the function. The local function never made sure that the *tt_len value was set to some value when the operation failed. The callers were handling these differences and made sure that they didn't access the incorrectly initialized variable. Sync both function as good as possible to avoid problems with new code which might not be aware of these differences in the behavior. Signed-off-by: Sven Eckelmann --- net/batman-adv/translation-table.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 5e134d08a80f..44bbaa3bb37d 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -797,21 +797,22 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, struct batadv_tvlv_tt_change **tt_change, s32 *tt_len) { - u16 num_vlan = 0; - u16 tvlv_len = 0; struct batadv_tvlv_tt_vlan_data *tt_vlan; struct batadv_orig_node_vlan *vlan; u16 total_entries = 0; size_t change_offset; u8 *tt_change_ptr; + u16 num_vlan = 0; int vlan_entries; u16 sum_entries; + u16 tvlv_len; spin_lock_bh(&orig_node->vlan_list_lock); hlist_for_each_entry(vlan, &orig_node->vlan_list, list) { vlan_entries = atomic_read(&vlan->tt.num_entries); if (check_add_overflow(vlan_entries, total_entries, &sum_entries)) { + tvlv_len = 0; *tt_len = 0; goto out; } @@ -827,12 +828,14 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, *tt_len = batadv_tt_len(total_entries); if (check_add_overflow(*tt_len, change_offset, &tvlv_len)) { + tvlv_len = 0; *tt_len = 0; goto out; } *tt_data = kmalloc(tvlv_len, GFP_ATOMIC); if (!*tt_data) { + tvlv_len = 0; *tt_len = 0; goto out; } @@ -867,6 +870,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, out: spin_unlock_bh(&orig_node->vlan_list_lock); + return tvlv_len; } @@ -896,13 +900,13 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, { struct batadv_tvlv_tt_vlan_data *tt_vlan; struct batadv_meshif_vlan *vlan; - size_t change_offset; - u16 num_vlan = 0; u16 total_entries = 0; - u16 tvlv_len; + size_t change_offset; u8 *tt_change_ptr; + u16 num_vlan = 0; int vlan_entries; u16 sum_entries; + u16 tvlv_len; spin_lock_bh(&bat_priv->meshif_vlan_list_lock); hlist_for_each_entry(vlan, &bat_priv->meshif_vlan_list, list) { @@ -910,6 +914,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, if (check_add_overflow(vlan_entries, total_entries, &sum_entries)) { tvlv_len = 0; + *tt_len = 0; goto out; } @@ -925,12 +930,14 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, if (check_add_overflow(*tt_len, change_offset, &tvlv_len)) { tvlv_len = 0; + *tt_len = 0; goto out; } *tt_data = kmalloc(tvlv_len, GFP_ATOMIC); if (!*tt_data) { tvlv_len = 0; + *tt_len = 0; goto out; } @@ -964,6 +971,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, out: spin_unlock_bh(&bat_priv->meshif_vlan_list_lock); + return tvlv_len; }