diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/can/bcm.c | 3 | ||||
| -rw-r--r-- | net/core/dev.c | 2 | ||||
| -rw-r--r-- | net/core/skbuff.c | 6 | ||||
| -rw-r--r-- | net/ipv4/icmp.c | 3 | ||||
| -rw-r--r-- | net/ipv4/inet_diag.c | 154 | ||||
| -rw-r--r-- | net/ipv4/ip_fragment.c | 19 | ||||
| -rw-r--r-- | net/ipv4/ipmr.c | 4 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 15 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 6 | ||||
| -rw-r--r-- | net/ipv4/tcp_output.c | 15 | ||||
| -rw-r--r-- | net/irda/irttp.c | 1 | ||||
| -rw-r--r-- | net/mac80211/offchannel.c | 2 | ||||
| -rw-r--r-- | net/netfilter/ipset/ip_set_hash_netiface.c | 2 | ||||
| -rw-r--r-- | net/openvswitch/flow.c | 14 | ||||
| -rw-r--r-- | net/openvswitch/vport-netdev.c | 2 | ||||
| -rw-r--r-- | net/sctp/chunk.c | 20 | ||||
| -rw-r--r-- | net/sctp/socket.c | 4 | ||||
| -rw-r--r-- | net/sctp/transport.c | 2 |
18 files changed, 191 insertions, 83 deletions
diff --git a/net/can/bcm.c b/net/can/bcm.c index 6f747582718e..969b7cdff59d 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
| @@ -1084,6 +1084,9 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
| 1084 | op->sk = sk; | 1084 | op->sk = sk; |
| 1085 | op->ifindex = ifindex; | 1085 | op->ifindex = ifindex; |
| 1086 | 1086 | ||
| 1087 | /* ifindex for timeout events w/o previous frame reception */ | ||
| 1088 | op->rx_ifindex = ifindex; | ||
| 1089 | |||
| 1087 | /* initialize uninitialized (kzalloc) structure */ | 1090 | /* initialize uninitialized (kzalloc) structure */ |
| 1088 | hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 1091 | hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 1089 | op->timer.function = bcm_rx_timeout_handler; | 1092 | op->timer.function = bcm_rx_timeout_handler; |
diff --git a/net/core/dev.c b/net/core/dev.c index c0946cb2b354..e5942bf45a6d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -3451,6 +3451,8 @@ static int napi_gro_complete(struct sk_buff *skb) | |||
| 3451 | struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; | 3451 | struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; |
| 3452 | int err = -ENOENT; | 3452 | int err = -ENOENT; |
| 3453 | 3453 | ||
| 3454 | BUILD_BUG_ON(sizeof(struct napi_gro_cb) > sizeof(skb->cb)); | ||
| 3455 | |||
| 3454 | if (NAPI_GRO_CB(skb)->count == 1) { | 3456 | if (NAPI_GRO_CB(skb)->count == 1) { |
| 3455 | skb_shinfo(skb)->gso_size = 0; | 3457 | skb_shinfo(skb)->gso_size = 0; |
| 3456 | goto out; | 3458 | goto out; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4007c1437fda..3f0636cd76cd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -3004,7 +3004,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
| 3004 | skb_shinfo(nskb)->gso_size = pinfo->gso_size; | 3004 | skb_shinfo(nskb)->gso_size = pinfo->gso_size; |
| 3005 | pinfo->gso_size = 0; | 3005 | pinfo->gso_size = 0; |
| 3006 | skb_header_release(p); | 3006 | skb_header_release(p); |
| 3007 | nskb->prev = p; | 3007 | NAPI_GRO_CB(nskb)->last = p; |
| 3008 | 3008 | ||
| 3009 | nskb->data_len += p->len; | 3009 | nskb->data_len += p->len; |
| 3010 | nskb->truesize += p->truesize; | 3010 | nskb->truesize += p->truesize; |
| @@ -3030,8 +3030,8 @@ merge: | |||
| 3030 | 3030 | ||
| 3031 | __skb_pull(skb, offset); | 3031 | __skb_pull(skb, offset); |
| 3032 | 3032 | ||
| 3033 | p->prev->next = skb; | 3033 | NAPI_GRO_CB(p)->last->next = skb; |
| 3034 | p->prev = skb; | 3034 | NAPI_GRO_CB(p)->last = skb; |
| 3035 | skb_header_release(skb); | 3035 | skb_header_release(skb); |
| 3036 | 3036 | ||
| 3037 | done: | 3037 | done: |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index f2eccd531746..17ff9fd7cdda 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -257,7 +257,8 @@ static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, | |||
| 257 | struct inet_peer *peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1); | 257 | struct inet_peer *peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1); |
| 258 | rc = inet_peer_xrlim_allow(peer, | 258 | rc = inet_peer_xrlim_allow(peer, |
| 259 | net->ipv4.sysctl_icmp_ratelimit); | 259 | net->ipv4.sysctl_icmp_ratelimit); |
| 260 | inet_putpeer(peer); | 260 | if (peer) |
| 261 | inet_putpeer(peer); | ||
| 261 | } | 262 | } |
| 262 | out: | 263 | out: |
| 263 | return rc; | 264 | return rc; |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 0c34bfabc11f..e23e16dc501d 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -44,6 +44,10 @@ struct inet_diag_entry { | |||
| 44 | u16 dport; | 44 | u16 dport; |
| 45 | u16 family; | 45 | u16 family; |
| 46 | u16 userlocks; | 46 | u16 userlocks; |
| 47 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 48 | struct in6_addr saddr_storage; /* for IPv4-mapped-IPv6 addresses */ | ||
| 49 | struct in6_addr daddr_storage; /* for IPv4-mapped-IPv6 addresses */ | ||
| 50 | #endif | ||
| 47 | }; | 51 | }; |
| 48 | 52 | ||
| 49 | static DEFINE_MUTEX(inet_diag_table_mutex); | 53 | static DEFINE_MUTEX(inet_diag_table_mutex); |
| @@ -428,25 +432,31 @@ static int inet_diag_bc_run(const struct nlattr *_bc, | |||
| 428 | break; | 432 | break; |
| 429 | } | 433 | } |
| 430 | 434 | ||
| 431 | if (cond->prefix_len == 0) | ||
| 432 | break; | ||
| 433 | |||
| 434 | if (op->code == INET_DIAG_BC_S_COND) | 435 | if (op->code == INET_DIAG_BC_S_COND) |
| 435 | addr = entry->saddr; | 436 | addr = entry->saddr; |
| 436 | else | 437 | else |
| 437 | addr = entry->daddr; | 438 | addr = entry->daddr; |
| 438 | 439 | ||
| 440 | if (cond->family != AF_UNSPEC && | ||
| 441 | cond->family != entry->family) { | ||
| 442 | if (entry->family == AF_INET6 && | ||
| 443 | cond->family == AF_INET) { | ||
| 444 | if (addr[0] == 0 && addr[1] == 0 && | ||
| 445 | addr[2] == htonl(0xffff) && | ||
| 446 | bitstring_match(addr + 3, | ||
| 447 | cond->addr, | ||
| 448 | cond->prefix_len)) | ||
| 449 | break; | ||
| 450 | } | ||
| 451 | yes = 0; | ||
| 452 | break; | ||
| 453 | } | ||
| 454 | |||
| 455 | if (cond->prefix_len == 0) | ||
| 456 | break; | ||
| 439 | if (bitstring_match(addr, cond->addr, | 457 | if (bitstring_match(addr, cond->addr, |
| 440 | cond->prefix_len)) | 458 | cond->prefix_len)) |
| 441 | break; | 459 | break; |
| 442 | if (entry->family == AF_INET6 && | ||
| 443 | cond->family == AF_INET) { | ||
| 444 | if (addr[0] == 0 && addr[1] == 0 && | ||
| 445 | addr[2] == htonl(0xffff) && | ||
| 446 | bitstring_match(addr + 3, cond->addr, | ||
| 447 | cond->prefix_len)) | ||
| 448 | break; | ||
| 449 | } | ||
| 450 | yes = 0; | 460 | yes = 0; |
| 451 | break; | 461 | break; |
| 452 | } | 462 | } |
| @@ -509,6 +519,55 @@ static int valid_cc(const void *bc, int len, int cc) | |||
| 509 | return 0; | 519 | return 0; |
| 510 | } | 520 | } |
| 511 | 521 | ||
| 522 | /* Validate an inet_diag_hostcond. */ | ||
| 523 | static bool valid_hostcond(const struct inet_diag_bc_op *op, int len, | ||
| 524 | int *min_len) | ||
| 525 | { | ||
| 526 | int addr_len; | ||
| 527 | struct inet_diag_hostcond *cond; | ||
| 528 | |||
| 529 | /* Check hostcond space. */ | ||
| 530 | *min_len += sizeof(struct inet_diag_hostcond); | ||
| 531 | if (len < *min_len) | ||
| 532 | return false; | ||
| 533 | cond = (struct inet_diag_hostcond *)(op + 1); | ||
| 534 | |||
| 535 | /* Check address family and address length. */ | ||
| 536 | switch (cond->family) { | ||
| 537 | case AF_UNSPEC: | ||
| 538 | addr_len = 0; | ||
| 539 | break; | ||
| 540 | case AF_INET: | ||
| 541 | addr_len = sizeof(struct in_addr); | ||
| 542 | break; | ||
| 543 | case AF_INET6: | ||
| 544 | addr_len = sizeof(struct in6_addr); | ||
| 545 | break; | ||
| 546 | default: | ||
| 547 | return false; | ||
| 548 | } | ||
| 549 | *min_len += addr_len; | ||
| 550 | if (len < *min_len) | ||
| 551 | return false; | ||
| 552 | |||
| 553 | /* Check prefix length (in bits) vs address length (in bytes). */ | ||
| 554 | if (cond->prefix_len > 8 * addr_len) | ||
| 555 | return false; | ||
| 556 | |||
| 557 | return true; | ||
| 558 | } | ||
| 559 | |||
| 560 | /* Validate a port comparison operator. */ | ||
| 561 | static inline bool valid_port_comparison(const struct inet_diag_bc_op *op, | ||
| 562 | int len, int *min_len) | ||
| 563 | { | ||
| 564 | /* Port comparisons put the port in a follow-on inet_diag_bc_op. */ | ||
| 565 | *min_len += sizeof(struct inet_diag_bc_op); | ||
| 566 | if (len < *min_len) | ||
| 567 | return false; | ||
| 568 | return true; | ||
| 569 | } | ||
| 570 | |||
| 512 | static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) | 571 | static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) |
| 513 | { | 572 | { |
| 514 | const void *bc = bytecode; | 573 | const void *bc = bytecode; |
| @@ -516,29 +575,39 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) | |||
| 516 | 575 | ||
| 517 | while (len > 0) { | 576 | while (len > 0) { |
| 518 | const struct inet_diag_bc_op *op = bc; | 577 | const struct inet_diag_bc_op *op = bc; |
| 578 | int min_len = sizeof(struct inet_diag_bc_op); | ||
| 519 | 579 | ||
| 520 | //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); | 580 | //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); |
| 521 | switch (op->code) { | 581 | switch (op->code) { |
| 522 | case INET_DIAG_BC_AUTO: | ||
| 523 | case INET_DIAG_BC_S_COND: | 582 | case INET_DIAG_BC_S_COND: |
| 524 | case INET_DIAG_BC_D_COND: | 583 | case INET_DIAG_BC_D_COND: |
| 584 | if (!valid_hostcond(bc, len, &min_len)) | ||
| 585 | return -EINVAL; | ||
| 586 | break; | ||
| 525 | case INET_DIAG_BC_S_GE: | 587 | case INET_DIAG_BC_S_GE: |
| 526 | case INET_DIAG_BC_S_LE: | 588 | case INET_DIAG_BC_S_LE: |
| 527 | case INET_DIAG_BC_D_GE: | 589 | case INET_DIAG_BC_D_GE: |
| 528 | case INET_DIAG_BC_D_LE: | 590 | case INET_DIAG_BC_D_LE: |
| 529 | case INET_DIAG_BC_JMP: | 591 | if (!valid_port_comparison(bc, len, &min_len)) |
| 530 | if (op->no < 4 || op->no > len + 4 || op->no & 3) | ||
| 531 | return -EINVAL; | ||
| 532 | if (op->no < len && | ||
| 533 | !valid_cc(bytecode, bytecode_len, len - op->no)) | ||
| 534 | return -EINVAL; | 592 | return -EINVAL; |
| 535 | break; | 593 | break; |
| 594 | case INET_DIAG_BC_AUTO: | ||
| 595 | case INET_DIAG_BC_JMP: | ||
| 536 | case INET_DIAG_BC_NOP: | 596 | case INET_DIAG_BC_NOP: |
| 537 | break; | 597 | break; |
| 538 | default: | 598 | default: |
| 539 | return -EINVAL; | 599 | return -EINVAL; |
| 540 | } | 600 | } |
| 541 | if (op->yes < 4 || op->yes > len + 4 || op->yes & 3) | 601 | |
| 602 | if (op->code != INET_DIAG_BC_NOP) { | ||
| 603 | if (op->no < min_len || op->no > len + 4 || op->no & 3) | ||
| 604 | return -EINVAL; | ||
| 605 | if (op->no < len && | ||
| 606 | !valid_cc(bytecode, bytecode_len, len - op->no)) | ||
| 607 | return -EINVAL; | ||
| 608 | } | ||
| 609 | |||
| 610 | if (op->yes < min_len || op->yes > len + 4 || op->yes & 3) | ||
| 542 | return -EINVAL; | 611 | return -EINVAL; |
| 543 | bc += op->yes; | 612 | bc += op->yes; |
| 544 | len -= op->yes; | 613 | len -= op->yes; |
| @@ -596,6 +665,36 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | |||
| 596 | cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); | 665 | cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); |
| 597 | } | 666 | } |
| 598 | 667 | ||
| 668 | /* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses | ||
| 669 | * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6. | ||
| 670 | */ | ||
| 671 | static inline void inet_diag_req_addrs(const struct sock *sk, | ||
| 672 | const struct request_sock *req, | ||
| 673 | struct inet_diag_entry *entry) | ||
| 674 | { | ||
| 675 | struct inet_request_sock *ireq = inet_rsk(req); | ||
| 676 | |||
| 677 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 678 | if (sk->sk_family == AF_INET6) { | ||
| 679 | if (req->rsk_ops->family == AF_INET6) { | ||
| 680 | entry->saddr = inet6_rsk(req)->loc_addr.s6_addr32; | ||
| 681 | entry->daddr = inet6_rsk(req)->rmt_addr.s6_addr32; | ||
| 682 | } else if (req->rsk_ops->family == AF_INET) { | ||
| 683 | ipv6_addr_set_v4mapped(ireq->loc_addr, | ||
| 684 | &entry->saddr_storage); | ||
| 685 | ipv6_addr_set_v4mapped(ireq->rmt_addr, | ||
| 686 | &entry->daddr_storage); | ||
| 687 | entry->saddr = entry->saddr_storage.s6_addr32; | ||
| 688 | entry->daddr = entry->daddr_storage.s6_addr32; | ||
| 689 | } | ||
| 690 | } else | ||
| 691 | #endif | ||
| 692 | { | ||
| 693 | entry->saddr = &ireq->loc_addr; | ||
| 694 | entry->daddr = &ireq->rmt_addr; | ||
| 695 | } | ||
| 696 | } | ||
| 697 | |||
| 599 | static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | 698 | static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, |
| 600 | struct request_sock *req, | 699 | struct request_sock *req, |
| 601 | struct user_namespace *user_ns, | 700 | struct user_namespace *user_ns, |
| @@ -637,8 +736,10 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
| 637 | r->idiag_inode = 0; | 736 | r->idiag_inode = 0; |
| 638 | #if IS_ENABLED(CONFIG_IPV6) | 737 | #if IS_ENABLED(CONFIG_IPV6) |
| 639 | if (r->idiag_family == AF_INET6) { | 738 | if (r->idiag_family == AF_INET6) { |
| 640 | *(struct in6_addr *)r->id.idiag_src = inet6_rsk(req)->loc_addr; | 739 | struct inet_diag_entry entry; |
| 641 | *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr; | 740 | inet_diag_req_addrs(sk, req, &entry); |
| 741 | memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr)); | ||
| 742 | memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr)); | ||
| 642 | } | 743 | } |
| 643 | #endif | 744 | #endif |
| 644 | 745 | ||
| @@ -691,18 +792,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
| 691 | continue; | 792 | continue; |
| 692 | 793 | ||
| 693 | if (bc) { | 794 | if (bc) { |
| 694 | entry.saddr = | 795 | inet_diag_req_addrs(sk, req, &entry); |
| 695 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 696 | (entry.family == AF_INET6) ? | ||
| 697 | inet6_rsk(req)->loc_addr.s6_addr32 : | ||
| 698 | #endif | ||
| 699 | &ireq->loc_addr; | ||
| 700 | entry.daddr = | ||
| 701 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 702 | (entry.family == AF_INET6) ? | ||
| 703 | inet6_rsk(req)->rmt_addr.s6_addr32 : | ||
| 704 | #endif | ||
| 705 | &ireq->rmt_addr; | ||
| 706 | entry.dport = ntohs(ireq->rmt_port); | 796 | entry.dport = ntohs(ireq->rmt_port); |
| 707 | 797 | ||
| 708 | if (!inet_diag_bc_run(bc, &entry)) | 798 | if (!inet_diag_bc_run(bc, &entry)) |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 448e68546827..8d5cc75dac88 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -707,28 +707,27 @@ EXPORT_SYMBOL(ip_defrag); | |||
| 707 | 707 | ||
| 708 | struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) | 708 | struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) |
| 709 | { | 709 | { |
| 710 | const struct iphdr *iph; | 710 | struct iphdr iph; |
| 711 | u32 len; | 711 | u32 len; |
| 712 | 712 | ||
| 713 | if (skb->protocol != htons(ETH_P_IP)) | 713 | if (skb->protocol != htons(ETH_P_IP)) |
| 714 | return skb; | 714 | return skb; |
| 715 | 715 | ||
| 716 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | 716 | if (!skb_copy_bits(skb, 0, &iph, sizeof(iph))) |
| 717 | return skb; | 717 | return skb; |
| 718 | 718 | ||
| 719 | iph = ip_hdr(skb); | 719 | if (iph.ihl < 5 || iph.version != 4) |
| 720 | if (iph->ihl < 5 || iph->version != 4) | ||
| 721 | return skb; | 720 | return skb; |
| 722 | if (!pskb_may_pull(skb, iph->ihl*4)) | 721 | |
| 723 | return skb; | 722 | len = ntohs(iph.tot_len); |
| 724 | iph = ip_hdr(skb); | 723 | if (skb->len < len || len < (iph.ihl * 4)) |
| 725 | len = ntohs(iph->tot_len); | ||
| 726 | if (skb->len < len || len < (iph->ihl * 4)) | ||
| 727 | return skb; | 724 | return skb; |
| 728 | 725 | ||
| 729 | if (ip_is_fragment(ip_hdr(skb))) { | 726 | if (ip_is_fragment(&iph)) { |
| 730 | skb = skb_share_check(skb, GFP_ATOMIC); | 727 | skb = skb_share_check(skb, GFP_ATOMIC); |
| 731 | if (skb) { | 728 | if (skb) { |
| 729 | if (!pskb_may_pull(skb, iph.ihl*4)) | ||
| 730 | return skb; | ||
| 732 | if (pskb_trim_rcsum(skb, len)) | 731 | if (pskb_trim_rcsum(skb, len)) |
| 733 | return skb; | 732 | return skb; |
| 734 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | 733 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 6168c4dc58b1..3eab2b2ffd34 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -1318,6 +1318,10 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
| 1318 | if (get_user(v, (u32 __user *)optval)) | 1318 | if (get_user(v, (u32 __user *)optval)) |
| 1319 | return -EFAULT; | 1319 | return -EFAULT; |
| 1320 | 1320 | ||
| 1321 | /* "pimreg%u" should not exceed 16 bytes (IFNAMSIZ) */ | ||
| 1322 | if (v != RT_TABLE_DEFAULT && v >= 1000000000) | ||
| 1323 | return -EINVAL; | ||
| 1324 | |||
| 1321 | rtnl_lock(); | 1325 | rtnl_lock(); |
| 1322 | ret = 0; | 1326 | ret = 0; |
| 1323 | if (sk == rtnl_dereference(mrt->mroute_sk)) { | 1327 | if (sk == rtnl_dereference(mrt->mroute_sk)) { |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 083092e3aed6..e457c7ab2e28 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -830,8 +830,8 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags) | |||
| 830 | return mss_now; | 830 | return mss_now; |
| 831 | } | 831 | } |
| 832 | 832 | ||
| 833 | static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, | 833 | static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, |
| 834 | size_t psize, int flags) | 834 | size_t size, int flags) |
| 835 | { | 835 | { |
| 836 | struct tcp_sock *tp = tcp_sk(sk); | 836 | struct tcp_sock *tp = tcp_sk(sk); |
| 837 | int mss_now, size_goal; | 837 | int mss_now, size_goal; |
| @@ -858,12 +858,9 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse | |||
| 858 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 858 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) |
| 859 | goto out_err; | 859 | goto out_err; |
| 860 | 860 | ||
| 861 | while (psize > 0) { | 861 | while (size > 0) { |
| 862 | struct sk_buff *skb = tcp_write_queue_tail(sk); | 862 | struct sk_buff *skb = tcp_write_queue_tail(sk); |
| 863 | struct page *page = pages[poffset / PAGE_SIZE]; | ||
| 864 | int copy, i; | 863 | int copy, i; |
| 865 | int offset = poffset % PAGE_SIZE; | ||
| 866 | int size = min_t(size_t, psize, PAGE_SIZE - offset); | ||
| 867 | bool can_coalesce; | 864 | bool can_coalesce; |
| 868 | 865 | ||
| 869 | if (!tcp_send_head(sk) || (copy = size_goal - skb->len) <= 0) { | 866 | if (!tcp_send_head(sk) || (copy = size_goal - skb->len) <= 0) { |
| @@ -912,8 +909,8 @@ new_segment: | |||
| 912 | TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; | 909 | TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; |
| 913 | 910 | ||
| 914 | copied += copy; | 911 | copied += copy; |
| 915 | poffset += copy; | 912 | offset += copy; |
| 916 | if (!(psize -= copy)) | 913 | if (!(size -= copy)) |
| 917 | goto out; | 914 | goto out; |
| 918 | 915 | ||
| 919 | if (skb->len < size_goal || (flags & MSG_OOB)) | 916 | if (skb->len < size_goal || (flags & MSG_OOB)) |
| @@ -960,7 +957,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset, | |||
| 960 | flags); | 957 | flags); |
| 961 | 958 | ||
| 962 | lock_sock(sk); | 959 | lock_sock(sk); |
| 963 | res = do_tcp_sendpages(sk, &page, offset, size, flags); | 960 | res = do_tcp_sendpages(sk, page, offset, size, flags); |
| 964 | release_sock(sk); | 961 | release_sock(sk); |
| 965 | return res; | 962 | return res; |
| 966 | } | 963 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 609ff98aeb47..181fc8234a52 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -5645,7 +5645,11 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
| 5645 | tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); | 5645 | tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); |
| 5646 | 5646 | ||
| 5647 | if (data) { /* Retransmit unacked data in SYN */ | 5647 | if (data) { /* Retransmit unacked data in SYN */ |
| 5648 | tcp_retransmit_skb(sk, data); | 5648 | tcp_for_write_queue_from(data, sk) { |
| 5649 | if (data == tcp_send_head(sk) || | ||
| 5650 | __tcp_retransmit_skb(sk, data)) | ||
| 5651 | break; | ||
| 5652 | } | ||
| 5649 | tcp_rearm_rto(sk); | 5653 | tcp_rearm_rto(sk); |
| 5650 | return true; | 5654 | return true; |
| 5651 | } | 5655 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 2798706cb063..948ac275b9b5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -2309,12 +2309,11 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to, | |||
| 2309 | * state updates are done by the caller. Returns non-zero if an | 2309 | * state updates are done by the caller. Returns non-zero if an |
| 2310 | * error occurred which prevented the send. | 2310 | * error occurred which prevented the send. |
| 2311 | */ | 2311 | */ |
| 2312 | int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | 2312 | int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) |
| 2313 | { | 2313 | { |
| 2314 | struct tcp_sock *tp = tcp_sk(sk); | 2314 | struct tcp_sock *tp = tcp_sk(sk); |
| 2315 | struct inet_connection_sock *icsk = inet_csk(sk); | 2315 | struct inet_connection_sock *icsk = inet_csk(sk); |
| 2316 | unsigned int cur_mss; | 2316 | unsigned int cur_mss; |
| 2317 | int err; | ||
| 2318 | 2317 | ||
| 2319 | /* Inconslusive MTU probe */ | 2318 | /* Inconslusive MTU probe */ |
| 2320 | if (icsk->icsk_mtup.probe_size) { | 2319 | if (icsk->icsk_mtup.probe_size) { |
| @@ -2387,11 +2386,17 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
| 2387 | if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { | 2386 | if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { |
| 2388 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, | 2387 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, |
| 2389 | GFP_ATOMIC); | 2388 | GFP_ATOMIC); |
| 2390 | err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : | 2389 | return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : |
| 2391 | -ENOBUFS; | 2390 | -ENOBUFS; |
| 2392 | } else { | 2391 | } else { |
| 2393 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); | 2392 | return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); |
| 2394 | } | 2393 | } |
| 2394 | } | ||
| 2395 | |||
| 2396 | int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | ||
| 2397 | { | ||
| 2398 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 2399 | int err = __tcp_retransmit_skb(sk, skb); | ||
| 2395 | 2400 | ||
| 2396 | if (err == 0) { | 2401 | if (err == 0) { |
| 2397 | /* Update global TCP statistics. */ | 2402 | /* Update global TCP statistics. */ |
diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 1002e3396f72..ae43c62f9045 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c | |||
| @@ -441,6 +441,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) | |||
| 441 | lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0); | 441 | lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0); |
| 442 | if (lsap == NULL) { | 442 | if (lsap == NULL) { |
| 443 | IRDA_DEBUG(0, "%s: unable to allocate LSAP!!\n", __func__); | 443 | IRDA_DEBUG(0, "%s: unable to allocate LSAP!!\n", __func__); |
| 444 | __irttp_close_tsap(self); | ||
| 444 | return NULL; | 445 | return NULL; |
| 445 | } | 446 | } |
| 446 | 447 | ||
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 83608ac16780..2c84185dfdb0 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
| @@ -458,8 +458,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) | |||
| 458 | list_move_tail(&roc->list, &tmp_list); | 458 | list_move_tail(&roc->list, &tmp_list); |
| 459 | roc->abort = true; | 459 | roc->abort = true; |
| 460 | } | 460 | } |
| 461 | |||
| 462 | ieee80211_start_next_roc(local); | ||
| 463 | mutex_unlock(&local->mtx); | 461 | mutex_unlock(&local->mtx); |
| 464 | 462 | ||
| 465 | list_for_each_entry_safe(roc, tmp, &tmp_list, list) { | 463 | list_for_each_entry_safe(roc, tmp, &tmp_list, list) { |
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index b9a63381e349..45a101439bc5 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c | |||
| @@ -793,7 +793,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = { | |||
| 793 | [IPSET_ATTR_IP] = { .type = NLA_NESTED }, | 793 | [IPSET_ATTR_IP] = { .type = NLA_NESTED }, |
| 794 | [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, | 794 | [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, |
| 795 | [IPSET_ATTR_IFACE] = { .type = NLA_NUL_STRING, | 795 | [IPSET_ATTR_IFACE] = { .type = NLA_NUL_STRING, |
| 796 | .len = IPSET_MAXNAMELEN - 1 }, | 796 | .len = IFNAMSIZ - 1 }, |
| 797 | [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, | 797 | [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, |
| 798 | [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, | 798 | [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, |
| 799 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, | 799 | [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 98c70630ad06..733cbf49ed1f 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
| @@ -702,15 +702,11 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, | |||
| 702 | /* We only match on the lower 8 bits of the opcode. */ | 702 | /* We only match on the lower 8 bits of the opcode. */ |
| 703 | if (ntohs(arp->ar_op) <= 0xff) | 703 | if (ntohs(arp->ar_op) <= 0xff) |
| 704 | key->ip.proto = ntohs(arp->ar_op); | 704 | key->ip.proto = ntohs(arp->ar_op); |
| 705 | 705 | memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); | |
| 706 | if (key->ip.proto == ARPOP_REQUEST | 706 | memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); |
| 707 | || key->ip.proto == ARPOP_REPLY) { | 707 | memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); |
| 708 | memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); | 708 | memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); |
| 709 | memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); | 709 | key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); |
| 710 | memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); | ||
| 711 | memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); | ||
| 712 | key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); | ||
| 713 | } | ||
| 714 | } | 710 | } |
| 715 | } else if (key->eth.type == htons(ETH_P_IPV6)) { | 711 | } else if (key->eth.type == htons(ETH_P_IPV6)) { |
| 716 | int nh_len; /* IPv6 Header + Extensions */ | 712 | int nh_len; /* IPv6 Header + Extensions */ |
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 3c1e58ba714b..a9033481fa5e 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c | |||
| @@ -158,7 +158,7 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) | |||
| 158 | 158 | ||
| 159 | if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { | 159 | if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { |
| 160 | net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", | 160 | net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", |
| 161 | ovs_dp_name(vport->dp), | 161 | netdev_vport->dev->name, |
| 162 | packet_length(skb), mtu); | 162 | packet_length(skb), mtu); |
| 163 | goto error; | 163 | goto error; |
| 164 | } | 164 | } |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 7c2df9c33df3..69ce21e3716f 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
| @@ -183,7 +183,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
| 183 | 183 | ||
| 184 | msg = sctp_datamsg_new(GFP_KERNEL); | 184 | msg = sctp_datamsg_new(GFP_KERNEL); |
| 185 | if (!msg) | 185 | if (!msg) |
| 186 | return NULL; | 186 | return ERR_PTR(-ENOMEM); |
| 187 | 187 | ||
| 188 | /* Note: Calculate this outside of the loop, so that all fragments | 188 | /* Note: Calculate this outside of the loop, so that all fragments |
| 189 | * have the same expiration. | 189 | * have the same expiration. |
| @@ -280,11 +280,14 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
| 280 | 280 | ||
| 281 | chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0); | 281 | chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0); |
| 282 | 282 | ||
| 283 | if (!chunk) | 283 | if (!chunk) { |
| 284 | err = -ENOMEM; | ||
| 284 | goto errout; | 285 | goto errout; |
| 286 | } | ||
| 287 | |||
| 285 | err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); | 288 | err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); |
| 286 | if (err < 0) | 289 | if (err < 0) |
| 287 | goto errout; | 290 | goto errout_chunk_free; |
| 288 | 291 | ||
| 289 | offset += len; | 292 | offset += len; |
| 290 | 293 | ||
| @@ -315,8 +318,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
| 315 | 318 | ||
| 316 | chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0); | 319 | chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0); |
| 317 | 320 | ||
| 318 | if (!chunk) | 321 | if (!chunk) { |
| 322 | err = -ENOMEM; | ||
| 319 | goto errout; | 323 | goto errout; |
| 324 | } | ||
| 320 | 325 | ||
| 321 | err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov); | 326 | err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov); |
| 322 | 327 | ||
| @@ -324,7 +329,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
| 324 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr | 329 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr |
| 325 | - (__u8 *)chunk->skb->data); | 330 | - (__u8 *)chunk->skb->data); |
| 326 | if (err < 0) | 331 | if (err < 0) |
| 327 | goto errout; | 332 | goto errout_chunk_free; |
| 328 | 333 | ||
| 329 | sctp_datamsg_assign(msg, chunk); | 334 | sctp_datamsg_assign(msg, chunk); |
| 330 | list_add_tail(&chunk->frag_list, &msg->chunks); | 335 | list_add_tail(&chunk->frag_list, &msg->chunks); |
| @@ -332,6 +337,9 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
| 332 | 337 | ||
| 333 | return msg; | 338 | return msg; |
| 334 | 339 | ||
| 340 | errout_chunk_free: | ||
| 341 | sctp_chunk_free(chunk); | ||
| 342 | |||
| 335 | errout: | 343 | errout: |
| 336 | list_for_each_safe(pos, temp, &msg->chunks) { | 344 | list_for_each_safe(pos, temp, &msg->chunks) { |
| 337 | list_del_init(pos); | 345 | list_del_init(pos); |
| @@ -339,7 +347,7 @@ errout: | |||
| 339 | sctp_chunk_free(chunk); | 347 | sctp_chunk_free(chunk); |
| 340 | } | 348 | } |
| 341 | sctp_datamsg_put(msg); | 349 | sctp_datamsg_put(msg); |
| 342 | return NULL; | 350 | return ERR_PTR(err); |
| 343 | } | 351 | } |
| 344 | 352 | ||
| 345 | /* Check whether this message has expired. */ | 353 | /* Check whether this message has expired. */ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a60d1f8b41c5..406d957d08fb 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -1915,8 +1915,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1915 | 1915 | ||
| 1916 | /* Break the message into multiple chunks of maximum size. */ | 1916 | /* Break the message into multiple chunks of maximum size. */ |
| 1917 | datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); | 1917 | datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); |
| 1918 | if (!datamsg) { | 1918 | if (IS_ERR(datamsg)) { |
| 1919 | err = -ENOMEM; | 1919 | err = PTR_ERR(datamsg); |
| 1920 | goto out_free; | 1920 | goto out_free; |
| 1921 | } | 1921 | } |
| 1922 | 1922 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 953c21e4af97..206cf5238fd3 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -331,7 +331,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) | |||
| 331 | * 1/8, rto_alpha would be expressed as 3. | 331 | * 1/8, rto_alpha would be expressed as 3. |
| 332 | */ | 332 | */ |
| 333 | tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) | 333 | tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) |
| 334 | + ((abs(tp->srtt - rtt)) >> net->sctp.rto_beta); | 334 | + (((__u32)abs64((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta); |
| 335 | tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) | 335 | tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) |
| 336 | + (rtt >> net->sctp.rto_alpha); | 336 | + (rtt >> net->sctp.rto_alpha); |
| 337 | } else { | 337 | } else { |
