diff options
author | Antonio Quartulli <antonio@meshcoding.com> | 2014-02-14 20:17:20 -0500 |
---|---|---|
committer | Antonio Quartulli <antonio@meshcoding.com> | 2014-02-17 11:17:02 -0500 |
commit | a5a5cb8cab526af2f6cbe9715f8ca843192f0d81 (patch) | |
tree | 8f456b9e7f4cfb8efde3af1ce47f96321cc17d94 | |
parent | 05c3c8a636aa9ee35ce13f65afc5b665615cc786 (diff) |
batman-adv: avoid double free when orig_node initialization fails
In the failure path of the orig_node initialization routine
the orig_node->bat_iv.bcast_own field is free'd twice: first
in batadv_iv_ogm_orig_get() and then later in
batadv_orig_node_free_rcu().
Fix it by removing the kfree in batadv_iv_ogm_orig_get().
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 42cbc0a68941..8323bced8e5b 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -241,18 +241,16 @@ batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr) | |||
241 | size = bat_priv->num_ifaces * sizeof(uint8_t); | 241 | size = bat_priv->num_ifaces * sizeof(uint8_t); |
242 | orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC); | 242 | orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC); |
243 | if (!orig_node->bat_iv.bcast_own_sum) | 243 | if (!orig_node->bat_iv.bcast_own_sum) |
244 | goto free_bcast_own; | 244 | goto free_orig_node; |
245 | 245 | ||
246 | hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, | 246 | hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, |
247 | batadv_choose_orig, orig_node, | 247 | batadv_choose_orig, orig_node, |
248 | &orig_node->hash_entry); | 248 | &orig_node->hash_entry); |
249 | if (hash_added != 0) | 249 | if (hash_added != 0) |
250 | goto free_bcast_own; | 250 | goto free_orig_node; |
251 | 251 | ||
252 | return orig_node; | 252 | return orig_node; |
253 | 253 | ||
254 | free_bcast_own: | ||
255 | kfree(orig_node->bat_iv.bcast_own); | ||
256 | free_orig_node: | 254 | free_orig_node: |
257 | /* free twice, as batadv_orig_node_new sets refcount to 2 */ | 255 | /* free twice, as batadv_orig_node_new sets refcount to 2 */ |
258 | batadv_orig_node_free_ref(orig_node); | 256 | batadv_orig_node_free_ref(orig_node); |