]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.33/l2tp-fix-races-with-ipv4-mapped-ipv6-addresses.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.33 / l2tp-fix-races-with-ipv4-mapped-ipv6-addresses.patch
1 From b954f94023dcc61388c8384f0f14eb8e42c863c5 Mon Sep 17 00:00:00 2001
2 From: Paolo Abeni <pabeni@redhat.com>
3 Date: Mon, 12 Mar 2018 14:54:24 +0100
4 Subject: l2tp: fix races with ipv4-mapped ipv6 addresses
5
6 From: Paolo Abeni <pabeni@redhat.com>
7
8 commit b954f94023dcc61388c8384f0f14eb8e42c863c5 upstream.
9
10 The l2tp_tunnel_create() function checks for v4mapped ipv6
11 sockets and cache that flag, so that l2tp core code can
12 reusing it at xmit time.
13
14 If the socket is provided by the userspace, the connection
15 status of the tunnel sockets can change between the tunnel
16 creation and the xmit call, so that syzbot is able to
17 trigger the following splat:
18
19 BUG: KASAN: use-after-free in ip6_dst_idev include/net/ip6_fib.h:192
20 [inline]
21 BUG: KASAN: use-after-free in ip6_xmit+0x1f76/0x2260
22 net/ipv6/ip6_output.c:264
23 Read of size 8 at addr ffff8801bd949318 by task syz-executor4/23448
24
25 CPU: 0 PID: 23448 Comm: syz-executor4 Not tainted 4.16.0-rc4+ #65
26 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
27 Google 01/01/2011
28 Call Trace:
29 __dump_stack lib/dump_stack.c:17 [inline]
30 dump_stack+0x194/0x24d lib/dump_stack.c:53
31 print_address_description+0x73/0x250 mm/kasan/report.c:256
32 kasan_report_error mm/kasan/report.c:354 [inline]
33 kasan_report+0x23c/0x360 mm/kasan/report.c:412
34 __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433
35 ip6_dst_idev include/net/ip6_fib.h:192 [inline]
36 ip6_xmit+0x1f76/0x2260 net/ipv6/ip6_output.c:264
37 inet6_csk_xmit+0x2fc/0x580 net/ipv6/inet6_connection_sock.c:139
38 l2tp_xmit_core net/l2tp/l2tp_core.c:1053 [inline]
39 l2tp_xmit_skb+0x105f/0x1410 net/l2tp/l2tp_core.c:1148
40 pppol2tp_sendmsg+0x470/0x670 net/l2tp/l2tp_ppp.c:341
41 sock_sendmsg_nosec net/socket.c:630 [inline]
42 sock_sendmsg+0xca/0x110 net/socket.c:640
43 ___sys_sendmsg+0x767/0x8b0 net/socket.c:2046
44 __sys_sendmsg+0xe5/0x210 net/socket.c:2080
45 SYSC_sendmsg net/socket.c:2091 [inline]
46 SyS_sendmsg+0x2d/0x50 net/socket.c:2087
47 do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
48 entry_SYSCALL_64_after_hwframe+0x42/0xb7
49 RIP: 0033:0x453e69
50 RSP: 002b:00007f819593cc68 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
51 RAX: ffffffffffffffda RBX: 00007f819593d6d4 RCX: 0000000000453e69
52 RDX: 0000000000000081 RSI: 000000002037ffc8 RDI: 0000000000000004
53 RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000
54 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff
55 R13: 00000000000004c3 R14: 00000000006f72e8 R15: 0000000000000000
56
57 This change addresses the issues:
58 * explicitly checking for TCP_ESTABLISHED for user space provided sockets
59 * dropping the v4mapped flag usage - it can become outdated - and
60 explicitly invoking ipv6_addr_v4mapped() instead
61
62 The issue is apparently there since ancient times.
63
64 v1 -> v2: (many thanks to Guillaume)
65 - with csum issue introduced in v1
66 - replace pr_err with pr_debug
67 - fix build issue with IPV6 disabled
68 - move l2tp_sk_is_v4mapped in l2tp_core.c
69
70 v2 -> v3:
71 - don't update inet_daddr for v4mapped address, unneeded
72 - drop rendundant check at creation time
73
74 Reported-and-tested-by: syzbot+92fa328176eb07e4ac1a@syzkaller.appspotmail.com
75 Fixes: 3557baabf280 ("[L2TP]: PPP over L2TP driver core")
76 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
77 Signed-off-by: David S. Miller <davem@davemloft.net>
78 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
79
80 ---
81 net/l2tp/l2tp_core.c | 38 ++++++++++++++++++--------------------
82 net/l2tp/l2tp_core.h | 3 ---
83 2 files changed, 18 insertions(+), 23 deletions(-)
84
85 --- a/net/l2tp/l2tp_core.c
86 +++ b/net/l2tp/l2tp_core.c
87 @@ -113,6 +113,13 @@ struct l2tp_net {
88 spinlock_t l2tp_session_hlist_lock;
89 };
90
91 +#if IS_ENABLED(CONFIG_IPV6)
92 +static bool l2tp_sk_is_v6(struct sock *sk)
93 +{
94 + return sk->sk_family == PF_INET6 &&
95 + !ipv6_addr_v4mapped(&sk->sk_v6_daddr);
96 +}
97 +#endif
98
99 static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk)
100 {
101 @@ -1130,7 +1137,7 @@ static int l2tp_xmit_core(struct l2tp_se
102 /* Queue the packet to IP for output */
103 skb->ignore_df = 1;
104 #if IS_ENABLED(CONFIG_IPV6)
105 - if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped)
106 + if (l2tp_sk_is_v6(tunnel->sock))
107 error = inet6_csk_xmit(tunnel->sock, skb, NULL);
108 else
109 #endif
110 @@ -1193,6 +1200,15 @@ int l2tp_xmit_skb(struct l2tp_session *s
111 goto out_unlock;
112 }
113
114 + /* The user-space may change the connection status for the user-space
115 + * provided socket at run time: we must check it under the socket lock
116 + */
117 + if (tunnel->fd >= 0 && sk->sk_state != TCP_ESTABLISHED) {
118 + kfree_skb(skb);
119 + ret = NET_XMIT_DROP;
120 + goto out_unlock;
121 + }
122 +
123 /* Get routing info from the tunnel socket */
124 skb_dst_drop(skb);
125 skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0)));
126 @@ -1212,7 +1228,7 @@ int l2tp_xmit_skb(struct l2tp_session *s
127
128 /* Calculate UDP checksum if configured to do so */
129 #if IS_ENABLED(CONFIG_IPV6)
130 - if (sk->sk_family == PF_INET6 && !tunnel->v4mapped)
131 + if (l2tp_sk_is_v6(sk))
132 udp6_set_csum(udp_get_no_check6_tx(sk),
133 skb, &inet6_sk(sk)->saddr,
134 &sk->sk_v6_daddr, udp_len);
135 @@ -1616,24 +1632,6 @@ int l2tp_tunnel_create(struct net *net,
136 if (cfg != NULL)
137 tunnel->debug = cfg->debug;
138
139 -#if IS_ENABLED(CONFIG_IPV6)
140 - if (sk->sk_family == PF_INET6) {
141 - struct ipv6_pinfo *np = inet6_sk(sk);
142 -
143 - if (ipv6_addr_v4mapped(&np->saddr) &&
144 - ipv6_addr_v4mapped(&sk->sk_v6_daddr)) {
145 - struct inet_sock *inet = inet_sk(sk);
146 -
147 - tunnel->v4mapped = true;
148 - inet->inet_saddr = np->saddr.s6_addr32[3];
149 - inet->inet_rcv_saddr = sk->sk_v6_rcv_saddr.s6_addr32[3];
150 - inet->inet_daddr = sk->sk_v6_daddr.s6_addr32[3];
151 - } else {
152 - tunnel->v4mapped = false;
153 - }
154 - }
155 -#endif
156 -
157 /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
158 tunnel->encap = encap;
159 if (encap == L2TP_ENCAPTYPE_UDP) {
160 --- a/net/l2tp/l2tp_core.h
161 +++ b/net/l2tp/l2tp_core.h
162 @@ -195,9 +195,6 @@ struct l2tp_tunnel {
163 struct sock *sock; /* Parent socket */
164 int fd; /* Parent fd, if tunnel socket
165 * was created by userspace */
166 -#if IS_ENABLED(CONFIG_IPV6)
167 - bool v4mapped;
168 -#endif
169
170 struct work_struct del_work;
171