[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(usagi-users 03054) skb->dev NULL pointer dereference in icmpv6_send() in linux-2.6.9-rc3 and earlier



Please consider including the small patch at the end of this file. It
fixes a NULL pointer dereference of skb->dev->ip6_ptr in the following
call flow.

ip6_xmit
-> (ip6_null_entry.output) ip6_pkt_discard_out
-> ip6_pkt_discard
-> icmpv6_send
-> in6_dev_get

The patch sets skb->dev to dst->dev.  This is a mirror of the
initialization in ip6_output2().  In both cases, the packet got to these
routines through dst->output(), so it is safe to assume that dst is not
NULL.

I have only observed this problem using SCTP/IPv6.  I think the
association is attempting to retransmit after the endpoints have been
torn down, so sctp_transport->dst == ip6_null_entry.  If the
ip6_null_entry is a valid destination returned by route look up
(ip6_null_entry.u.dst.path), support equivalent to ip6_output2 probably
should exist.  The change below fixes the kernel panics I have observed.

Thanks,
	Dave Craig

--- linux-2.6.9-rc3/net/ipv6/route.c.orig       2004-10-01
13:29:29.000000000 -0700
+++ linux-2.6.9-rc3/net/ipv6/route.c    2004-10-01 13:38:09.000000000
-0700
@@ -1357,6 +1357,14 @@
 
 int ip6_pkt_discard_out(struct sk_buff **pskb)
 {
+       (*pskb)->dev = (*pskb)->dst->dev;
+       if (NULL == (*pskb)->dev) {
+               /*
+                 * Perhaps we should discard rather than reject.
+                 * icmpv6_send() will fault trying
(*pskb)->dev->ip6_ptr.
+                 */
+               BUG();
+       }
        return ip6_pkt_discard(*pskb);
 }