| From 3feec9095d12e311b7d4eb7fe7e5dfa75d4a72a5 Mon Sep 17 00:00:00 2001 |
| From: James Chapman <jchapman@katalix.com> |
| Date: Tue, 16 Mar 2010 06:46:31 +0000 |
| Subject: l2tp: Fix oops in pppol2tp_xmit |
| |
| From: James Chapman <jchapman@katalix.com> |
| |
| commit 3feec9095d12e311b7d4eb7fe7e5dfa75d4a72a5 upstream. |
| |
| When transmitting L2TP frames, we derive the outgoing interface's UDP |
| checksum hardware assist capabilities from the tunnel dst dev. This |
| can sometimes be NULL, especially when routing protocols are used and |
| routing changes occur. This patch just checks for NULL dst or dev |
| pointers when checking for netdev hardware assist features. |
| |
| BUG: unable to handle kernel NULL pointer dereference at 0000000c |
| IP: [<f89d074c>] pppol2tp_xmit+0x341/0x4da [pppol2tp] |
| *pde = 00000000 |
| Oops: 0000 [#1] SMP |
| last sysfs file: /sys/class/net/lo/operstate |
| Modules linked in: pppol2tp pppox ppp_generic slhc ipv6 dummy loop snd_hda_codec_atihdmi snd_hda_intel snd_hda_codec snd_pcm snd_timer snd soundcore snd_page_alloc evdev psmouse serio_raw processor button i2c_piix4 i2c_core ati_agp agpgart pcspkr ext3 jbd mbcache sd_mod ide_pci_generic atiixp ide_core ahci ata_generic floppy ehci_hcd ohci_hcd libata e1000e scsi_mod usbcore nls_base thermal fan thermal_sys [last unloaded: scsi_wait_scan] |
| |
| Pid: 0, comm: swapper Not tainted (2.6.32.8 #1) |
| EIP: 0060:[<f89d074c>] EFLAGS: 00010297 CPU: 3 |
| EIP is at pppol2tp_xmit+0x341/0x4da [pppol2tp] |
| EAX: 00000000 EBX: f64d1680 ECX: 000005b9 EDX: 00000000 |
| ESI: f6b91850 EDI: f64d16ac EBP: f6a0c4c0 ESP: f70a9cac |
| DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 |
| Process swapper (pid: 0, ti=f70a8000 task=f70a31c0 task.ti=f70a8000) |
| Stack: |
| 000005a9 000005b9 f734c400 f66652c0 f7352e00 f67dc800 00000000 f6b91800 |
| <0> 000005a3 f70ef6c4 f67dcda9 000005a3 f89b192e 00000246 000005a3 f64d1680 |
| <0> f63633e0 f6363320 f64d1680 f65a7320 f65a7364 f65856c0 f64d1680 f679f02f |
| Call Trace: |
| [<f89b192e>] ? ppp_push+0x459/0x50e [ppp_generic] |
| [<f89b217f>] ? ppp_xmit_process+0x3b6/0x430 [ppp_generic] |
| [<f89b2306>] ? ppp_start_xmit+0x10d/0x120 [ppp_generic] |
| [<c11c15cb>] ? dev_hard_start_xmit+0x21f/0x2b2 |
| [<c11d0947>] ? sch_direct_xmit+0x48/0x10e |
| [<c11c19a0>] ? dev_queue_xmit+0x263/0x3a6 |
| [<c11e2a9f>] ? ip_finish_output+0x1f7/0x221 |
| [<c11df682>] ? ip_forward_finish+0x2e/0x30 |
| [<c11de645>] ? ip_rcv_finish+0x295/0x2a9 |
| [<c11c0b19>] ? netif_receive_skb+0x3e9/0x404 |
| [<f814b791>] ? e1000_clean_rx_irq+0x253/0x2fc [e1000e] |
| [<f814cb7a>] ? e1000_clean+0x63/0x1fc [e1000e] |
| [<c1047eff>] ? sched_clock_local+0x15/0x11b |
| [<c11c1095>] ? net_rx_action+0x96/0x195 |
| [<c1035750>] ? __do_softirq+0xaa/0x151 |
| [<c1035828>] ? do_softirq+0x31/0x3c |
| [<c10358fe>] ? irq_exit+0x26/0x58 |
| [<c1004b21>] ? do_IRQ+0x78/0x89 |
| [<c1003729>] ? common_interrupt+0x29/0x30 |
| [<c101ac28>] ? native_safe_halt+0x2/0x3 |
| [<c1008c54>] ? default_idle+0x55/0x75 |
| [<c1009045>] ? c1e_idle+0xd2/0xd5 |
| [<c100233c>] ? cpu_idle+0x46/0x62 |
| Code: 8d 45 08 f0 ff 45 08 89 6b 08 c7 43 68 7e fb 9c f8 8a 45 24 83 e0 0c 3c 04 75 09 80 63 64 f3 e9 b4 00 00 00 8b 43 18 8b 4c 24 04 <8b> 40 0c 8d 79 11 f6 40 44 0e 8a 43 64 75 51 6a 00 8b 4c 24 08 |
| EIP: [<f89d074c>] pppol2tp_xmit+0x341/0x4da [pppol2tp] SS:ESP 0068:f70a9cac |
| CR2: 000000000000000c |
| |
| Signed-off-by: James Chapman <jchapman@katalix.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/net/pppol2tp.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/net/pppol2tp.c |
| +++ b/drivers/net/pppol2tp.c |
| @@ -1178,7 +1178,8 @@ static int pppol2tp_xmit(struct ppp_chan |
| /* Calculate UDP checksum if configured to do so */ |
| if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT) |
| skb->ip_summed = CHECKSUM_NONE; |
| - else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { |
| + else if ((skb_dst(skb) && skb_dst(skb)->dev) && |
| + (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) { |
| skb->ip_summed = CHECKSUM_COMPLETE; |
| csum = skb_checksum(skb, 0, udp_len, 0); |
| uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr, |