Commit 6fb9974f49f7a6032118c5b6caa6e08e7097913e

Authored by Herbert Xu
1 parent 203755029e

[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 <herbert@gondor.apana.org.au>

Showing 1 changed file with 2 additions and 2 deletions Side-by-side Diff

net/core/neighbour.c
... ... @@ -816,10 +816,10 @@
816 816 }
817 817  
818 818 if (neigh->nud_state & NUD_IN_TIMER) {
819   - neigh_hold(neigh);
820 819 if (time_before(next, jiffies + HZ/2))
821 820 next = jiffies + HZ/2;
822   - neigh_add_timer(neigh, next);
  821 + if (!mod_timer(&neigh->timer, next))
  822 + neigh_hold(neigh);
823 823 }
824 824 if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
825 825 struct sk_buff *skb = skb_peek(&neigh->arp_queue);