aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@ascom.ch>2011-02-18 07:20:13 -0500
committerMarek Lindner <lindner_marek@yahoo.de>2011-03-05 06:50:13 -0500
commit9e0b33c221f1364e4d7562177a918eef8e85317a (patch)
tree817088eeeecc694cf9ad06a563321b2d11f2f0cd /net
parent43c70ad5ce5691cce24dae6610731694c0f3fcc8 (diff)
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>
Diffstat (limited to 'net')
-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)
171 struct bat_priv *bat_priv = netdev_priv(net_dev); 171 struct bat_priv *bat_priv = netdev_priv(net_dev);
172 struct softif_neigh *softif_neigh; 172 struct softif_neigh *softif_neigh;
173 struct hlist_node *node; 173 struct hlist_node *node;
174 size_t buf_size, pos;
175 char *buff;
176 174
177 if (!bat_priv->primary_if) { 175 if (!bat_priv->primary_if) {
178 return seq_printf(seq, "BATMAN mesh %s disabled - " 176 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 180
183 seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); 181 seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
184 182
185 buf_size = 1;
186 /* Estimate length for: " xx:xx:xx:xx:xx:xx\n" */
187 rcu_read_lock(); 183 rcu_read_lock();
188 hlist_for_each_entry_rcu(softif_neigh, node, 184 hlist_for_each_entry_rcu(softif_neigh, node,
189 &bat_priv->softif_neigh_list, list) 185 &bat_priv->softif_neigh_list, list)
190 buf_size += 30; 186 seq_printf(seq, "%s %pM (vid: %d)\n",
191 rcu_read_unlock();
192
193 buff = kmalloc(buf_size, GFP_ATOMIC);
194 if (!buff)
195 return -ENOMEM;
196
197 buff[0] = '\0';
198 pos = 0;
199
200 rcu_read_lock();
201 hlist_for_each_entry_rcu(softif_neigh, node,
202 &bat_priv->softif_neigh_list, list) {
203 pos += snprintf(buff + pos, 31, "%s %pM (vid: %d)\n",
204 bat_priv->softif_neigh == softif_neigh 187 bat_priv->softif_neigh == softif_neigh
205 ? "=>" : " ", softif_neigh->addr, 188 ? "=>" : " ", softif_neigh->addr,
206 softif_neigh->vid); 189 softif_neigh->vid);
207 }
208 rcu_read_unlock(); 190 rcu_read_unlock();
209 191
210 seq_printf(seq, "%s", buff);
211 kfree(buff);
212 return 0; 192 return 0;
213} 193}
214 194