summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@ascom.ch>2011-02-18 13:20:13 +0100
committerMarek Lindner <lindner_marek@yahoo.de>2011-03-05 12:50:13 +0100
commit9e0b33c221f1364e4d7562177a918eef8e85317a (patch)
tree817088eeeecc694cf9ad06a563321b2d11f2f0cd
parentbatman-adv: Increase orig_node refcount before releasing rcu read lock (diff)
downloadlinux-9e0b33c221f1364e4d7562177a918eef8e85317a.tar.xz
linux-9e0b33c221f1364e4d7562177a918eef8e85317a.zip
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: Linus Lüssing <linus.luessing@ascom.ch> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
-rw-r--r--net/batman-adv/soft-interface.c22
1 files changed, 1 insertions, 21 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 152beaafae1d..c30ccd66786a 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -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 softif_neigh *softif_neigh;
struct hlist_node *node;
- size_t buf_size, pos;
- char *buff;
if (!bat_priv->primary_if) {
return seq_printf(seq, "BATMAN mesh %s disabled - "
@@ -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);
- buf_size = 1;
- /* Estimate length for: " xx:xx:xx:xx:xx:xx\n" */
rcu_read_lock();
hlist_for_each_entry_rcu(softif_neigh, node,
&bat_priv->softif_neigh_list, list)
- buf_size += 30;
- 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",
+ seq_printf(seq, "%s %pM (vid: %d)\n",
bat_priv->softif_neigh == softif_neigh
? "=>" : " ", softif_neigh->addr,
softif_neigh->vid);
- }
rcu_read_unlock();
- seq_printf(seq, "%s", buff);
- kfree(buff);
return 0;
}