[PATCH 3.8 14/91] l2tp: fix kernel panic when using IPv4-mapped IPv6 addresses

2013-11-07 Thread Kamal Mostafa
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

2013-11-07 Thread Kamal Mostafa
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