aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-11-30 14:14:09 -0500
committerDavid S. Miller <davem@davemloft.net>2016-11-30 14:14:09 -0500
commit7752f72748db3ce9312e2171f80cbbb42bf4dde6 (patch)
tree9546bf8fd1837769d8ff63d13acac5a1f57e5a9a
parentbb83d62fa83405d7c325873a317c9374f98eedef (diff)
parent31e2f21fb35bfaa5bdbe1a4860dc99e6b10d8dcd (diff)
Merge branch 'l2tp-fixes'
Guillaume Nault says: ==================== l2tp: fixes for l2tp_ip and l2tp_ip6 socket handling This series addresses problems found while working on commit 32c231164b76 ("l2tp: fix racy SOCK_ZAPPED flag check in l2tp_ip{,6}_bind()"). The first three patches fix races in socket's connect, recv and bind operations. The last two ones fix scenarios where l2tp fails to correctly lookup its userspace sockets. Apart from the last patch, which is l2tp_ip6 specific, every patch fixes the same problem in the L2TP IPv4 and IPv6 code. All problems fixed by this series exist since the creation of the l2tp_ip and l2tp_ip6 modules. Changes since v1: * Patch #3: fix possible uninitialised use of 'ret' in l2tp_ip_bind(). ==================== Acked-by: James Chapman <jchapman@katalix.com>
-rw-r--r--include/net/ipv6.h2
-rw-r--r--net/ipv6/datagram.c4
-rw-r--r--net/l2tp/l2tp_ip.c63
-rw-r--r--net/l2tp/l2tp_ip6.c79
4 files changed, 81 insertions, 67 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8fed1cd78658..f11ca837361b 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -970,6 +970,8 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
970int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, 970int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
971 char __user *optval, int __user *optlen); 971 char __user *optval, int __user *optlen);
972 972
973int __ip6_datagram_connect(struct sock *sk, struct sockaddr *addr,
974 int addr_len);
973int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); 975int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len);
974int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr, 976int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr,
975 int addr_len); 977 int addr_len);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 37874e2f30ed..ccf40550c475 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -139,7 +139,8 @@ void ip6_datagram_release_cb(struct sock *sk)
139} 139}
140EXPORT_SYMBOL_GPL(ip6_datagram_release_cb); 140EXPORT_SYMBOL_GPL(ip6_datagram_release_cb);
141 141
142static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) 142int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,
143 int addr_len)
143{ 144{
144 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; 145 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
145 struct inet_sock *inet = inet_sk(sk); 146 struct inet_sock *inet = inet_sk(sk);
@@ -252,6 +253,7 @@ ipv4_connected:
252out: 253out:
253 return err; 254 return err;
254} 255}
256EXPORT_SYMBOL_GPL(__ip6_datagram_connect);
255 257
256int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) 258int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
257{ 259{
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 982f6c44ea01..8938b6ba57a0 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -61,7 +61,8 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif
61 if ((l2tp->conn_id == tunnel_id) && 61 if ((l2tp->conn_id == tunnel_id) &&
62 net_eq(sock_net(sk), net) && 62 net_eq(sock_net(sk), net) &&
63 !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && 63 !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
64 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) 64 (!sk->sk_bound_dev_if || !dif ||
65 sk->sk_bound_dev_if == dif))
65 goto found; 66 goto found;
66 } 67 }
67 68
@@ -182,15 +183,17 @@ pass_up:
182 struct iphdr *iph = (struct iphdr *) skb_network_header(skb); 183 struct iphdr *iph = (struct iphdr *) skb_network_header(skb);
183 184
184 read_lock_bh(&l2tp_ip_lock); 185 read_lock_bh(&l2tp_ip_lock);
185 sk = __l2tp_ip_bind_lookup(net, iph->daddr, 0, tunnel_id); 186 sk = __l2tp_ip_bind_lookup(net, iph->daddr, inet_iif(skb),
187 tunnel_id);
188 if (!sk) {
189 read_unlock_bh(&l2tp_ip_lock);
190 goto discard;
191 }
192
193 sock_hold(sk);
186 read_unlock_bh(&l2tp_ip_lock); 194 read_unlock_bh(&l2tp_ip_lock);
187 } 195 }
188 196
189 if (sk == NULL)
190 goto discard;
191
192 sock_hold(sk);
193
194 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) 197 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
195 goto discard_put; 198 goto discard_put;
196 199
@@ -256,15 +259,9 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
256 if (addr->l2tp_family != AF_INET) 259 if (addr->l2tp_family != AF_INET)
257 return -EINVAL; 260 return -EINVAL;
258 261
259 ret = -EADDRINUSE;
260 read_lock_bh(&l2tp_ip_lock);
261 if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
262 sk->sk_bound_dev_if, addr->l2tp_conn_id))
263 goto out_in_use;
264
265 read_unlock_bh(&l2tp_ip_lock);
266
267 lock_sock(sk); 262 lock_sock(sk);
263
264 ret = -EINVAL;
268 if (!sock_flag(sk, SOCK_ZAPPED)) 265 if (!sock_flag(sk, SOCK_ZAPPED))
269 goto out; 266 goto out;
270 267
@@ -281,14 +278,22 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
281 inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr; 278 inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr;
282 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) 279 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
283 inet->inet_saddr = 0; /* Use device */ 280 inet->inet_saddr = 0; /* Use device */
284 sk_dst_reset(sk);
285 281
282 write_lock_bh(&l2tp_ip_lock);
283 if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
284 sk->sk_bound_dev_if, addr->l2tp_conn_id)) {
285 write_unlock_bh(&l2tp_ip_lock);
286 ret = -EADDRINUSE;
287 goto out;
288 }
289
290 sk_dst_reset(sk);
286 l2tp_ip_sk(sk)->conn_id = addr->l2tp_conn_id; 291 l2tp_ip_sk(sk)->conn_id = addr->l2tp_conn_id;
287 292
288 write_lock_bh(&l2tp_ip_lock);
289 sk_add_bind_node(sk, &l2tp_ip_bind_table); 293 sk_add_bind_node(sk, &l2tp_ip_bind_table);
290 sk_del_node_init(sk); 294 sk_del_node_init(sk);
291 write_unlock_bh(&l2tp_ip_lock); 295 write_unlock_bh(&l2tp_ip_lock);
296
292 ret = 0; 297 ret = 0;
293 sock_reset_flag(sk, SOCK_ZAPPED); 298 sock_reset_flag(sk, SOCK_ZAPPED);
294 299
@@ -296,11 +301,6 @@ out:
296 release_sock(sk); 301 release_sock(sk);
297 302
298 return ret; 303 return ret;
299
300out_in_use:
301 read_unlock_bh(&l2tp_ip_lock);
302
303 return ret;
304} 304}
305 305
306static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) 306static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -308,21 +308,24 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
308 struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr; 308 struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr;
309 int rc; 309 int rc;
310 310
311 if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
312 return -EINVAL;
313
314 if (addr_len < sizeof(*lsa)) 311 if (addr_len < sizeof(*lsa))
315 return -EINVAL; 312 return -EINVAL;
316 313
317 if (ipv4_is_multicast(lsa->l2tp_addr.s_addr)) 314 if (ipv4_is_multicast(lsa->l2tp_addr.s_addr))
318 return -EINVAL; 315 return -EINVAL;
319 316
320 rc = ip4_datagram_connect(sk, uaddr, addr_len);
321 if (rc < 0)
322 return rc;
323
324 lock_sock(sk); 317 lock_sock(sk);
325 318
319 /* Must bind first - autobinding does not work */
320 if (sock_flag(sk, SOCK_ZAPPED)) {
321 rc = -EINVAL;
322 goto out_sk;
323 }
324
325 rc = __ip4_datagram_connect(sk, uaddr, addr_len);
326 if (rc < 0)
327 goto out_sk;
328
326 l2tp_ip_sk(sk)->peer_conn_id = lsa->l2tp_conn_id; 329 l2tp_ip_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
327 330
328 write_lock_bh(&l2tp_ip_lock); 331 write_lock_bh(&l2tp_ip_lock);
@@ -330,7 +333,9 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
330 sk_add_bind_node(sk, &l2tp_ip_bind_table); 333 sk_add_bind_node(sk, &l2tp_ip_bind_table);
331 write_unlock_bh(&l2tp_ip_lock); 334 write_unlock_bh(&l2tp_ip_lock);
332 335
336out_sk:
333 release_sock(sk); 337 release_sock(sk);
338
334 return rc; 339 return rc;
335} 340}
336 341
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 9978d01ba0ba..aa821cb639e5 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -72,8 +72,9 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
72 72
73 if ((l2tp->conn_id == tunnel_id) && 73 if ((l2tp->conn_id == tunnel_id) &&
74 net_eq(sock_net(sk), net) && 74 net_eq(sock_net(sk), net) &&
75 !(addr && ipv6_addr_equal(addr, laddr)) && 75 (!addr || ipv6_addr_equal(addr, laddr)) &&
76 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) 76 (!sk->sk_bound_dev_if || !dif ||
77 sk->sk_bound_dev_if == dif))
77 goto found; 78 goto found;
78 } 79 }
79 80
@@ -196,16 +197,17 @@ pass_up:
196 struct ipv6hdr *iph = ipv6_hdr(skb); 197 struct ipv6hdr *iph = ipv6_hdr(skb);
197 198
198 read_lock_bh(&l2tp_ip6_lock); 199 read_lock_bh(&l2tp_ip6_lock);
199 sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, 200 sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, inet6_iif(skb),
200 0, tunnel_id); 201 tunnel_id);
202 if (!sk) {
203 read_unlock_bh(&l2tp_ip6_lock);
204 goto discard;
205 }
206
207 sock_hold(sk);
201 read_unlock_bh(&l2tp_ip6_lock); 208 read_unlock_bh(&l2tp_ip6_lock);
202 } 209 }
203 210
204 if (sk == NULL)
205 goto discard;
206
207 sock_hold(sk);
208
209 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 211 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
210 goto discard_put; 212 goto discard_put;
211 213
@@ -266,6 +268,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
266 struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr; 268 struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr;
267 struct net *net = sock_net(sk); 269 struct net *net = sock_net(sk);
268 __be32 v4addr = 0; 270 __be32 v4addr = 0;
271 int bound_dev_if;
269 int addr_type; 272 int addr_type;
270 int err; 273 int err;
271 274
@@ -284,13 +287,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
284 if (addr_type & IPV6_ADDR_MULTICAST) 287 if (addr_type & IPV6_ADDR_MULTICAST)
285 return -EADDRNOTAVAIL; 288 return -EADDRNOTAVAIL;
286 289
287 err = -EADDRINUSE;
288 read_lock_bh(&l2tp_ip6_lock);
289 if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr,
290 sk->sk_bound_dev_if, addr->l2tp_conn_id))
291 goto out_in_use;
292 read_unlock_bh(&l2tp_ip6_lock);
293
294 lock_sock(sk); 290 lock_sock(sk);
295 291
296 err = -EINVAL; 292 err = -EINVAL;
@@ -300,28 +296,25 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
300 if (sk->sk_state != TCP_CLOSE) 296 if (sk->sk_state != TCP_CLOSE)
301 goto out_unlock; 297 goto out_unlock;
302 298
299 bound_dev_if = sk->sk_bound_dev_if;
300
303 /* Check if the address belongs to the host. */ 301 /* Check if the address belongs to the host. */
304 rcu_read_lock(); 302 rcu_read_lock();
305 if (addr_type != IPV6_ADDR_ANY) { 303 if (addr_type != IPV6_ADDR_ANY) {
306 struct net_device *dev = NULL; 304 struct net_device *dev = NULL;
307 305
308 if (addr_type & IPV6_ADDR_LINKLOCAL) { 306 if (addr_type & IPV6_ADDR_LINKLOCAL) {
309 if (addr_len >= sizeof(struct sockaddr_in6) && 307 if (addr->l2tp_scope_id)
310 addr->l2tp_scope_id) { 308 bound_dev_if = addr->l2tp_scope_id;
311 /* Override any existing binding, if another
312 * one is supplied by user.
313 */
314 sk->sk_bound_dev_if = addr->l2tp_scope_id;
315 }
316 309
317 /* Binding to link-local address requires an 310 /* Binding to link-local address requires an
318 interface */ 311 * interface.
319 if (!sk->sk_bound_dev_if) 312 */
313 if (!bound_dev_if)
320 goto out_unlock_rcu; 314 goto out_unlock_rcu;
321 315
322 err = -ENODEV; 316 err = -ENODEV;
323 dev = dev_get_by_index_rcu(sock_net(sk), 317 dev = dev_get_by_index_rcu(sock_net(sk), bound_dev_if);
324 sk->sk_bound_dev_if);
325 if (!dev) 318 if (!dev)
326 goto out_unlock_rcu; 319 goto out_unlock_rcu;
327 } 320 }
@@ -336,13 +329,22 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
336 } 329 }
337 rcu_read_unlock(); 330 rcu_read_unlock();
338 331
339 inet->inet_rcv_saddr = inet->inet_saddr = v4addr; 332 write_lock_bh(&l2tp_ip6_lock);
333 if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, bound_dev_if,
334 addr->l2tp_conn_id)) {
335 write_unlock_bh(&l2tp_ip6_lock);
336 err = -EADDRINUSE;
337 goto out_unlock;
338 }
339
340 inet->inet_saddr = v4addr;
341 inet->inet_rcv_saddr = v4addr;
342 sk->sk_bound_dev_if = bound_dev_if;
340 sk->sk_v6_rcv_saddr = addr->l2tp_addr; 343 sk->sk_v6_rcv_saddr = addr->l2tp_addr;
341 np->saddr = addr->l2tp_addr; 344 np->saddr = addr->l2tp_addr;
342 345
343 l2tp_ip6_sk(sk)->conn_id = addr->l2tp_conn_id; 346 l2tp_ip6_sk(sk)->conn_id = addr->l2tp_conn_id;
344 347
345 write_lock_bh(&l2tp_ip6_lock);
346 sk_add_bind_node(sk, &l2tp_ip6_bind_table); 348 sk_add_bind_node(sk, &l2tp_ip6_bind_table);
347 sk_del_node_init(sk); 349 sk_del_node_init(sk);
348 write_unlock_bh(&l2tp_ip6_lock); 350 write_unlock_bh(&l2tp_ip6_lock);
@@ -355,10 +357,7 @@ out_unlock_rcu:
355 rcu_read_unlock(); 357 rcu_read_unlock();
356out_unlock: 358out_unlock:
357 release_sock(sk); 359 release_sock(sk);
358 return err;
359 360
360out_in_use:
361 read_unlock_bh(&l2tp_ip6_lock);
362 return err; 361 return err;
363} 362}
364 363
@@ -371,9 +370,6 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr,
371 int addr_type; 370 int addr_type;
372 int rc; 371 int rc;
373 372
374 if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
375 return -EINVAL;
376
377 if (addr_len < sizeof(*lsa)) 373 if (addr_len < sizeof(*lsa))
378 return -EINVAL; 374 return -EINVAL;
379 375
@@ -390,10 +386,18 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr,
390 return -EINVAL; 386 return -EINVAL;
391 } 387 }
392 388
393 rc = ip6_datagram_connect(sk, uaddr, addr_len);
394
395 lock_sock(sk); 389 lock_sock(sk);
396 390
391 /* Must bind first - autobinding does not work */
392 if (sock_flag(sk, SOCK_ZAPPED)) {
393 rc = -EINVAL;
394 goto out_sk;
395 }
396
397 rc = __ip6_datagram_connect(sk, uaddr, addr_len);
398 if (rc < 0)
399 goto out_sk;
400
397 l2tp_ip6_sk(sk)->peer_conn_id = lsa->l2tp_conn_id; 401 l2tp_ip6_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
398 402
399 write_lock_bh(&l2tp_ip6_lock); 403 write_lock_bh(&l2tp_ip6_lock);
@@ -401,6 +405,7 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr,
401 sk_add_bind_node(sk, &l2tp_ip6_bind_table); 405 sk_add_bind_node(sk, &l2tp_ip6_bind_table);
402 write_unlock_bh(&l2tp_ip6_lock); 406 write_unlock_bh(&l2tp_ip6_lock);
403 407
408out_sk:
404 release_sock(sk); 409 release_sock(sk);
405 410
406 return rc; 411 return rc;