summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2026-06-02 17:20:57 +0200
committerSven Eckelmann <sven@narfation.org>2026-06-03 08:27:17 +0200
commit5f80c363677c6aea0f2fc9a4fe0b5622abd97674 (patch)
treefb949f8d6e9b04a04221092cb60a61f59628177f
parent5e50d4b8ae3ea622122d3c6a38d7f6fe68dfddca (diff)
downloadlinux-5f80c363677c6aea0f2fc9a4fe0b5622abd97674.tar.gz
linux-5f80c363677c6aea0f2fc9a4fe0b5622abd97674.zip
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 <sven@narfation.org>
-rw-r--r--net/batman-adv/translation-table.c18
1 files 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;
}