Fix potencial null pointer dereference.
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.
Signed-off-by Ralf Baechle <[email protected]>
--- net/netrom/nr_route.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
net/netrom/nr_route.c +13 -12
@@ -725,31 +725,32 @@ void nr_link_failed(ax25_cb *ax25, int rstruct 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); }/*