Skip to content

Commit 564d74d

Browse files
committed
Merge tag 'batadv-net-pullrequest-20241210' of git://git.open-mesh.org/linux-merge
Simon Wunderlich says: ==================== Here are some batman-adv bugfixes: - fix TT unitialized data and size limit issues, by Remi Pommarel (3 patches) * tag 'batadv-net-pullrequest-20241210' of git://git.open-mesh.org/linux-merge: batman-adv: Do not let TT changes list grows indefinitely batman-adv: Remove uninitialized data in full table TT response batman-adv: Do not send uninitialized TT changes ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents acfcdb7 + fff8f17 commit 564d74d

File tree

1 file changed

+40
-18
lines changed

1 file changed

+40
-18
lines changed

net/batman-adv/translation-table.c

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -948,16 +948,25 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
948948
int tt_diff_len, tt_change_len = 0;
949949
int tt_diff_entries_num = 0;
950950
int tt_diff_entries_count = 0;
951+
bool drop_changes = false;
952+
size_t tt_extra_len = 0;
951953
u16 tvlv_len;
952954

953955
tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes);
954956
tt_diff_len = batadv_tt_len(tt_diff_entries_num);
955957

956958
/* if we have too many changes for one packet don't send any
957-
* and wait for the tt table request which will be fragmented
959+
* and wait for the tt table request so we can reply with the full
960+
* (fragmented) table.
961+
*
962+
* The local change history should still be cleaned up so the next
963+
* TT round can start again with a clean state.
958964
*/
959-
if (tt_diff_len > bat_priv->soft_iface->mtu)
965+
if (tt_diff_len > bat_priv->soft_iface->mtu) {
960966
tt_diff_len = 0;
967+
tt_diff_entries_num = 0;
968+
drop_changes = true;
969+
}
961970

962971
tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
963972
&tt_change, &tt_diff_len);
@@ -966,7 +975,7 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
966975

967976
tt_data->flags = BATADV_TT_OGM_DIFF;
968977

969-
if (tt_diff_len == 0)
978+
if (!drop_changes && tt_diff_len == 0)
970979
goto container_register;
971980

972981
spin_lock_bh(&bat_priv->tt.changes_list_lock);
@@ -985,6 +994,9 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
985994
}
986995
spin_unlock_bh(&bat_priv->tt.changes_list_lock);
987996

997+
tt_extra_len = batadv_tt_len(tt_diff_entries_num -
998+
tt_diff_entries_count);
999+
9881000
/* Keep the buffer for possible tt_request */
9891001
spin_lock_bh(&bat_priv->tt.last_changeset_lock);
9901002
kfree(bat_priv->tt.last_changeset);
@@ -993,6 +1005,7 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
9931005
tt_change_len = batadv_tt_len(tt_diff_entries_count);
9941006
/* check whether this new OGM has no changes due to size problems */
9951007
if (tt_diff_entries_count > 0) {
1008+
tt_diff_len -= tt_extra_len;
9961009
/* if kmalloc() fails we will reply with the full table
9971010
* instead of providing the diff
9981011
*/
@@ -1005,6 +1018,8 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
10051018
}
10061019
spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
10071020

1021+
/* Remove extra packet space for OGM */
1022+
tvlv_len -= tt_extra_len;
10081023
container_register:
10091024
batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
10101025
tvlv_len);
@@ -2705,14 +2720,16 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
27052720
*
27062721
* Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
27072722
* is not provided then this becomes a no-op.
2723+
*
2724+
* Return: Remaining unused length in tvlv_buff.
27082725
*/
2709-
static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2710-
struct batadv_hashtable *hash,
2711-
void *tvlv_buff, u16 tt_len,
2712-
bool (*valid_cb)(const void *,
2713-
const void *,
2714-
u8 *flags),
2715-
void *cb_data)
2726+
static u16 batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2727+
struct batadv_hashtable *hash,
2728+
void *tvlv_buff, u16 tt_len,
2729+
bool (*valid_cb)(const void *,
2730+
const void *,
2731+
u8 *flags),
2732+
void *cb_data)
27162733
{
27172734
struct batadv_tt_common_entry *tt_common_entry;
27182735
struct batadv_tvlv_tt_change *tt_change;
@@ -2726,7 +2743,7 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
27262743
tt_change = tvlv_buff;
27272744

27282745
if (!valid_cb)
2729-
return;
2746+
return tt_len;
27302747

27312748
rcu_read_lock();
27322749
for (i = 0; i < hash->size; i++) {
@@ -2752,6 +2769,8 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
27522769
}
27532770
}
27542771
rcu_read_unlock();
2772+
2773+
return batadv_tt_len(tt_tot - tt_num_entries);
27552774
}
27562775

27572776
/**
@@ -3022,10 +3041,11 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
30223041
goto out;
30233042

30243043
/* fill the rest of the tvlv with the real TT entries */
3025-
batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash,
3026-
tt_change, tt_len,
3027-
batadv_tt_global_valid,
3028-
req_dst_orig_node);
3044+
tvlv_len -= batadv_tt_tvlv_generate(bat_priv,
3045+
bat_priv->tt.global_hash,
3046+
tt_change, tt_len,
3047+
batadv_tt_global_valid,
3048+
req_dst_orig_node);
30293049
}
30303050

30313051
/* Don't send the response, if larger than fragmented packet. */
@@ -3149,9 +3169,11 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
31493169
goto out;
31503170

31513171
/* fill the rest of the tvlv with the real TT entries */
3152-
batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash,
3153-
tt_change, tt_len,
3154-
batadv_tt_local_valid, NULL);
3172+
tvlv_len -= batadv_tt_tvlv_generate(bat_priv,
3173+
bat_priv->tt.local_hash,
3174+
tt_change, tt_len,
3175+
batadv_tt_local_valid,
3176+
NULL);
31553177
}
31563178

31573179
tvlv_tt_data->flags = BATADV_TT_RESPONSE;

0 commit comments

Comments
 (0)