Commit 9e0b33c2 authored by Linus Lüssing's avatar Linus Lüssing Committed by Marek Lindner

batman-adv: Fix possible buffer overflow in softif neigh list output

When printing the soft interface table the number of entries in the
softif neigh list are first being counted and a fitting buffer
allocated. After that the softif neigh list gets locked again and
the buffer printed - which has the following two issues:

For one thing, the softif neigh list might have grown when reacquiring
the rcu lock, which results in writing outside of the allocated buffer.
Furthermore 31 Bytes are not enough for printing an entry with a vid
of more than 2 digits.

The manual buffering is unnecessary, we can safely print to the seq
directly during the rcu_read_lock().
Signed-off-by: default avatarLinus Lüssing <linus.luessing@ascom.ch>
Signed-off-by: default avatarMarek Lindner <lindner_marek@yahoo.de>
parent 43c70ad5
...@@ -171,8 +171,6 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) ...@@ -171,8 +171,6 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
struct bat_priv *bat_priv = netdev_priv(net_dev); struct bat_priv *bat_priv = netdev_priv(net_dev);
struct softif_neigh *softif_neigh; struct softif_neigh *softif_neigh;
struct hlist_node *node; struct hlist_node *node;
size_t buf_size, pos;
char *buff;
if (!bat_priv->primary_if) { if (!bat_priv->primary_if) {
return seq_printf(seq, "BATMAN mesh %s disabled - " return seq_printf(seq, "BATMAN mesh %s disabled - "
...@@ -182,33 +180,15 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) ...@@ -182,33 +180,15 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
buf_size = 1;
/* Estimate length for: " xx:xx:xx:xx:xx:xx\n" */
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(softif_neigh, node, hlist_for_each_entry_rcu(softif_neigh, node,
&bat_priv->softif_neigh_list, list) &bat_priv->softif_neigh_list, list)
buf_size += 30; seq_printf(seq, "%s %pM (vid: %d)\n",
rcu_read_unlock();
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff)
return -ENOMEM;
buff[0] = '\0';
pos = 0;
rcu_read_lock();
hlist_for_each_entry_rcu(softif_neigh, node,
&bat_priv->softif_neigh_list, list) {
pos += snprintf(buff + pos, 31, "%s %pM (vid: %d)\n",
bat_priv->softif_neigh == softif_neigh bat_priv->softif_neigh == softif_neigh
? "=>" : " ", softif_neigh->addr, ? "=>" : " ", softif_neigh->addr,
softif_neigh->vid); softif_neigh->vid);
}
rcu_read_unlock(); rcu_read_unlock();
seq_printf(seq, "%s", buff);
kfree(buff);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment