In article <0320111483D8B84AAAB437215BBDA526D605B3@NAEX01.na.qualcomm.com> (at Tue, 5 Oct 2004 15:08:47 -0700), "Craig, Dave" <dwcraig@qualcomm.com> says:
> Please consider including the attached patch at the end of this file. It fixes a NULL pointer dereference of skb->dev->ip6_ptr in the following call flow.
Looks fine to me. David, please apply.
BTW, please "sign-off" next time.
Thanks.
Signed-off-by: Hidaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
--
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
--- Begin Message ---
- To: <linux-net@vger.kernel.org>
- Subject: skb->dev NULL pointer dereference in icmpv6_send() in linux-2.6.9-rc3 and earlier
- From: "Craig, Dave" <dwcraig@qualcomm.com>
- Date: Tue, 5 Oct 2004 15:08:47 -0700
- Delivered-to: yoshfuji@yue.st-paulia.net
- Delivered-to: yoshfuji@sapphire.st-paulia.net
- Sender: linux-net-owner@vger.kernel.org
- Thread-index: AcSrJ+D+tcv0XewjQKmlhMwgCT1Fpw==
- Thread-topic: skb->dev NULL pointer dereference in icmpv6_send() in linux-2.6.9-rc3 and earlier
Please consider including the attached 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);
}
--- End Message ---