[linux-next] LinuxNextTracking branch, master, updated. next-20150107

batman at open-mesh.org batman at open-mesh.org
Thu Jan 8 00:21:30 CET 2015


The following commit has been merged in the master branch:
commit 9d31b3ce81683ce3c9fd10afa70892e373b21067
Author: Linus Lüssing <linus.luessing at c0d3.blue>
Date:   Sat Dec 13 23:32:15 2014 +0100

    batman-adv: fix potential TT client + orig-node memory leak
    
    This patch fixes a potential memory leak which can occur once an
    originator times out. On timeout the according global translation table
    entry might not get purged correctly. Furthermore, the non purged TT
    entry will cause its orig-node to leak, too. Which additionally can lead
    to the new multicast optimization feature not kicking in because of a
    therefore bogus counter.
    
    In detail: The batadv_tt_global_entry->orig_list holds the reference to
    the orig-node. Usually this reference is released after
    BATADV_PURGE_TIMEOUT through: _batadv_purge_orig()->
    batadv_purge_orig_node()->batadv_update_route()->_batadv_update_route()->
    batadv_tt_global_del_orig() which purges this global tt entry and
    releases the reference to the orig-node.
    
    However, if between two batadv_purge_orig_node() calls the orig-node
    timeout grew to 2*BATADV_PURGE_TIMEOUT then this call path isn't
    reached. Instead the according orig-node is removed from the
    originator hash in _batadv_purge_orig(), the batadv_update_route()
    part is skipped and won't be reached anymore.
    
    Fixing the issue by moving batadv_tt_global_del_orig() out of the rcu
    callback.
    
    Signed-off-by: Linus Lüssing <linus.luessing at c0d3.blue>
    Acked-by: Antonio Quartulli <antonio at meshcoding.com>
    Signed-off-by: Marek Lindner <mareklindner at neomailbox.ch>
    Signed-off-by: Antonio Quartulli <antonio at meshcoding.com>

diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 648bdba..bea8198 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -570,9 +570,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
 
 	batadv_frag_purge_orig(orig_node, NULL);
 
-	batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1,
-				  "originator timed out");
-
 	if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
 		orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
 
@@ -978,6 +975,9 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
 			if (batadv_purge_orig_node(bat_priv, orig_node)) {
 				batadv_gw_node_delete(bat_priv, orig_node);
 				hlist_del_rcu(&orig_node->hash_entry);
+				batadv_tt_global_del_orig(orig_node->bat_priv,
+							  orig_node, -1,
+							  "originator timed out");
 				batadv_orig_node_free_ref(orig_node);
 				continue;
 			}

-- 
LinuxNextTracking


More information about the linux-merge mailing list