From: Sven Eckelmann Date: Tue, 2 Jun 2026 15:20:57 +0000 (+0200) Subject: batman-adv: tt: sync local and global tvlv preparation return values X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f80c363677c6aea0f2fc9a4fe0b5622abd97674;p=thirdparty%2Flinux.git 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 --- diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 5e134d08a80fd..44bbaa3bb37d1 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; }