From: Herbert Xu Date: Sun, 23 Oct 2005 06:37:48 +0000 (+1000) Subject: [NEIGH] Fix add_timer race in neigh_add_timer X-Git-Tag: v2.6.14~40^2~1 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6fb9974f49f7a6032118c5b6caa6e08e7097913e;p=linux-2.6 [NEIGH] Fix add_timer race in neigh_add_timer neigh_add_timer cannot use add_timer unconditionally. The reason is that by the time it has obtained the write lock someone else (e.g., neigh_update) could have already added a new timer. So it should only use mod_timer and deal with its return value accordingly. This bug would have led to rare neighbour cache entry leaks. Signed-off-by: Herbert Xu --- diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 766caa0dd9..37d8d8c295 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -816,10 +816,10 @@ static void neigh_timer_handler(unsigned long arg) } if (neigh->nud_state & NUD_IN_TIMER) { - neigh_hold(neigh); if (time_before(next, jiffies + HZ/2)) next = jiffies + HZ/2; - neigh_add_timer(neigh, next); + if (!mod_timer(&neigh->timer, next)) + neigh_hold(neigh); } if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { struct sk_buff *skb = skb_peek(&neigh->arp_queue);