diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/sco.c | 6 | ||||
-rw-r--r-- | net/ceph/Makefile | 22 | ||||
-rw-r--r-- | net/ceph/buffer.c | 2 | ||||
-rw-r--r-- | net/core/filter.c | 19 | ||||
-rw-r--r-- | net/core/request_sock.c | 4 | ||||
-rw-r--r-- | net/dccp/input.c | 3 | ||||
-rw-r--r-- | net/decnet/af_decnet.c | 2 | ||||
-rw-r--r-- | net/econet/af_econet.c | 93 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 2 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 3 | ||||
-rw-r--r-- | net/ipv4/proc.c | 1 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 6 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 42 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 7 | ||||
-rw-r--r-- | net/ipv6/sit.c | 3 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip.c | 6 | ||||
-rw-r--r-- | net/mac80211/rx.c | 6 | ||||
-rw-r--r-- | net/mac80211/tx.c | 7 | ||||
-rw-r--r-- | net/unix/af_unix.c | 37 | ||||
-rw-r--r-- | net/unix/garbage.c | 9 | ||||
-rw-r--r-- | net/x25/x25_link.c | 1 | ||||
-rw-r--r-- | net/xfrm/xfrm_hash.c | 2 |
25 files changed, 163 insertions, 128 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index d0927d1fdada..66b9e5c0523a 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -882,7 +882,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | |||
882 | int lm = 0; | 882 | int lm = 0; |
883 | 883 | ||
884 | if (type != SCO_LINK && type != ESCO_LINK) | 884 | if (type != SCO_LINK && type != ESCO_LINK) |
885 | return 0; | 885 | return -EINVAL; |
886 | 886 | ||
887 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 887 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
888 | 888 | ||
@@ -908,7 +908,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) | |||
908 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 908 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
909 | 909 | ||
910 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | 910 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) |
911 | return 0; | 911 | return -EINVAL; |
912 | 912 | ||
913 | if (!status) { | 913 | if (!status) { |
914 | struct sco_conn *conn; | 914 | struct sco_conn *conn; |
@@ -927,7 +927,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) | |||
927 | BT_DBG("hcon %p reason %d", hcon, reason); | 927 | BT_DBG("hcon %p reason %d", hcon, reason); |
928 | 928 | ||
929 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | 929 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) |
930 | return 0; | 930 | return -EINVAL; |
931 | 931 | ||
932 | sco_conn_del(hcon, bt_err(reason)); | 932 | sco_conn_del(hcon, bt_err(reason)); |
933 | 933 | ||
diff --git a/net/ceph/Makefile b/net/ceph/Makefile index 153bdec40835..e87ef435e11b 100644 --- a/net/ceph/Makefile +++ b/net/ceph/Makefile | |||
@@ -1,9 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Makefile for CEPH filesystem. | 2 | # Makefile for CEPH filesystem. |
3 | # | 3 | # |
4 | |||
5 | ifneq ($(KERNELRELEASE),) | ||
6 | |||
7 | obj-$(CONFIG_CEPH_LIB) += libceph.o | 4 | obj-$(CONFIG_CEPH_LIB) += libceph.o |
8 | 5 | ||
9 | libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ | 6 | libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ |
@@ -16,22 +13,3 @@ libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ | |||
16 | ceph_fs.o ceph_strings.o ceph_hash.o \ | 13 | ceph_fs.o ceph_strings.o ceph_hash.o \ |
17 | pagevec.o | 14 | pagevec.o |
18 | 15 | ||
19 | else | ||
20 | #Otherwise we were called directly from the command | ||
21 | # line; invoke the kernel build system. | ||
22 | |||
23 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build | ||
24 | PWD := $(shell pwd) | ||
25 | |||
26 | default: all | ||
27 | |||
28 | all: | ||
29 | $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules | ||
30 | |||
31 | modules_install: | ||
32 | $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules_install | ||
33 | |||
34 | clean: | ||
35 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean | ||
36 | |||
37 | endif | ||
diff --git a/net/ceph/buffer.c b/net/ceph/buffer.c index 53d8abfa25d5..bf3e6a13c215 100644 --- a/net/ceph/buffer.c +++ b/net/ceph/buffer.c | |||
@@ -19,7 +19,7 @@ struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) | |||
19 | if (b->vec.iov_base) { | 19 | if (b->vec.iov_base) { |
20 | b->is_vmalloc = false; | 20 | b->is_vmalloc = false; |
21 | } else { | 21 | } else { |
22 | b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL); | 22 | b->vec.iov_base = __vmalloc(len, gfp | __GFP_HIGHMEM, PAGE_KERNEL); |
23 | if (!b->vec.iov_base) { | 23 | if (!b->vec.iov_base) { |
24 | kfree(b); | 24 | kfree(b); |
25 | return NULL; | 25 | return NULL; |
diff --git a/net/core/filter.c b/net/core/filter.c index 25500f16a18a..e193e29d4671 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -615,23 +615,16 @@ int sk_chk_filter(struct sock_filter *filter, int flen) | |||
615 | EXPORT_SYMBOL(sk_chk_filter); | 615 | EXPORT_SYMBOL(sk_chk_filter); |
616 | 616 | ||
617 | /** | 617 | /** |
618 | * sk_filter_rcu_release - Release a socket filter by rcu_head | 618 | * sk_filter_release_rcu - Release a socket filter by rcu_head |
619 | * @rcu: rcu_head that contains the sk_filter to free | 619 | * @rcu: rcu_head that contains the sk_filter to free |
620 | */ | 620 | */ |
621 | static void sk_filter_rcu_release(struct rcu_head *rcu) | 621 | void sk_filter_release_rcu(struct rcu_head *rcu) |
622 | { | 622 | { |
623 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); | 623 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); |
624 | 624 | ||
625 | sk_filter_release(fp); | 625 | kfree(fp); |
626 | } | ||
627 | |||
628 | static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp) | ||
629 | { | ||
630 | unsigned int size = sk_filter_len(fp); | ||
631 | |||
632 | atomic_sub(size, &sk->sk_omem_alloc); | ||
633 | call_rcu_bh(&fp->rcu, sk_filter_rcu_release); | ||
634 | } | 626 | } |
627 | EXPORT_SYMBOL(sk_filter_release_rcu); | ||
635 | 628 | ||
636 | /** | 629 | /** |
637 | * sk_attach_filter - attach a socket filter | 630 | * sk_attach_filter - attach a socket filter |
@@ -675,7 +668,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
675 | rcu_assign_pointer(sk->sk_filter, fp); | 668 | rcu_assign_pointer(sk->sk_filter, fp); |
676 | 669 | ||
677 | if (old_fp) | 670 | if (old_fp) |
678 | sk_filter_delayed_uncharge(sk, old_fp); | 671 | sk_filter_uncharge(sk, old_fp); |
679 | return 0; | 672 | return 0; |
680 | } | 673 | } |
681 | EXPORT_SYMBOL_GPL(sk_attach_filter); | 674 | EXPORT_SYMBOL_GPL(sk_attach_filter); |
@@ -689,7 +682,7 @@ int sk_detach_filter(struct sock *sk) | |||
689 | sock_owned_by_user(sk)); | 682 | sock_owned_by_user(sk)); |
690 | if (filter) { | 683 | if (filter) { |
691 | rcu_assign_pointer(sk->sk_filter, NULL); | 684 | rcu_assign_pointer(sk->sk_filter, NULL); |
692 | sk_filter_delayed_uncharge(sk, filter); | 685 | sk_filter_uncharge(sk, filter); |
693 | ret = 0; | 686 | ret = 0; |
694 | } | 687 | } |
695 | return ret; | 688 | return ret; |
diff --git a/net/core/request_sock.c b/net/core/request_sock.c index 41d99435f62d..182236b2510a 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c | |||
@@ -46,9 +46,7 @@ int reqsk_queue_alloc(struct request_sock_queue *queue, | |||
46 | nr_table_entries = roundup_pow_of_two(nr_table_entries + 1); | 46 | nr_table_entries = roundup_pow_of_two(nr_table_entries + 1); |
47 | lopt_size += nr_table_entries * sizeof(struct request_sock *); | 47 | lopt_size += nr_table_entries * sizeof(struct request_sock *); |
48 | if (lopt_size > PAGE_SIZE) | 48 | if (lopt_size > PAGE_SIZE) |
49 | lopt = __vmalloc(lopt_size, | 49 | lopt = vzalloc(lopt_size); |
50 | GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, | ||
51 | PAGE_KERNEL); | ||
52 | else | 50 | else |
53 | lopt = kzalloc(lopt_size, GFP_KERNEL); | 51 | lopt = kzalloc(lopt_size, GFP_KERNEL); |
54 | if (lopt == NULL) | 52 | if (lopt == NULL) |
diff --git a/net/dccp/input.c b/net/dccp/input.c index 7d230d14ce22..15af247ea007 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -241,7 +241,8 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) | |||
241 | dccp_update_gsr(sk, seqno); | 241 | dccp_update_gsr(sk, seqno); |
242 | 242 | ||
243 | if (dh->dccph_type != DCCP_PKT_SYNC && | 243 | if (dh->dccph_type != DCCP_PKT_SYNC && |
244 | (ackno != DCCP_PKT_WITHOUT_ACK_SEQ)) | 244 | ackno != DCCP_PKT_WITHOUT_ACK_SEQ && |
245 | after48(ackno, dp->dccps_gar)) | ||
245 | dp->dccps_gar = ackno; | 246 | dp->dccps_gar = ackno; |
246 | } else { | 247 | } else { |
247 | unsigned long now = jiffies; | 248 | unsigned long now = jiffies; |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 9ecef9968c39..0065e7e14af4 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -1556,6 +1556,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us | |||
1556 | if (r_len > sizeof(struct linkinfo_dn)) | 1556 | if (r_len > sizeof(struct linkinfo_dn)) |
1557 | r_len = sizeof(struct linkinfo_dn); | 1557 | r_len = sizeof(struct linkinfo_dn); |
1558 | 1558 | ||
1559 | memset(&link, 0, sizeof(link)); | ||
1560 | |||
1559 | switch(sock->state) { | 1561 | switch(sock->state) { |
1560 | case SS_CONNECTING: | 1562 | case SS_CONNECTING: |
1561 | link.idn_linkstate = LL_CONNECTING; | 1563 | link.idn_linkstate = LL_CONNECTING; |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index f8c1ae4b41f0..f180371fa415 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
32 | #include <linux/udp.h> | 32 | #include <linux/udp.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/vmalloc.h> | ||
34 | #include <net/sock.h> | 35 | #include <net/sock.h> |
35 | #include <net/inet_common.h> | 36 | #include <net/inet_common.h> |
36 | #include <linux/stat.h> | 37 | #include <linux/stat.h> |
@@ -276,12 +277,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
276 | #endif | 277 | #endif |
277 | #ifdef CONFIG_ECONET_AUNUDP | 278 | #ifdef CONFIG_ECONET_AUNUDP |
278 | struct msghdr udpmsg; | 279 | struct msghdr udpmsg; |
279 | struct iovec iov[msg->msg_iovlen+1]; | 280 | struct iovec iov[2]; |
280 | struct aunhdr ah; | 281 | struct aunhdr ah; |
281 | struct sockaddr_in udpdest; | 282 | struct sockaddr_in udpdest; |
282 | __kernel_size_t size; | 283 | __kernel_size_t size; |
283 | int i; | ||
284 | mm_segment_t oldfs; | 284 | mm_segment_t oldfs; |
285 | char *userbuf; | ||
285 | #endif | 286 | #endif |
286 | 287 | ||
287 | /* | 288 | /* |
@@ -297,23 +298,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
297 | 298 | ||
298 | mutex_lock(&econet_mutex); | 299 | mutex_lock(&econet_mutex); |
299 | 300 | ||
300 | if (saddr == NULL) { | 301 | if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) { |
301 | struct econet_sock *eo = ec_sk(sk); | 302 | mutex_unlock(&econet_mutex); |
302 | 303 | return -EINVAL; | |
303 | addr.station = eo->station; | 304 | } |
304 | addr.net = eo->net; | 305 | addr.station = saddr->addr.station; |
305 | port = eo->port; | 306 | addr.net = saddr->addr.net; |
306 | cb = eo->cb; | 307 | port = saddr->port; |
307 | } else { | 308 | cb = saddr->cb; |
308 | if (msg->msg_namelen < sizeof(struct sockaddr_ec)) { | ||
309 | mutex_unlock(&econet_mutex); | ||
310 | return -EINVAL; | ||
311 | } | ||
312 | addr.station = saddr->addr.station; | ||
313 | addr.net = saddr->addr.net; | ||
314 | port = saddr->port; | ||
315 | cb = saddr->cb; | ||
316 | } | ||
317 | 309 | ||
318 | /* Look for a device with the right network number. */ | 310 | /* Look for a device with the right network number. */ |
319 | dev = net2dev_map[addr.net]; | 311 | dev = net2dev_map[addr.net]; |
@@ -328,17 +320,17 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
328 | } | 320 | } |
329 | } | 321 | } |
330 | 322 | ||
331 | if (len + 15 > dev->mtu) { | ||
332 | mutex_unlock(&econet_mutex); | ||
333 | return -EMSGSIZE; | ||
334 | } | ||
335 | |||
336 | if (dev->type == ARPHRD_ECONET) { | 323 | if (dev->type == ARPHRD_ECONET) { |
337 | /* Real hardware Econet. We're not worthy etc. */ | 324 | /* Real hardware Econet. We're not worthy etc. */ |
338 | #ifdef CONFIG_ECONET_NATIVE | 325 | #ifdef CONFIG_ECONET_NATIVE |
339 | unsigned short proto = 0; | 326 | unsigned short proto = 0; |
340 | int res; | 327 | int res; |
341 | 328 | ||
329 | if (len + 15 > dev->mtu) { | ||
330 | mutex_unlock(&econet_mutex); | ||
331 | return -EMSGSIZE; | ||
332 | } | ||
333 | |||
342 | dev_hold(dev); | 334 | dev_hold(dev); |
343 | 335 | ||
344 | skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev), | 336 | skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev), |
@@ -351,7 +343,6 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
351 | 343 | ||
352 | eb = (struct ec_cb *)&skb->cb; | 344 | eb = (struct ec_cb *)&skb->cb; |
353 | 345 | ||
354 | /* BUG: saddr may be NULL */ | ||
355 | eb->cookie = saddr->cookie; | 346 | eb->cookie = saddr->cookie; |
356 | eb->sec = *saddr; | 347 | eb->sec = *saddr; |
357 | eb->sent = ec_tx_done; | 348 | eb->sent = ec_tx_done; |
@@ -415,6 +406,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
415 | return -ENETDOWN; /* No socket - can't send */ | 406 | return -ENETDOWN; /* No socket - can't send */ |
416 | } | 407 | } |
417 | 408 | ||
409 | if (len > 32768) { | ||
410 | err = -E2BIG; | ||
411 | goto error; | ||
412 | } | ||
413 | |||
418 | /* Make up a UDP datagram and hand it off to some higher intellect. */ | 414 | /* Make up a UDP datagram and hand it off to some higher intellect. */ |
419 | 415 | ||
420 | memset(&udpdest, 0, sizeof(udpdest)); | 416 | memset(&udpdest, 0, sizeof(udpdest)); |
@@ -446,36 +442,26 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
446 | 442 | ||
447 | /* tack our header on the front of the iovec */ | 443 | /* tack our header on the front of the iovec */ |
448 | size = sizeof(struct aunhdr); | 444 | size = sizeof(struct aunhdr); |
449 | /* | ||
450 | * XXX: that is b0rken. We can't mix userland and kernel pointers | ||
451 | * in iovec, since on a lot of platforms copy_from_user() will | ||
452 | * *not* work with the kernel and userland ones at the same time, | ||
453 | * regardless of what we do with set_fs(). And we are talking about | ||
454 | * econet-over-ethernet here, so "it's only ARM anyway" doesn't | ||
455 | * apply. Any suggestions on fixing that code? -- AV | ||
456 | */ | ||
457 | iov[0].iov_base = (void *)&ah; | 445 | iov[0].iov_base = (void *)&ah; |
458 | iov[0].iov_len = size; | 446 | iov[0].iov_len = size; |
459 | for (i = 0; i < msg->msg_iovlen; i++) { | 447 | |
460 | void __user *base = msg->msg_iov[i].iov_base; | 448 | userbuf = vmalloc(len); |
461 | size_t iov_len = msg->msg_iov[i].iov_len; | 449 | if (userbuf == NULL) { |
462 | /* Check it now since we switch to KERNEL_DS later. */ | 450 | err = -ENOMEM; |
463 | if (!access_ok(VERIFY_READ, base, iov_len)) { | 451 | goto error; |
464 | mutex_unlock(&econet_mutex); | ||
465 | return -EFAULT; | ||
466 | } | ||
467 | iov[i+1].iov_base = base; | ||
468 | iov[i+1].iov_len = iov_len; | ||
469 | size += iov_len; | ||
470 | } | 452 | } |
471 | 453 | ||
454 | iov[1].iov_base = userbuf; | ||
455 | iov[1].iov_len = len; | ||
456 | err = memcpy_fromiovec(userbuf, msg->msg_iov, len); | ||
457 | if (err) | ||
458 | goto error_free_buf; | ||
459 | |||
472 | /* Get a skbuff (no data, just holds our cb information) */ | 460 | /* Get a skbuff (no data, just holds our cb information) */ |
473 | if ((skb = sock_alloc_send_skb(sk, 0, | 461 | if ((skb = sock_alloc_send_skb(sk, 0, |
474 | msg->msg_flags & MSG_DONTWAIT, | 462 | msg->msg_flags & MSG_DONTWAIT, |
475 | &err)) == NULL) { | 463 | &err)) == NULL) |
476 | mutex_unlock(&econet_mutex); | 464 | goto error_free_buf; |
477 | return err; | ||
478 | } | ||
479 | 465 | ||
480 | eb = (struct ec_cb *)&skb->cb; | 466 | eb = (struct ec_cb *)&skb->cb; |
481 | 467 | ||
@@ -491,7 +477,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
491 | udpmsg.msg_name = (void *)&udpdest; | 477 | udpmsg.msg_name = (void *)&udpdest; |
492 | udpmsg.msg_namelen = sizeof(udpdest); | 478 | udpmsg.msg_namelen = sizeof(udpdest); |
493 | udpmsg.msg_iov = &iov[0]; | 479 | udpmsg.msg_iov = &iov[0]; |
494 | udpmsg.msg_iovlen = msg->msg_iovlen + 1; | 480 | udpmsg.msg_iovlen = 2; |
495 | udpmsg.msg_control = NULL; | 481 | udpmsg.msg_control = NULL; |
496 | udpmsg.msg_controllen = 0; | 482 | udpmsg.msg_controllen = 0; |
497 | udpmsg.msg_flags=0; | 483 | udpmsg.msg_flags=0; |
@@ -499,9 +485,13 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
499 | oldfs = get_fs(); set_fs(KERNEL_DS); /* More privs :-) */ | 485 | oldfs = get_fs(); set_fs(KERNEL_DS); /* More privs :-) */ |
500 | err = sock_sendmsg(udpsock, &udpmsg, size); | 486 | err = sock_sendmsg(udpsock, &udpmsg, size); |
501 | set_fs(oldfs); | 487 | set_fs(oldfs); |
488 | |||
489 | error_free_buf: | ||
490 | vfree(userbuf); | ||
502 | #else | 491 | #else |
503 | err = -EPROTOTYPE; | 492 | err = -EPROTOTYPE; |
504 | #endif | 493 | #endif |
494 | error: | ||
505 | mutex_unlock(&econet_mutex); | 495 | mutex_unlock(&econet_mutex); |
506 | 496 | ||
507 | return err; | 497 | return err; |
@@ -671,6 +661,11 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) | |||
671 | err = 0; | 661 | err = 0; |
672 | switch (cmd) { | 662 | switch (cmd) { |
673 | case SIOCSIFADDR: | 663 | case SIOCSIFADDR: |
664 | if (!capable(CAP_NET_ADMIN)) { | ||
665 | err = -EPERM; | ||
666 | break; | ||
667 | } | ||
668 | |||
674 | edev = dev->ec_ptr; | 669 | edev = dev->ec_ptr; |
675 | if (edev == NULL) { | 670 | if (edev == NULL) { |
676 | /* Magic up a new one. */ | 671 | /* Magic up a new one. */ |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 200eb538fbb3..0f280348e0fd 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -365,7 +365,7 @@ static struct tnode *tnode_alloc(size_t size) | |||
365 | if (size <= PAGE_SIZE) | 365 | if (size <= PAGE_SIZE) |
366 | return kzalloc(size, GFP_KERNEL); | 366 | return kzalloc(size, GFP_KERNEL); |
367 | else | 367 | else |
368 | return __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); | 368 | return vzalloc(size); |
369 | } | 369 | } |
370 | 370 | ||
371 | static void __tnode_vfree(struct work_struct *arg) | 371 | static void __tnode_vfree(struct work_struct *arg) |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 1b344f30b463..3c0369a3a663 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -133,8 +133,7 @@ int __inet_inherit_port(struct sock *sk, struct sock *child) | |||
133 | } | 133 | } |
134 | } | 134 | } |
135 | } | 135 | } |
136 | sk_add_bind_node(child, &tb->owners); | 136 | inet_bind_hash(child, tb, port); |
137 | inet_csk(child)->icsk_bind_hash = tb; | ||
138 | spin_unlock(&head->lock); | 137 | spin_unlock(&head->lock); |
139 | 138 | ||
140 | return 0; | 139 | return 0; |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1b48eb1ed453..b14ec7d03b6e 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = { | |||
253 | SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), | 253 | SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), |
254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), | 254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), |
255 | SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), | 255 | SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), |
256 | SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW), | ||
256 | SNMP_MIB_SENTINEL | 257 | SNMP_MIB_SENTINEL |
257 | }; | 258 | }; |
258 | 259 | ||
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index e91911d7aae2..1b4ec21497a4 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -26,6 +26,8 @@ static int zero; | |||
26 | static int tcp_retr1_max = 255; | 26 | static int tcp_retr1_max = 255; |
27 | static int ip_local_port_range_min[] = { 1, 1 }; | 27 | static int ip_local_port_range_min[] = { 1, 1 }; |
28 | static int ip_local_port_range_max[] = { 65535, 65535 }; | 28 | static int ip_local_port_range_max[] = { 65535, 65535 }; |
29 | static int tcp_adv_win_scale_min = -31; | ||
30 | static int tcp_adv_win_scale_max = 31; | ||
29 | 31 | ||
30 | /* Update system visible IP port range */ | 32 | /* Update system visible IP port range */ |
31 | static void set_local_port_range(int range[2]) | 33 | static void set_local_port_range(int range[2]) |
@@ -426,7 +428,9 @@ static struct ctl_table ipv4_table[] = { | |||
426 | .data = &sysctl_tcp_adv_win_scale, | 428 | .data = &sysctl_tcp_adv_win_scale, |
427 | .maxlen = sizeof(int), | 429 | .maxlen = sizeof(int), |
428 | .mode = 0644, | 430 | .mode = 0644, |
429 | .proc_handler = proc_dointvec | 431 | .proc_handler = proc_dointvec_minmax, |
432 | .extra1 = &tcp_adv_win_scale_min, | ||
433 | .extra2 = &tcp_adv_win_scale_max, | ||
430 | }, | 434 | }, |
431 | { | 435 | { |
432 | .procname = "tcp_tw_reuse", | 436 | .procname = "tcp_tw_reuse", |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 2bb46d55f40c..6c11eece262c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2244,7 +2244,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2244 | /* Values greater than interface MTU won't take effect. However | 2244 | /* Values greater than interface MTU won't take effect. However |
2245 | * at the point when this call is done we typically don't yet | 2245 | * at the point when this call is done we typically don't yet |
2246 | * know which interface is going to be used */ | 2246 | * know which interface is going to be used */ |
2247 | if (val < 64 || val > MAX_TCP_WINDOW) { | 2247 | if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) { |
2248 | err = -EINVAL; | 2248 | err = -EINVAL; |
2249 | break; | 2249 | break; |
2250 | } | 2250 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index dd555051ec8b..4fc3387aa994 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -2013,7 +2013,9 @@ get_req: | |||
2013 | } | 2013 | } |
2014 | get_sk: | 2014 | get_sk: |
2015 | sk_nulls_for_each_from(sk, node) { | 2015 | sk_nulls_for_each_from(sk, node) { |
2016 | if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) { | 2016 | if (!net_eq(sock_net(sk), net)) |
2017 | continue; | ||
2018 | if (sk->sk_family == st->family) { | ||
2017 | cur = sk; | 2019 | cur = sk; |
2018 | goto out; | 2020 | goto out; |
2019 | } | 2021 | } |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 3527b51d6159..80b1f80759ab 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -392,7 +392,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) | |||
392 | * socket up. We've got bigger problems than | 392 | * socket up. We've got bigger problems than |
393 | * non-graceful socket closings. | 393 | * non-graceful socket closings. |
394 | */ | 394 | */ |
395 | LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n"); | 395 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); |
396 | } | 396 | } |
397 | 397 | ||
398 | tcp_update_metrics(sk); | 398 | tcp_update_metrics(sk); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 749b6498588e..97041f24cd27 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -231,11 +231,10 @@ void tcp_select_initial_window(int __space, __u32 mss, | |||
231 | /* when initializing use the value from init_rcv_wnd | 231 | /* when initializing use the value from init_rcv_wnd |
232 | * rather than the default from above | 232 | * rather than the default from above |
233 | */ | 233 | */ |
234 | if (init_rcv_wnd && | 234 | if (init_rcv_wnd) |
235 | (*rcv_wnd > init_rcv_wnd * mss)) | 235 | *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss); |
236 | *rcv_wnd = init_rcv_wnd * mss; | 236 | else |
237 | else if (*rcv_wnd > init_cwnd * mss) | 237 | *rcv_wnd = min(*rcv_wnd, init_cwnd * mss); |
238 | *rcv_wnd = init_cwnd * mss; | ||
239 | } | 238 | } |
240 | 239 | ||
241 | /* Set the clamp no higher than max representable value */ | 240 | /* Set the clamp no higher than max representable value */ |
@@ -386,27 +385,30 @@ struct tcp_out_options { | |||
386 | */ | 385 | */ |
387 | static u8 tcp_cookie_size_check(u8 desired) | 386 | static u8 tcp_cookie_size_check(u8 desired) |
388 | { | 387 | { |
389 | if (desired > 0) { | 388 | int cookie_size; |
389 | |||
390 | if (desired > 0) | ||
390 | /* previously specified */ | 391 | /* previously specified */ |
391 | return desired; | 392 | return desired; |
392 | } | 393 | |
393 | if (sysctl_tcp_cookie_size <= 0) { | 394 | cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); |
395 | if (cookie_size <= 0) | ||
394 | /* no default specified */ | 396 | /* no default specified */ |
395 | return 0; | 397 | return 0; |
396 | } | 398 | |
397 | if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) { | 399 | if (cookie_size <= TCP_COOKIE_MIN) |
398 | /* value too small, specify minimum */ | 400 | /* value too small, specify minimum */ |
399 | return TCP_COOKIE_MIN; | 401 | return TCP_COOKIE_MIN; |
400 | } | 402 | |
401 | if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) { | 403 | if (cookie_size >= TCP_COOKIE_MAX) |
402 | /* value too large, specify maximum */ | 404 | /* value too large, specify maximum */ |
403 | return TCP_COOKIE_MAX; | 405 | return TCP_COOKIE_MAX; |
404 | } | 406 | |
405 | if (0x1 & sysctl_tcp_cookie_size) { | 407 | if (cookie_size & 1) |
406 | /* 8-bit multiple, illegal, fix it */ | 408 | /* 8-bit multiple, illegal, fix it */ |
407 | return (u8)(sysctl_tcp_cookie_size + 0x1); | 409 | cookie_size++; |
408 | } | 410 | |
409 | return (u8)sysctl_tcp_cookie_size; | 411 | return (u8)cookie_size; |
410 | } | 412 | } |
411 | 413 | ||
412 | /* Write previously computed TCP options to the packet. | 414 | /* Write previously computed TCP options to the packet. |
@@ -1516,6 +1518,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1516 | struct tcp_sock *tp = tcp_sk(sk); | 1518 | struct tcp_sock *tp = tcp_sk(sk); |
1517 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1519 | const struct inet_connection_sock *icsk = inet_csk(sk); |
1518 | u32 send_win, cong_win, limit, in_flight; | 1520 | u32 send_win, cong_win, limit, in_flight; |
1521 | int win_divisor; | ||
1519 | 1522 | ||
1520 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) | 1523 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) |
1521 | goto send_now; | 1524 | goto send_now; |
@@ -1547,13 +1550,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1547 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) | 1550 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) |
1548 | goto send_now; | 1551 | goto send_now; |
1549 | 1552 | ||
1550 | if (sysctl_tcp_tso_win_divisor) { | 1553 | win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor); |
1554 | if (win_divisor) { | ||
1551 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 1555 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
1552 | 1556 | ||
1553 | /* If at least some fraction of a window is available, | 1557 | /* If at least some fraction of a window is available, |
1554 | * just use it. | 1558 | * just use it. |
1555 | */ | 1559 | */ |
1556 | chunk /= sysctl_tcp_tso_win_divisor; | 1560 | chunk /= win_divisor; |
1557 | if (limit >= chunk) | 1561 | if (limit >= chunk) |
1558 | goto send_now; | 1562 | goto send_now; |
1559 | } else { | 1563 | } else { |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index b1155554bb18..4f4483e697bd 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1173,6 +1173,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
1173 | sizeof (struct ipv6hdr); | 1173 | sizeof (struct ipv6hdr); |
1174 | 1174 | ||
1175 | dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr); | 1175 | dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr); |
1176 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | ||
1177 | dev->mtu-=8; | ||
1176 | 1178 | ||
1177 | if (dev->mtu < IPV6_MIN_MTU) | 1179 | if (dev->mtu < IPV6_MIN_MTU) |
1178 | dev->mtu = IPV6_MIN_MTU; | 1180 | dev->mtu = IPV6_MIN_MTU; |
@@ -1361,12 +1363,17 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { | |||
1361 | 1363 | ||
1362 | static void ip6_tnl_dev_setup(struct net_device *dev) | 1364 | static void ip6_tnl_dev_setup(struct net_device *dev) |
1363 | { | 1365 | { |
1366 | struct ip6_tnl *t; | ||
1367 | |||
1364 | dev->netdev_ops = &ip6_tnl_netdev_ops; | 1368 | dev->netdev_ops = &ip6_tnl_netdev_ops; |
1365 | dev->destructor = ip6_dev_free; | 1369 | dev->destructor = ip6_dev_free; |
1366 | 1370 | ||
1367 | dev->type = ARPHRD_TUNNEL6; | 1371 | dev->type = ARPHRD_TUNNEL6; |
1368 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); | 1372 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); |
1369 | dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); | 1373 | dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); |
1374 | t = netdev_priv(dev); | ||
1375 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | ||
1376 | dev->mtu-=8; | ||
1370 | dev->flags |= IFF_NOARP; | 1377 | dev->flags |= IFF_NOARP; |
1371 | dev->addr_len = sizeof(struct in6_addr); | 1378 | dev->addr_len = sizeof(struct in6_addr); |
1372 | dev->features |= NETIF_F_NETNS_LOCAL; | 1379 | dev->features |= NETIF_F_NETNS_LOCAL; |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 6e48a80d0f25..8ce38f10a547 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -606,8 +606,9 @@ static int ipip6_rcv(struct sk_buff *skb) | |||
606 | return 0; | 606 | return 0; |
607 | } | 607 | } |
608 | 608 | ||
609 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); | 609 | /* no tunnel matched, let upstream know, ipsec may handle it */ |
610 | rcu_read_unlock(); | 610 | rcu_read_unlock(); |
611 | return 1; | ||
611 | out: | 612 | out: |
612 | kfree_skb(skb); | 613 | kfree_skb(skb); |
613 | return 0; | 614 | return 0; |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 04635e88e8ed..110efb704c9b 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -672,4 +672,8 @@ MODULE_LICENSE("GPL"); | |||
672 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); | 672 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); |
673 | MODULE_DESCRIPTION("L2TP over IP"); | 673 | MODULE_DESCRIPTION("L2TP over IP"); |
674 | MODULE_VERSION("1.0"); | 674 | MODULE_VERSION("1.0"); |
675 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP); | 675 | |
676 | /* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like | ||
677 | * enums | ||
678 | */ | ||
679 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP); | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d2fcd22ab06d..55337709de41 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2245,6 +2245,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
2245 | break; | 2245 | break; |
2246 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): | 2246 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): |
2247 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): | 2247 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): |
2248 | if (is_multicast_ether_addr(mgmt->da) && | ||
2249 | !is_broadcast_ether_addr(mgmt->da)) | ||
2250 | return RX_DROP_MONITOR; | ||
2251 | |||
2248 | /* process only for station */ | 2252 | /* process only for station */ |
2249 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 2253 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
2250 | return RX_DROP_MONITOR; | 2254 | return RX_DROP_MONITOR; |
@@ -2739,6 +2743,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2739 | 2743 | ||
2740 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) | 2744 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) |
2741 | return; | 2745 | return; |
2746 | goto out; | ||
2742 | } | 2747 | } |
2743 | } | 2748 | } |
2744 | 2749 | ||
@@ -2778,6 +2783,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2778 | return; | 2783 | return; |
2779 | } | 2784 | } |
2780 | 2785 | ||
2786 | out: | ||
2781 | dev_kfree_skb(skb); | 2787 | dev_kfree_skb(skb); |
2782 | } | 2788 | } |
2783 | 2789 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e69483647f33..2ba742656825 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1595,7 +1595,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1595 | list) { | 1595 | list) { |
1596 | if (!ieee80211_sdata_running(tmp_sdata)) | 1596 | if (!ieee80211_sdata_running(tmp_sdata)) |
1597 | continue; | 1597 | continue; |
1598 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) | 1598 | if (tmp_sdata->vif.type == |
1599 | NL80211_IFTYPE_MONITOR || | ||
1600 | tmp_sdata->vif.type == | ||
1601 | NL80211_IFTYPE_AP_VLAN || | ||
1602 | tmp_sdata->vif.type == | ||
1603 | NL80211_IFTYPE_WDS) | ||
1599 | continue; | 1604 | continue; |
1600 | if (compare_ether_addr(tmp_sdata->vif.addr, | 1605 | if (compare_ether_addr(tmp_sdata->vif.addr, |
1601 | hdr->addr2) == 0) { | 1606 | hdr->addr2) == 0) { |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 7ff31c60186a..417d7a6c36cf 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1344,9 +1344,25 @@ static void unix_destruct_scm(struct sk_buff *skb) | |||
1344 | sock_wfree(skb); | 1344 | sock_wfree(skb); |
1345 | } | 1345 | } |
1346 | 1346 | ||
1347 | #define MAX_RECURSION_LEVEL 4 | ||
1348 | |||
1347 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | 1349 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) |
1348 | { | 1350 | { |
1349 | int i; | 1351 | int i; |
1352 | unsigned char max_level = 0; | ||
1353 | int unix_sock_count = 0; | ||
1354 | |||
1355 | for (i = scm->fp->count - 1; i >= 0; i--) { | ||
1356 | struct sock *sk = unix_get_socket(scm->fp->fp[i]); | ||
1357 | |||
1358 | if (sk) { | ||
1359 | unix_sock_count++; | ||
1360 | max_level = max(max_level, | ||
1361 | unix_sk(sk)->recursion_level); | ||
1362 | } | ||
1363 | } | ||
1364 | if (unlikely(max_level > MAX_RECURSION_LEVEL)) | ||
1365 | return -ETOOMANYREFS; | ||
1350 | 1366 | ||
1351 | /* | 1367 | /* |
1352 | * Need to duplicate file references for the sake of garbage | 1368 | * Need to duplicate file references for the sake of garbage |
@@ -1357,9 +1373,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | |||
1357 | if (!UNIXCB(skb).fp) | 1373 | if (!UNIXCB(skb).fp) |
1358 | return -ENOMEM; | 1374 | return -ENOMEM; |
1359 | 1375 | ||
1360 | for (i = scm->fp->count-1; i >= 0; i--) | 1376 | if (unix_sock_count) { |
1361 | unix_inflight(scm->fp->fp[i]); | 1377 | for (i = scm->fp->count - 1; i >= 0; i--) |
1362 | return 0; | 1378 | unix_inflight(scm->fp->fp[i]); |
1379 | } | ||
1380 | return max_level; | ||
1363 | } | 1381 | } |
1364 | 1382 | ||
1365 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) | 1383 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) |
@@ -1394,6 +1412,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1394 | struct sk_buff *skb; | 1412 | struct sk_buff *skb; |
1395 | long timeo; | 1413 | long timeo; |
1396 | struct scm_cookie tmp_scm; | 1414 | struct scm_cookie tmp_scm; |
1415 | int max_level; | ||
1397 | 1416 | ||
1398 | if (NULL == siocb->scm) | 1417 | if (NULL == siocb->scm) |
1399 | siocb->scm = &tmp_scm; | 1418 | siocb->scm = &tmp_scm; |
@@ -1432,8 +1451,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1432 | goto out; | 1451 | goto out; |
1433 | 1452 | ||
1434 | err = unix_scm_to_skb(siocb->scm, skb, true); | 1453 | err = unix_scm_to_skb(siocb->scm, skb, true); |
1435 | if (err) | 1454 | if (err < 0) |
1436 | goto out_free; | 1455 | goto out_free; |
1456 | max_level = err + 1; | ||
1437 | unix_get_secdata(siocb->scm, skb); | 1457 | unix_get_secdata(siocb->scm, skb); |
1438 | 1458 | ||
1439 | skb_reset_transport_header(skb); | 1459 | skb_reset_transport_header(skb); |
@@ -1515,6 +1535,8 @@ restart: | |||
1515 | if (sock_flag(other, SOCK_RCVTSTAMP)) | 1535 | if (sock_flag(other, SOCK_RCVTSTAMP)) |
1516 | __net_timestamp(skb); | 1536 | __net_timestamp(skb); |
1517 | skb_queue_tail(&other->sk_receive_queue, skb); | 1537 | skb_queue_tail(&other->sk_receive_queue, skb); |
1538 | if (max_level > unix_sk(other)->recursion_level) | ||
1539 | unix_sk(other)->recursion_level = max_level; | ||
1518 | unix_state_unlock(other); | 1540 | unix_state_unlock(other); |
1519 | other->sk_data_ready(other, len); | 1541 | other->sk_data_ready(other, len); |
1520 | sock_put(other); | 1542 | sock_put(other); |
@@ -1545,6 +1567,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1545 | int sent = 0; | 1567 | int sent = 0; |
1546 | struct scm_cookie tmp_scm; | 1568 | struct scm_cookie tmp_scm; |
1547 | bool fds_sent = false; | 1569 | bool fds_sent = false; |
1570 | int max_level; | ||
1548 | 1571 | ||
1549 | if (NULL == siocb->scm) | 1572 | if (NULL == siocb->scm) |
1550 | siocb->scm = &tmp_scm; | 1573 | siocb->scm = &tmp_scm; |
@@ -1608,10 +1631,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1608 | 1631 | ||
1609 | /* Only send the fds in the first buffer */ | 1632 | /* Only send the fds in the first buffer */ |
1610 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); | 1633 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); |
1611 | if (err) { | 1634 | if (err < 0) { |
1612 | kfree_skb(skb); | 1635 | kfree_skb(skb); |
1613 | goto out_err; | 1636 | goto out_err; |
1614 | } | 1637 | } |
1638 | max_level = err + 1; | ||
1615 | fds_sent = true; | 1639 | fds_sent = true; |
1616 | 1640 | ||
1617 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 1641 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
@@ -1627,6 +1651,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1627 | goto pipe_err_free; | 1651 | goto pipe_err_free; |
1628 | 1652 | ||
1629 | skb_queue_tail(&other->sk_receive_queue, skb); | 1653 | skb_queue_tail(&other->sk_receive_queue, skb); |
1654 | if (max_level > unix_sk(other)->recursion_level) | ||
1655 | unix_sk(other)->recursion_level = max_level; | ||
1630 | unix_state_unlock(other); | 1656 | unix_state_unlock(other); |
1631 | other->sk_data_ready(other, size); | 1657 | other->sk_data_ready(other, size); |
1632 | sent += size; | 1658 | sent += size; |
@@ -1847,6 +1873,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1847 | unix_state_lock(sk); | 1873 | unix_state_lock(sk); |
1848 | skb = skb_dequeue(&sk->sk_receive_queue); | 1874 | skb = skb_dequeue(&sk->sk_receive_queue); |
1849 | if (skb == NULL) { | 1875 | if (skb == NULL) { |
1876 | unix_sk(sk)->recursion_level = 0; | ||
1850 | if (copied >= target) | 1877 | if (copied >= target) |
1851 | goto unlock; | 1878 | goto unlock; |
1852 | 1879 | ||
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index c8df6fda0b1f..f89f83bf828e 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
@@ -96,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait); | |||
96 | unsigned int unix_tot_inflight; | 96 | unsigned int unix_tot_inflight; |
97 | 97 | ||
98 | 98 | ||
99 | static struct sock *unix_get_socket(struct file *filp) | 99 | struct sock *unix_get_socket(struct file *filp) |
100 | { | 100 | { |
101 | struct sock *u_sock = NULL; | 101 | struct sock *u_sock = NULL; |
102 | struct inode *inode = filp->f_path.dentry->d_inode; | 102 | struct inode *inode = filp->f_path.dentry->d_inode; |
@@ -259,9 +259,16 @@ static void inc_inflight_move_tail(struct unix_sock *u) | |||
259 | } | 259 | } |
260 | 260 | ||
261 | static bool gc_in_progress = false; | 261 | static bool gc_in_progress = false; |
262 | #define UNIX_INFLIGHT_TRIGGER_GC 16000 | ||
262 | 263 | ||
263 | void wait_for_unix_gc(void) | 264 | void wait_for_unix_gc(void) |
264 | { | 265 | { |
266 | /* | ||
267 | * If number of inflight sockets is insane, | ||
268 | * force a garbage collect right now. | ||
269 | */ | ||
270 | if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress) | ||
271 | unix_gc(); | ||
265 | wait_event(unix_gc_wait, gc_in_progress == false); | 272 | wait_event(unix_gc_wait, gc_in_progress == false); |
266 | } | 273 | } |
267 | 274 | ||
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 4c81f6abb65b..4cbc942f762a 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c | |||
@@ -398,6 +398,7 @@ void __exit x25_link_free(void) | |||
398 | list_for_each_safe(entry, tmp, &x25_neigh_list) { | 398 | list_for_each_safe(entry, tmp, &x25_neigh_list) { |
399 | nb = list_entry(entry, struct x25_neigh, node); | 399 | nb = list_entry(entry, struct x25_neigh, node); |
400 | __x25_remove_neigh(nb); | 400 | __x25_remove_neigh(nb); |
401 | dev_put(nb->dev); | ||
401 | } | 402 | } |
402 | write_unlock_bh(&x25_neigh_list_lock); | 403 | write_unlock_bh(&x25_neigh_list_lock); |
403 | } | 404 | } |
diff --git a/net/xfrm/xfrm_hash.c b/net/xfrm/xfrm_hash.c index a2023ec52329..1e98bc0fe0a5 100644 --- a/net/xfrm/xfrm_hash.c +++ b/net/xfrm/xfrm_hash.c | |||
@@ -19,7 +19,7 @@ struct hlist_head *xfrm_hash_alloc(unsigned int sz) | |||
19 | if (sz <= PAGE_SIZE) | 19 | if (sz <= PAGE_SIZE) |
20 | n = kzalloc(sz, GFP_KERNEL); | 20 | n = kzalloc(sz, GFP_KERNEL); |
21 | else if (hashdist) | 21 | else if (hashdist) |
22 | n = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); | 22 | n = vzalloc(sz); |
23 | else | 23 | else |
24 | n = (struct hlist_head *) | 24 | n = (struct hlist_head *) |
25 | __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, | 25 | __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, |