[PATCH 3.8 14/91] l2tp: fix kernel panic when using IPv4-mapped IPv6 addresses
3.8.13.13 -stable review patch. If anyone has any objections, please let me know. -- From: =?UTF-8?q?Fran=C3=A7ois=20Cachereul?= [ Upstream commit e18503f41f9b12132c95d7c31ca6ee5155e44e5c ] IPv4 mapped addresses cause kernel panic. The patch juste check whether the IPv6 address is an IPv4 mapped address. If so, use IPv4 API instead of IPv6. [ 940.026915] general protection fault: [#1] [ 940.026915] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core pppox ppp_generic slhc loop psmouse [ 940.026915] CPU: 0 PID: 3184 Comm: memcheck-amd64- Not tainted 3.11.0+ #1 [ 940.026915] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 [ 940.026915] task: 880007130e20 ti: 88000737e000 task.ti: 88000737e000 [ 940.026915] RIP: 0010:[] [] ip6_xmit+0x276/0x326 [ 940.026915] RSP: 0018:88000737fd28 EFLAGS: 00010286 [ 940.026915] RAX: c748521a75ceff48 RBX: 88c30800 RCX: [ 940.026915] RDX: 8875cc4e RSI: 0028 RDI: 8800060e5a40 [ 940.026915] RBP: 8800060e5a40 R08: R09: 8875cc90 [ 940.026915] R10: R11: R12: 88000737fda0 [ 940.026915] R13: R14: 2000 R15: 880005d3b580 [ 940.026915] FS: 7f163dc5e800() GS:81623000() knlGS: [ 940.026915] CS: 0010 DS: ES: CR0: 80050033 [ 940.026915] CR2: 0004032dc940 CR3: 05c25000 CR4: 06f0 [ 940.026915] Stack: [ 940.026915] 8875cc4e 81694e90 88c30b38 0020 [ 940.026915] 1100523c4bac 88000737fdb4 88c30800 [ 940.026915] 880005d3b580 88c30b38 8800060e5a40 0020 [ 940.026915] Call Trace: [ 940.026915] [] ? inet6_csk_xmit+0xa4/0xc4 [ 940.026915] [] ? l2tp_xmit_skb+0x503/0x55a [l2tp_core] [ 940.026915] [] ? pskb_expand_head+0x161/0x214 [ 940.026915] [] ? pppol2tp_xmit+0xf2/0x143 [l2tp_ppp] [ 940.026915] [] ? ppp_channel_push+0x36/0x8b [ppp_generic] [ 940.026915] [] ? ppp_write+0xaf/0xc5 [ppp_generic] [ 940.026915] [] ? vfs_write+0xa2/0x106 [ 940.026915] [] ? SyS_write+0x56/0x8a [ 940.026915] [] ? system_call_fastpath+0x16/0x1b [ 940.026915] Code: 00 49 8b 8f d8 00 00 00 66 83 7c 11 02 00 74 60 49 8b 47 58 48 83 e0 fe 48 8b 80 18 01 00 00 48 85 c0 74 13 48 8b 80 78 02 00 00 <48> ff 40 28 41 8b 57 68 48 01 50 30 48 8b 54 24 08 49 c7 c1 51 [ 940.026915] RIP [] ip6_xmit+0x276/0x326 [ 940.026915] RSP [ 940.057945] ---[ end trace be8aba9a61c8b7f3 ]--- [ 940.058583] Kernel panic - not syncing: Fatal exception in interrupt Signed-off-by: François CACHEREUL Signed-off-by: David S. Miller Signed-off-by: Kamal Mostafa --- net/l2tp/l2tp_core.c | 27 +++ net/l2tp/l2tp_core.h | 3 +++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 2ac884d..8861e9f 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -517,6 +517,7 @@ out: static inline int l2tp_verify_udp_checksum(struct sock *sk, struct sk_buff *skb) { + struct l2tp_tunnel *tunnel = (struct l2tp_tunnel *)sk->sk_user_data; struct udphdr *uh = udp_hdr(skb); u16 ulen = ntohs(uh->len); __wsum psum; @@ -525,7 +526,7 @@ static inline int l2tp_verify_udp_checksum(struct sock *sk, return 0; #if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family == PF_INET6) { + if (sk->sk_family == PF_INET6 && !tunnel->v4mapped) { if (!uh->check) { LIMIT_NETDEBUG(KERN_INFO "L2TP: IPv6: checksum is 0\n"); return 1; @@ -1088,7 +1089,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, /* Queue the packet to IP for output */ skb->local_df = 1; #if IS_ENABLED(CONFIG_IPV6) - if (skb->sk->sk_family == PF_INET6) + if (skb->sk->sk_family == PF_INET6 && !tunnel->v4mapped) error = inet6_csk_xmit(skb, NULL); else #endif @@ -1221,7 +1222,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len /* Calculate UDP checksum if configured to do so */ #if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family == PF_INET6) + if (sk->sk_family == PF_INET6 && !tunnel->v4mapped) l2tp_xmit_ipv6_csum(sk, skb, udp_len); else #endif @@ -1624,6 +1625,24 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 if (cfg != NULL) tunnel->debug = cfg->debug; +#if IS_ENABLED(CONFIG_IPV6) + if (sk->sk_family == PF_INET6) { + struct ipv6_pinfo *np = inet6_sk(sk); + + if (ipv6_addr_v4mapped(>saddr) && + ipv6_addr_v4mapped(>daddr)) { +
[PATCH 3.8 14/91] l2tp: fix kernel panic when using IPv4-mapped IPv6 addresses
3.8.13.13 -stable review patch. If anyone has any objections, please let me know. -- From: =?UTF-8?q?Fran=C3=A7ois=20Cachereul?= f.cacher...@alphalink.fr [ Upstream commit e18503f41f9b12132c95d7c31ca6ee5155e44e5c ] IPv4 mapped addresses cause kernel panic. The patch juste check whether the IPv6 address is an IPv4 mapped address. If so, use IPv4 API instead of IPv6. [ 940.026915] general protection fault: [#1] [ 940.026915] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core pppox ppp_generic slhc loop psmouse [ 940.026915] CPU: 0 PID: 3184 Comm: memcheck-amd64- Not tainted 3.11.0+ #1 [ 940.026915] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 [ 940.026915] task: 880007130e20 ti: 88000737e000 task.ti: 88000737e000 [ 940.026915] RIP: 0010:[81333780] [81333780] ip6_xmit+0x276/0x326 [ 940.026915] RSP: 0018:88000737fd28 EFLAGS: 00010286 [ 940.026915] RAX: c748521a75ceff48 RBX: 88c30800 RCX: [ 940.026915] RDX: 8875cc4e RSI: 0028 RDI: 8800060e5a40 [ 940.026915] RBP: 8800060e5a40 R08: R09: 8875cc90 [ 940.026915] R10: R11: R12: 88000737fda0 [ 940.026915] R13: R14: 2000 R15: 880005d3b580 [ 940.026915] FS: 7f163dc5e800() GS:81623000() knlGS: [ 940.026915] CS: 0010 DS: ES: CR0: 80050033 [ 940.026915] CR2: 0004032dc940 CR3: 05c25000 CR4: 06f0 [ 940.026915] Stack: [ 940.026915] 8875cc4e 81694e90 88c30b38 0020 [ 940.026915] 1100523c4bac 88000737fdb4 88c30800 [ 940.026915] 880005d3b580 88c30b38 8800060e5a40 0020 [ 940.026915] Call Trace: [ 940.026915] [81356cc3] ? inet6_csk_xmit+0xa4/0xc4 [ 940.026915] [a0038535] ? l2tp_xmit_skb+0x503/0x55a [l2tp_core] [ 940.026915] [812b8d3b] ? pskb_expand_head+0x161/0x214 [ 940.026915] [a003e91d] ? pppol2tp_xmit+0xf2/0x143 [l2tp_ppp] [ 940.026915] [a00292e0] ? ppp_channel_push+0x36/0x8b [ppp_generic] [ 940.026915] [a00293fe] ? ppp_write+0xaf/0xc5 [ppp_generic] [ 940.026915] [8110ead4] ? vfs_write+0xa2/0x106 [ 940.026915] [8110edd6] ? SyS_write+0x56/0x8a [ 940.026915] [81378ac0] ? system_call_fastpath+0x16/0x1b [ 940.026915] Code: 00 49 8b 8f d8 00 00 00 66 83 7c 11 02 00 74 60 49 8b 47 58 48 83 e0 fe 48 8b 80 18 01 00 00 48 85 c0 74 13 48 8b 80 78 02 00 00 48 ff 40 28 41 8b 57 68 48 01 50 30 48 8b 54 24 08 49 c7 c1 51 [ 940.026915] RIP [81333780] ip6_xmit+0x276/0x326 [ 940.026915] RSP 88000737fd28 [ 940.057945] ---[ end trace be8aba9a61c8b7f3 ]--- [ 940.058583] Kernel panic - not syncing: Fatal exception in interrupt Signed-off-by: François CACHEREUL f.cacher...@alphalink.fr Signed-off-by: David S. Miller da...@davemloft.net Signed-off-by: Kamal Mostafa ka...@canonical.com --- net/l2tp/l2tp_core.c | 27 +++ net/l2tp/l2tp_core.h | 3 +++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 2ac884d..8861e9f 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -517,6 +517,7 @@ out: static inline int l2tp_verify_udp_checksum(struct sock *sk, struct sk_buff *skb) { + struct l2tp_tunnel *tunnel = (struct l2tp_tunnel *)sk-sk_user_data; struct udphdr *uh = udp_hdr(skb); u16 ulen = ntohs(uh-len); __wsum psum; @@ -525,7 +526,7 @@ static inline int l2tp_verify_udp_checksum(struct sock *sk, return 0; #if IS_ENABLED(CONFIG_IPV6) - if (sk-sk_family == PF_INET6) { + if (sk-sk_family == PF_INET6 !tunnel-v4mapped) { if (!uh-check) { LIMIT_NETDEBUG(KERN_INFO L2TP: IPv6: checksum is 0\n); return 1; @@ -1088,7 +1089,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, /* Queue the packet to IP for output */ skb-local_df = 1; #if IS_ENABLED(CONFIG_IPV6) - if (skb-sk-sk_family == PF_INET6) + if (skb-sk-sk_family == PF_INET6 !tunnel-v4mapped) error = inet6_csk_xmit(skb, NULL); else #endif @@ -1221,7 +1222,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len /* Calculate UDP checksum if configured to do so */ #if IS_ENABLED(CONFIG_IPV6) - if (sk-sk_family == PF_INET6) + if (sk-sk_family == PF_INET6 !tunnel-v4mapped) l2tp_xmit_ipv6_csum(sk, skb, udp_len); else #endif @@ -1624,6 +1625,24 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 if (cfg != NULL) tunnel-debug