batman-adv: fix potential orig_node reference leak

Message ID 1391601768-6792-1-git-send-email-sw@simonwunderlich.de (mailing list archive)
State Superseded, archived
Headers

Commit Message

Simon Wunderlich Feb. 5, 2014, 12:02 p.m. UTC
  Since batadv_orig_node_new() does not add the originator into the orig
hash, it should only return the created orig_node object with a refcount
of one (for the object return). Otherwise batadv_iv_ogm_orig_get() will
not free the orig_node correctly when allocating its private structures
or adding to the hash fails (refcount will just be decreased to one) and
eventually leak it.

Reported-by: Antonio Quartulli <antonio@meshcoding.com>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
 bat_iv_ogm.c |    8 +++++++-
 originator.c |    3 +--
 2 files changed, 8 insertions(+), 3 deletions(-)
  

Patch

diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
index 7cf26bc..10acd39 100644
--- a/bat_iv_ogm.c
+++ b/bat_iv_ogm.c
@@ -243,11 +243,17 @@  batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr)
 	if (!orig_node->bat_iv.bcast_own_sum)
 		goto free_bcast_own;
 
+	/* increase refcount for the hash reference */
+	if (atomic_inc_not_zero(&orig_node->refcount))
+		goto free_bcast_own;
+
 	hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
 				     batadv_choose_orig, orig_node,
 				     &orig_node->hash_entry);
-	if (hash_added != 0)
+	if (hash_added != 0) {
+		batadv_orig_node_free_ref(orig_node);
 		goto free_bcast_own;
+	}
 
 	return orig_node;
 
diff --git a/originator.c b/originator.c
index c4d16e5..c308367 100644
--- a/originator.c
+++ b/originator.c
@@ -625,8 +625,7 @@  struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
 
 	batadv_nc_init_orig(orig_node);
 
-	/* extra reference for return */
-	atomic_set(&orig_node->refcount, 2);
+	atomic_set(&orig_node->refcount, 1);
 
 	orig_node->tt_initialised = false;
 	orig_node->bat_priv = bat_priv;