Skip to contentSkip to conversation

Fix potencial null pointer dereference.

NETROM Ralf Baechle DL5RB 1 participant 1 message May 13, 2006 Networking

lore
Share & tools
lore
#0 lore raw

If the neighbour list becomes empty just just in the time during which we've dropped nr_neigh_list_lock the missing braces around the second loop block in nr_link_failed may result in a NULL pointer getting dereferenced. This race can only be triggered on a SMP or preemptible kernel.

Test reports appreciated.

---
 net/netrom/nr_route.c |   25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)
net/netrom/nr_route.c +13 -12
Index: linux-net/net/netrom/nr_route.c
===================================================================
@@ -725,31 +725,32 @@ void nr_link_failed(ax25_cb *ax25, int r
 	struct nr_node  *nr_node = NULL;
 
 	spin_lock_bh(&nr_neigh_list_lock);
-	nr_neigh_for_each(s, node, &nr_neigh_list)
+	nr_neigh_for_each(s, node, &nr_neigh_list) {
 		if (s->ax25 == ax25) {
-			nr_neigh_hold(s);
 			nr_neigh = s;
 			break;
 		}
-	spin_unlock_bh(&nr_neigh_list_lock);
+	}
 
-	if (nr_neigh == NULL) return;
+	if (nr_neigh == NULL)
+		goto out_unlock;
 
 	nr_neigh->ax25 = NULL;
 	ax25_cb_put(ax25);
 
-	if (++nr_neigh->failed < sysctl_netrom_link_fails_count) {
-		nr_neigh_put(nr_neigh);
-		return;
-	}
-	spin_lock_bh(&nr_node_list_lock);
-	nr_node_for_each(nr_node, node, &nr_node_list)
+	if (++nr_neigh->failed < sysctl_netrom_link_fails_count)
+		goto out_unlock;
+
+	nr_node_for_each(nr_node, node, &nr_node_list) {
 		nr_node_lock(nr_node);
-		if (nr_node->which < nr_node->count && nr_node->routes[nr_node->which].neighbour == nr_neigh)
+		if (nr_node->which < nr_node->count &&
+		    nr_node->routes[nr_node->which].neighbour == nr_neigh)
 			nr_node->which++;
 		nr_node_unlock(nr_node);
+	}
+
+out_unlock:
 	spin_unlock_bh(&nr_node_list_lock);
-	nr_neigh_put(nr_neigh);
 }
 
 /*