net: ip_expire() must revalidate route
authorEric Dumazet <eric.dumazet@gmail.com>
Wed, 4 May 2011 10:02:26 +0000 (10:02 +0000)
committerSteve Conklin <sconklin@canonical.com>
Thu, 2 Jun 2011 19:23:23 +0000 (14:23 -0500)
commit77ae4e1f052e4a898b0bc443b506eb7c15d6ad51
treeb327fa0319c84c3e1ae18dc884604e5524adc25c
parentffea945dac7e9bc12264370d169eee02f4949078
net: ip_expire() must revalidate route

BugLink: http://bugs.launchpad.net/bugs/788691

commit 64f3b9e203bd06855072e295557dca1485a2ecba upstream.

Commit 4a94445c9a5c (net: Use ip_route_input_noref() in input path)
added a bug in IP defragmentation handling, in case timeout is fired.

When a frame is defragmented, we use last skb dst field when building
final skb. Its dst is valid, since we are in rcu read section.

But if a timeout occurs, we take first queued fragment to build one ICMP
TIME EXCEEDED message. Problem is all queued skb have weak dst pointers,
since we escaped RCU critical section after their queueing. icmp_send()
might dereference a now freed (and possibly reused) part of memory.

Calling skb_dst_drop() and ip_route_input_noref() to revalidate route is
the only possible choice.

Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Steve Conklin <sconklin@canonical.com>
net/ipv4/ip_fragment.c