diff options
author | Marek Lindner <lindner_marek@yahoo.de> | 2011-04-20 09:40:58 -0400 |
---|---|---|
committer | Sven Eckelmann <sven@narfation.org> | 2011-05-01 16:49:03 -0400 |
commit | 32ae9b221e788413ce68feaae2ca39e406211a0a (patch) | |
tree | d827f989976a28fea5cdcb349c308baa98182c35 /net/batman-adv/translation-table.c | |
parent | 71e4aa9c465fd66c110667ab5d620fb6a4ef2157 (diff) |
batman-adv: Make bat_priv->primary_if an rcu protected pointer
The rcu protected macros rcu_dereference() and rcu_assign_pointer()
for the bat_priv->primary_if need to be used, as well as spin/rcu locking.
Otherwise we might end up using a primary_if pointer pointing to already
freed memory.
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r-- | net/batman-adv/translation-table.c | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 8d15b48d1692..f931830d630e 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "main.h" | 22 | #include "main.h" |
23 | #include "translation-table.h" | 23 | #include "translation-table.h" |
24 | #include "soft-interface.h" | 24 | #include "soft-interface.h" |
25 | #include "hard-interface.h" | ||
25 | #include "hash.h" | 26 | #include "hash.h" |
26 | #include "originator.h" | 27 | #include "originator.h" |
27 | 28 | ||
@@ -237,16 +238,26 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) | |||
237 | struct bat_priv *bat_priv = netdev_priv(net_dev); | 238 | struct bat_priv *bat_priv = netdev_priv(net_dev); |
238 | struct hashtable_t *hash = bat_priv->hna_local_hash; | 239 | struct hashtable_t *hash = bat_priv->hna_local_hash; |
239 | struct hna_local_entry *hna_local_entry; | 240 | struct hna_local_entry *hna_local_entry; |
241 | struct hard_iface *primary_if; | ||
240 | struct hlist_node *node; | 242 | struct hlist_node *node; |
241 | struct hlist_head *head; | 243 | struct hlist_head *head; |
242 | size_t buf_size, pos; | 244 | size_t buf_size, pos; |
243 | char *buff; | 245 | char *buff; |
244 | int i; | 246 | int i, ret = 0; |
245 | 247 | ||
246 | if (!bat_priv->primary_if) { | 248 | primary_if = primary_if_get_selected(bat_priv); |
247 | return seq_printf(seq, "BATMAN mesh %s disabled - " | 249 | if (!primary_if) { |
248 | "please specify interfaces to enable it\n", | 250 | ret = seq_printf(seq, "BATMAN mesh %s disabled - " |
249 | net_dev->name); | 251 | "please specify interfaces to enable it\n", |
252 | net_dev->name); | ||
253 | goto out; | ||
254 | } | ||
255 | |||
256 | if (primary_if->if_status != IF_ACTIVE) { | ||
257 | ret = seq_printf(seq, "BATMAN mesh %s disabled - " | ||
258 | "primary interface not active\n", | ||
259 | net_dev->name); | ||
260 | goto out; | ||
250 | } | 261 | } |
251 | 262 | ||
252 | seq_printf(seq, "Locally retrieved addresses (from %s) " | 263 | seq_printf(seq, "Locally retrieved addresses (from %s) " |
@@ -269,7 +280,8 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) | |||
269 | buff = kmalloc(buf_size, GFP_ATOMIC); | 280 | buff = kmalloc(buf_size, GFP_ATOMIC); |
270 | if (!buff) { | 281 | if (!buff) { |
271 | spin_unlock_bh(&bat_priv->hna_lhash_lock); | 282 | spin_unlock_bh(&bat_priv->hna_lhash_lock); |
272 | return -ENOMEM; | 283 | ret = -ENOMEM; |
284 | goto out; | ||
273 | } | 285 | } |
274 | 286 | ||
275 | buff[0] = '\0'; | 287 | buff[0] = '\0'; |
@@ -291,7 +303,10 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) | |||
291 | 303 | ||
292 | seq_printf(seq, "%s", buff); | 304 | seq_printf(seq, "%s", buff); |
293 | kfree(buff); | 305 | kfree(buff); |
294 | return 0; | 306 | out: |
307 | if (primary_if) | ||
308 | hardif_free_ref(primary_if); | ||
309 | return ret; | ||
295 | } | 310 | } |
296 | 311 | ||
297 | static void _hna_local_del(struct hlist_node *node, void *arg) | 312 | static void _hna_local_del(struct hlist_node *node, void *arg) |
@@ -468,16 +483,26 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) | |||
468 | struct bat_priv *bat_priv = netdev_priv(net_dev); | 483 | struct bat_priv *bat_priv = netdev_priv(net_dev); |
469 | struct hashtable_t *hash = bat_priv->hna_global_hash; | 484 | struct hashtable_t *hash = bat_priv->hna_global_hash; |
470 | struct hna_global_entry *hna_global_entry; | 485 | struct hna_global_entry *hna_global_entry; |
486 | struct hard_iface *primary_if; | ||
471 | struct hlist_node *node; | 487 | struct hlist_node *node; |
472 | struct hlist_head *head; | 488 | struct hlist_head *head; |
473 | size_t buf_size, pos; | 489 | size_t buf_size, pos; |
474 | char *buff; | 490 | char *buff; |
475 | int i; | 491 | int i, ret = 0; |
476 | 492 | ||
477 | if (!bat_priv->primary_if) { | 493 | primary_if = primary_if_get_selected(bat_priv); |
478 | return seq_printf(seq, "BATMAN mesh %s disabled - " | 494 | if (!primary_if) { |
479 | "please specify interfaces to enable it\n", | 495 | ret = seq_printf(seq, "BATMAN mesh %s disabled - please " |
480 | net_dev->name); | 496 | "specify interfaces to enable it\n", |
497 | net_dev->name); | ||
498 | goto out; | ||
499 | } | ||
500 | |||
501 | if (primary_if->if_status != IF_ACTIVE) { | ||
502 | ret = seq_printf(seq, "BATMAN mesh %s disabled - " | ||
503 | "primary interface not active\n", | ||
504 | net_dev->name); | ||
505 | goto out; | ||
481 | } | 506 | } |
482 | 507 | ||
483 | seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", | 508 | seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", |
@@ -499,7 +524,8 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) | |||
499 | buff = kmalloc(buf_size, GFP_ATOMIC); | 524 | buff = kmalloc(buf_size, GFP_ATOMIC); |
500 | if (!buff) { | 525 | if (!buff) { |
501 | spin_unlock_bh(&bat_priv->hna_ghash_lock); | 526 | spin_unlock_bh(&bat_priv->hna_ghash_lock); |
502 | return -ENOMEM; | 527 | ret = -ENOMEM; |
528 | goto out; | ||
503 | } | 529 | } |
504 | buff[0] = '\0'; | 530 | buff[0] = '\0'; |
505 | pos = 0; | 531 | pos = 0; |
@@ -522,7 +548,10 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) | |||
522 | 548 | ||
523 | seq_printf(seq, "%s", buff); | 549 | seq_printf(seq, "%s", buff); |
524 | kfree(buff); | 550 | kfree(buff); |
525 | return 0; | 551 | out: |
552 | if (primary_if) | ||
553 | hardif_free_ref(primary_if); | ||
554 | return ret; | ||
526 | } | 555 | } |
527 | 556 | ||
528 | static void _hna_global_del_orig(struct bat_priv *bat_priv, | 557 | static void _hna_global_del_orig(struct bat_priv *bat_priv, |