From: Greg Kroah-Hartman Date: Fri, 7 Nov 2014 19:51:16 +0000 (-0800) Subject: 3.17-stable patches X-Git-Tag: v3.10.60~80 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=79f6993b088a690c8de050f143992b23af2fcf87;p=thirdparty%2Fkernel%2Fstable-queue.git 3.17-stable patches added patches: ax88179_178a-fix-bonding-failure.patch cxgb4-fix-missing-initialization-of-win0_lock.patch drivers-net-disable-ufo-through-virtio.patch drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch drivers-net-macvtap-and-tun-depend-on-inet.patch gre-use-inner-mac-length-when-computing-tunnel-length.patch hyperv-fix-the-total_data_buflen-in-send-path.patch ipv4-do-not-cache-routing-failures-due-to-disabled-forwarding.patch ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch macvlan-fix-a-race-on-port-dismantle-and-possible-skb-leaks.patch mlx4-avoid-leaking-steering-rules-on-flow-creation-error-flow.patch net-fix-saving-tx-flow-hash-in-sock-for-outgoing-connections.patch net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch net-tso-fix-unaligned-access-to-crafted-tcp-header-in-helper-api.patch netlink-re-add-locking-to-netlink_lookup-and-seq-walker.patch stmmac-pci-set-default-of-the-filter-bins.patch tcp-md5-do-not-use-alloc_percpu.patch tipc-fix-bug-in-bundled-buffer-reception.patch vxlan-fix-a-free-after-use.patch vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch vxlan-using-pskb_may_pull-as-early-as-possible.patch x86-bpf_jit-fix-two-bugs-in-ebpf-jit-compiler.patch --- diff --git a/queue-3.17/ax88179_178a-fix-bonding-failure.patch b/queue-3.17/ax88179_178a-fix-bonding-failure.patch new file mode 100644 index 00000000000..436917d960f --- /dev/null +++ b/queue-3.17/ax88179_178a-fix-bonding-failure.patch @@ -0,0 +1,59 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Ian Morgan +Date: Sun, 19 Oct 2014 08:05:13 -0400 +Subject: ax88179_178a: fix bonding failure + +From: Ian Morgan + +[ Upstream commit 95ff88688781db2f64042e69bd499e518bbb36e5 ] + +The following patch fixes a bug which causes the ax88179_178a driver to be +incapable of being added to a bond. + +When I brought up the issue with the bonding maintainers, they indicated +that the real problem was with the NIC driver which must return zero for +success (of setting the MAC address). I see that several other NIC drivers +follow that pattern by either simply always returing zero, or by passing +through a negative (error) result while rewriting any positive return code +to zero. With that same philisophy applied to the ax88179_178a driver, it +allows it to work correctly with the bonding driver. + +I believe this is suitable for queuing in -stable, as it's a small, simple, +and obvious fix that corrects a defect with no other known workaround. + +This patch is against vanilla 3.17(.0). + +Signed-off-by: Ian Morgan + + drivers/net/usb/ax88179_178a.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/ax88179_178a.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/usb/ax88179_178a.c ++++ b/drivers/net/usb/ax88179_178a.c +@@ -937,6 +937,7 @@ static int ax88179_set_mac_addr(struct n + { + struct usbnet *dev = netdev_priv(net); + struct sockaddr *addr = p; ++ int ret; + + if (netif_running(net)) + return -EBUSY; +@@ -946,8 +947,12 @@ static int ax88179_set_mac_addr(struct n + memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); + + /* Set the MAC address */ +- return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ++ ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, + ETH_ALEN, net->dev_addr); ++ if (ret < 0) ++ return ret; ++ ++ return 0; + } + + static const struct net_device_ops ax88179_netdev_ops = { diff --git a/queue-3.17/cxgb4-fix-missing-initialization-of-win0_lock.patch b/queue-3.17/cxgb4-fix-missing-initialization-of-win0_lock.patch new file mode 100644 index 00000000000..2bc21ce872c --- /dev/null +++ b/queue-3.17/cxgb4-fix-missing-initialization-of-win0_lock.patch @@ -0,0 +1,33 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Anish Bhatt +Date: Wed, 29 Oct 2014 17:54:03 -0700 +Subject: cxgb4 : Fix missing initialization of win0_lock + +From: Anish Bhatt + +[ Upstream commit e327c225c911529898ec300cb96d2088893de3df ] + +win0_lock was being used un-initialized, resulting in warning traces +being seen when lock debugging is enabled (and just wrong) + +Fixes : fc5ab0209650 ('cxgb4: Replaced the backdoor mechanism to access the HW + memory with PCIe Window method') + +Signed-off-by: Anish Bhatt +Signed-off-by: Casey Leedom +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -6557,6 +6557,7 @@ static int init_one(struct pci_dev *pdev + + spin_lock_init(&adapter->stats_lock); + spin_lock_init(&adapter->tid_release_lock); ++ spin_lock_init(&adapter->win0_lock); + + INIT_WORK(&adapter->tid_release_task, process_tid_release_list); + INIT_WORK(&adapter->db_full_task, process_db_full); diff --git a/queue-3.17/drivers-net-disable-ufo-through-virtio.patch b/queue-3.17/drivers-net-disable-ufo-through-virtio.patch new file mode 100644 index 00000000000..39a354b8e2b --- /dev/null +++ b/queue-3.17/drivers-net-disable-ufo-through-virtio.patch @@ -0,0 +1,217 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Ben Hutchings +Date: Thu, 30 Oct 2014 18:27:12 +0000 +Subject: drivers/net: Disable UFO through virtio + +From: Ben Hutchings + +[ Upstream commit 3d0ad09412ffe00c9afa201d01effdb6023d09b4 ] + +IPv6 does not allow fragmentation by routers, so there is no +fragmentation ID in the fixed header. UFO for IPv6 requires the ID to +be passed separately, but there is no provision for this in the virtio +net protocol. + +Until recently our software implementation of UFO/IPv6 generated a new +ID, but this was a bug. Now we will use ID=0 for any UFO/IPv6 packet +passed through a tap, which is even worse. + +Unfortunately there is no distinction between UFO/IPv4 and v6 +features, so disable UFO on taps and virtio_net completely until we +have a proper solution. + +We cannot depend on VM managers respecting the tap feature flags, so +keep accepting UFO packets but log a warning the first time we do +this. + +Signed-off-by: Ben Hutchings +Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data") +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvtap.c | 13 +++++-------- + drivers/net/tun.c | 19 +++++++++++-------- + drivers/net/virtio_net.c | 24 ++++++++++++++---------- + 3 files changed, 30 insertions(+), 26 deletions(-) + +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -65,7 +65,7 @@ static struct cdev macvtap_cdev; + static const struct proto_ops macvtap_socket_ops; + + #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ +- NETIF_F_TSO6 | NETIF_F_UFO) ++ NETIF_F_TSO6) + #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) + #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG) + +@@ -569,6 +569,8 @@ static int macvtap_skb_from_vnet_hdr(str + gso_type = SKB_GSO_TCPV6; + break; + case VIRTIO_NET_HDR_GSO_UDP: ++ pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n", ++ current->comm); + gso_type = SKB_GSO_UDP; + break; + default: +@@ -614,8 +616,6 @@ static void macvtap_skb_to_vnet_hdr(cons + vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (sinfo->gso_type & SKB_GSO_TCPV6) + vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; +- else if (sinfo->gso_type & SKB_GSO_UDP) +- vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; + else + BUG(); + if (sinfo->gso_type & SKB_GSO_TCP_ECN) +@@ -950,9 +950,6 @@ static int set_offload(struct macvtap_qu + if (arg & TUN_F_TSO6) + feature_mask |= NETIF_F_TSO6; + } +- +- if (arg & TUN_F_UFO) +- feature_mask |= NETIF_F_UFO; + } + + /* tun/tap driver inverts the usage for TSO offloads, where +@@ -963,7 +960,7 @@ static int set_offload(struct macvtap_qu + * When user space turns off TSO, we turn off GSO/LRO so that + * user-space will not receive TSO frames. + */ +- if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO)) ++ if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6)) + features |= RX_OFFLOADS; + else + features &= ~RX_OFFLOADS; +@@ -1064,7 +1061,7 @@ static long macvtap_ioctl(struct file *f + case TUNSETOFFLOAD: + /* let the user check for future flags */ + if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | +- TUN_F_TSO_ECN | TUN_F_UFO)) ++ TUN_F_TSO_ECN)) + return -EINVAL; + + rtnl_lock(); +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -174,7 +174,7 @@ struct tun_struct { + struct net_device *dev; + netdev_features_t set_features; + #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ +- NETIF_F_TSO6|NETIF_F_UFO) ++ NETIF_F_TSO6) + + int vnet_hdr_sz; + int sndbuf; +@@ -1149,8 +1149,18 @@ static ssize_t tun_get_user(struct tun_s + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; + break; + case VIRTIO_NET_HDR_GSO_UDP: ++ { ++ static bool warned; ++ ++ if (!warned) { ++ warned = true; ++ netdev_warn(tun->dev, ++ "%s: using disabled UFO feature; please fix this program\n", ++ current->comm); ++ } + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + break; ++ } + default: + tun->dev->stats.rx_frame_errors++; + kfree_skb(skb); +@@ -1251,8 +1261,6 @@ static ssize_t tun_put_user(struct tun_s + gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (sinfo->gso_type & SKB_GSO_TCPV6) + gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; +- else if (sinfo->gso_type & SKB_GSO_UDP) +- gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; + else { + pr_err("unexpected GSO type: " + "0x%x, gso_size %d, hdr_len %d\n", +@@ -1762,11 +1770,6 @@ static int set_offload(struct tun_struct + features |= NETIF_F_TSO6; + arg &= ~(TUN_F_TSO4|TUN_F_TSO6); + } +- +- if (arg & TUN_F_UFO) { +- features |= NETIF_F_UFO; +- arg &= ~TUN_F_UFO; +- } + } + + /* This gives the user a way to test for new features in future by +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -497,8 +497,17 @@ static void receive_buf(struct receive_q + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; + break; + case VIRTIO_NET_HDR_GSO_UDP: ++ { ++ static bool warned; ++ ++ if (!warned) { ++ warned = true; ++ netdev_warn(dev, ++ "host using disabled UFO feature; please fix it\n"); ++ } + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + break; ++ } + case VIRTIO_NET_HDR_GSO_TCPV6: + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; + break; +@@ -885,8 +894,6 @@ static int xmit_skb(struct send_queue *s + hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; +- else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) +- hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP; + else + BUG(); + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN) +@@ -1710,7 +1717,7 @@ static int virtnet_probe(struct virtio_d + dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; + + if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { +- dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO ++ dev->hw_features |= NETIF_F_TSO + | NETIF_F_TSO_ECN | NETIF_F_TSO6; + } + /* Individual feature bits: what can host handle? */ +@@ -1720,11 +1727,9 @@ static int virtnet_probe(struct virtio_d + dev->hw_features |= NETIF_F_TSO6; + if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) + dev->hw_features |= NETIF_F_TSO_ECN; +- if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) +- dev->hw_features |= NETIF_F_UFO; + + if (gso) +- dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO); ++ dev->features |= dev->hw_features & NETIF_F_ALL_TSO; + /* (!csum && gso) case will be fixed by register_netdev() */ + } + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) +@@ -1764,8 +1769,7 @@ static int virtnet_probe(struct virtio_d + /* If we can receive ANY GSO packets, we must allocate large ones. */ + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) || +- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) || +- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO)) ++ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) + vi->big_packets = true; + + if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) +@@ -1965,9 +1969,9 @@ static struct virtio_device_id id_table[ + static unsigned int features[] = { + VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, + VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, +- VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, ++ VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6, + VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, +- VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, ++ VIRTIO_NET_F_GUEST_ECN, + VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, + VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, + VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, diff --git a/queue-3.17/drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch b/queue-3.17/drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch new file mode 100644 index 00000000000..279d91d05bf --- /dev/null +++ b/queue-3.17/drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch @@ -0,0 +1,139 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Ben Hutchings +Date: Thu, 30 Oct 2014 18:27:17 +0000 +Subject: drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets + +From: Ben Hutchings + +[ Upstream commit 5188cd44c55db3e92cd9e77a40b5baa7ed4340f7 ] + +UFO is now disabled on all drivers that work with virtio net headers, +but userland may try to send UFO/IPv6 packets anyway. Instead of +sending with ID=0, we should select identifiers on their behalf (as we +used to). + +Signed-off-by: Ben Hutchings +Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data") +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvtap.c | 3 +++ + drivers/net/tun.c | 6 +++++- + include/net/ipv6.h | 2 ++ + net/ipv6/output_core.c | 34 ++++++++++++++++++++++++++++++++++ + 4 files changed, 44 insertions(+), 1 deletion(-) + +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -16,6 +16,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -572,6 +573,8 @@ static int macvtap_skb_from_vnet_hdr(str + pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n", + current->comm); + gso_type = SKB_GSO_UDP; ++ if (skb->protocol == htons(ETH_P_IPV6)) ++ ipv6_proxy_select_ident(skb); + break; + default: + return -EINVAL; +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -65,6 +65,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1139,6 +1140,8 @@ static ssize_t tun_get_user(struct tun_s + break; + } + ++ skb_reset_network_header(skb); ++ + if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { + pr_debug("GSO!\n"); + switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { +@@ -1159,6 +1162,8 @@ static ssize_t tun_get_user(struct tun_s + current->comm); + } + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; ++ if (skb->protocol == htons(ETH_P_IPV6)) ++ ipv6_proxy_select_ident(skb); + break; + } + default: +@@ -1189,7 +1194,6 @@ static ssize_t tun_get_user(struct tun_s + skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; + } + +- skb_reset_network_header(skb); + skb_probe_transport_header(skb, 0); + + rxhash = skb_get_hash(skb); +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -669,6 +669,8 @@ static inline int ipv6_addr_diff(const s + return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); + } + ++void ipv6_proxy_select_ident(struct sk_buff *skb); ++ + int ip6_dst_hoplimit(struct dst_entry *dst); + + static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6, +--- a/net/ipv6/output_core.c ++++ b/net/ipv6/output_core.c +@@ -3,11 +3,45 @@ + * not configured or static. These functions are needed by GSO/GRO implementation. + */ + #include ++#include + #include + #include + #include + #include + ++/* This function exists only for tap drivers that must support broken ++ * clients requesting UFO without specifying an IPv6 fragment ID. ++ * ++ * This is similar to ipv6_select_ident() but we use an independent hash ++ * seed to limit information leakage. ++ * ++ * The network header must be set before calling this. ++ */ ++void ipv6_proxy_select_ident(struct sk_buff *skb) ++{ ++ static u32 ip6_proxy_idents_hashrnd __read_mostly; ++ struct in6_addr buf[2]; ++ struct in6_addr *addrs; ++ u32 hash, id; ++ ++ addrs = skb_header_pointer(skb, ++ skb_network_offset(skb) + ++ offsetof(struct ipv6hdr, saddr), ++ sizeof(buf), buf); ++ if (!addrs) ++ return; ++ ++ net_get_random_once(&ip6_proxy_idents_hashrnd, ++ sizeof(ip6_proxy_idents_hashrnd)); ++ ++ hash = __ipv6_addr_jhash(&addrs[1], ip6_proxy_idents_hashrnd); ++ hash = __ipv6_addr_jhash(&addrs[0], hash); ++ ++ id = ip_idents_reserve(hash, 1); ++ skb_shinfo(skb)->ip6_frag_id = htonl(id); ++} ++EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); ++ + int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) + { + u16 offset = sizeof(struct ipv6hdr); diff --git a/queue-3.17/drivers-net-macvtap-and-tun-depend-on-inet.patch b/queue-3.17/drivers-net-macvtap-and-tun-depend-on-inet.patch new file mode 100644 index 00000000000..828f4a72858 --- /dev/null +++ b/queue-3.17/drivers-net-macvtap-and-tun-depend-on-inet.patch @@ -0,0 +1,43 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Ben Hutchings +Date: Fri, 31 Oct 2014 03:10:31 +0000 +Subject: drivers/net: macvtap and tun depend on INET + +From: Ben Hutchings + +[ Upstream commit de11b0e8c569b96c2cf6a811e3805b7aeef498a3 ] + +These drivers now call ipv6_proxy_select_ident(), which is defined +only if CONFIG_INET is enabled. However, they have really depended +on CONFIG_INET for as long as they have allowed sending GSO packets +from userland. + +Reported-by: kbuild test robot +Signed-off-by: Ben Hutchings +Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr") +Fixes: b9fb9ee07e67 ("macvtap: add GSO/csum offload support") +Fixes: 5188cd44c55d ("drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets") +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/Kconfig | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -135,6 +135,7 @@ config MACVLAN + config MACVTAP + tristate "MAC-VLAN based tap driver" + depends on MACVLAN ++ depends on INET + help + This adds a specialized tap character device driver that is based + on the MAC-VLAN network interface, called macvtap. A macvtap device +@@ -201,6 +202,7 @@ config RIONET_RX_SIZE + + config TUN + tristate "Universal TUN/TAP device driver support" ++ depends on INET + select CRC32 + ---help--- + TUN/TAP provides packet reception and transmission for user space diff --git a/queue-3.17/gre-use-inner-mac-length-when-computing-tunnel-length.patch b/queue-3.17/gre-use-inner-mac-length-when-computing-tunnel-length.patch new file mode 100644 index 00000000000..17186995688 --- /dev/null +++ b/queue-3.17/gre-use-inner-mac-length-when-computing-tunnel-length.patch @@ -0,0 +1,35 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Tom Herbert +Date: Thu, 30 Oct 2014 08:40:56 -0700 +Subject: gre: Use inner mac length when computing tunnel length + +From: Tom Herbert + +[ Upstream commit 14051f0452a2c26a3f4791e6ad6a435e8f1945ff ] + +Currently, skb_inner_network_header is used but this does not account +for Ethernet header for ETH_P_TEB. Use skb_inner_mac_header which +handles TEB and also should work with IP encapsulation in which case +inner mac and inner network headers are the same. + +Tested: Ran TCP_STREAM over GRE, worked as expected. + +Signed-off-by: Tom Herbert +Acked-by: Alexander Duyck +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/gre_offload.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/gre_offload.c ++++ b/net/ipv4/gre_offload.c +@@ -51,7 +51,7 @@ static struct sk_buff *gre_gso_segment(s + + greh = (struct gre_base_hdr *)skb_transport_header(skb); + +- ghl = skb_inner_network_header(skb) - skb_transport_header(skb); ++ ghl = skb_inner_mac_header(skb) - skb_transport_header(skb); + if (unlikely(ghl < sizeof(*greh))) + goto out; + diff --git a/queue-3.17/hyperv-fix-the-total_data_buflen-in-send-path.patch b/queue-3.17/hyperv-fix-the-total_data_buflen-in-send-path.patch new file mode 100644 index 00000000000..59c8a70ba5a --- /dev/null +++ b/queue-3.17/hyperv-fix-the-total_data_buflen-in-send-path.patch @@ -0,0 +1,34 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Haiyang Zhang +Date: Wed, 22 Oct 2014 13:47:18 -0700 +Subject: hyperv: Fix the total_data_buflen in send path + +From: Haiyang Zhang + +[ Upstream commit 942396b01989d54977120f3625e5ba31afe7a75c ] + +total_data_buflen is used by netvsc_send() to decide if a packet can be put +into send buffer. It should also include the size of RNDIS message before the +Ethernet frame. Otherwise, a messge with total size bigger than send_section_size +may be copied into the send buffer, and cause data corruption. + +[Request to include this patch to the Stable branches] + +Signed-off-by: Haiyang Zhang +Reviewed-by: K. Y. Srinivasan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hyperv/netvsc_drv.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -556,6 +556,7 @@ do_lso: + do_send: + /* Start filling in the page buffers with the rndis hdr */ + rndis_msg->msg_len += rndis_msg_size; ++ packet->total_data_buflen = rndis_msg->msg_len; + packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size, + skb, &packet->page_buf[0]); + diff --git a/queue-3.17/ipv4-do-not-cache-routing-failures-due-to-disabled-forwarding.patch b/queue-3.17/ipv4-do-not-cache-routing-failures-due-to-disabled-forwarding.patch new file mode 100644 index 00000000000..f37edd04b8e --- /dev/null +++ b/queue-3.17/ipv4-do-not-cache-routing-failures-due-to-disabled-forwarding.patch @@ -0,0 +1,38 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Nicolas Cavallari +Date: Thu, 30 Oct 2014 10:09:53 +0100 +Subject: ipv4: Do not cache routing failures due to disabled forwarding. + +From: Nicolas Cavallari + +[ Upstream commit fa19c2b050ab5254326f5fc07096dd3c6a8d5d58 ] + +If we cache them, the kernel will reuse them, independently of +whether forwarding is enabled or not. Which means that if forwarding is +disabled on the input interface where the first routing request comes +from, then that unreachable result will be cached and reused for +other interfaces, even if forwarding is enabled on them. The opposite +is also true. + +This can be verified with two interfaces A and B and an output interface +C, where B has forwarding enabled, but not A and trying +ip route get $dst iif A from $src && ip route get $dst iif B from $src + +Signed-off-by: Nicolas Cavallari +Reviewed-by: Julian Anastasov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/route.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1798,6 +1798,7 @@ local_input: + no_route: + RT_CACHE_STAT_INC(in_no_route); + res.type = RTN_UNREACHABLE; ++ res.fi = NULL; + goto local_input; + + /* diff --git a/queue-3.17/ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch b/queue-3.17/ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch new file mode 100644 index 00000000000..11b937a6c0e --- /dev/null +++ b/queue-3.17/ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch @@ -0,0 +1,56 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Vasily Averin +Date: Wed, 15 Oct 2014 16:24:02 +0400 +Subject: ipv4: dst_entry leak in ip_send_unicast_reply() + +From: Vasily Averin + +[ Upstream commit 4062090e3e5caaf55bed4523a69f26c3265cc1d2 ] + +ip_setup_cork() called inside ip_append_data() steals dst entry from rt to cork +and in case errors in __ip_append_data() nobody frees stolen dst entry + +Fixes: 2e77d89b2fa8 ("net: avoid a pair of dst_hold()/dst_release() in ip_append_data()") +Signed-off-by: Vasily Averin +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -1533,6 +1533,7 @@ void ip_send_unicast_reply(struct net *n + struct sk_buff *nskb; + struct sock *sk; + struct inet_sock *inet; ++ int err; + + if (ip_options_echo(&replyopts.opt.opt, skb)) + return; +@@ -1572,8 +1573,13 @@ void ip_send_unicast_reply(struct net *n + sock_net_set(sk, net); + __skb_queue_head_init(&sk->sk_write_queue); + sk->sk_sndbuf = sysctl_wmem_default; +- ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, len, 0, +- &ipc, &rt, MSG_DONTWAIT); ++ err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, ++ len, 0, &ipc, &rt, MSG_DONTWAIT); ++ if (unlikely(err)) { ++ ip_flush_pending_frames(sk); ++ goto out; ++ } ++ + nskb = skb_peek(&sk->sk_write_queue); + if (nskb) { + if (arg->csumoffset >= 0) +@@ -1585,7 +1591,7 @@ void ip_send_unicast_reply(struct net *n + skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); + ip_push_pending_frames(sk, &fl4); + } +- ++out: + put_cpu_var(unicast_sock); + + ip_rt_put(rt); diff --git a/queue-3.17/ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch b/queue-3.17/ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch new file mode 100644 index 00000000000..2d8e47c0b61 --- /dev/null +++ b/queue-3.17/ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch @@ -0,0 +1,38 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Li RongQing +Date: Fri, 17 Oct 2014 16:53:23 +0800 +Subject: ipv4: fix a potential use after free in ip_tunnel_core.c + +From: Li RongQing + +[ Upstream commit 1245dfc8cadb258386fcd27df38215a0eccb1f17 ] + +pskb_may_pull() maybe change skb->data and make eth pointer oboslete, +so set eth after pskb_may_pull() + +Fixes:3d7b46cd("ip_tunnel: push generic protocol handling to ip_tunnel module") +Cc: Pravin B Shelar +Signed-off-by: Li RongQing +Acked-by: Pravin B Shelar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_tunnel_core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv4/ip_tunnel_core.c ++++ b/net/ipv4/ip_tunnel_core.c +@@ -91,11 +91,12 @@ int iptunnel_pull_header(struct sk_buff + skb_pull_rcsum(skb, hdr_len); + + if (inner_proto == htons(ETH_P_TEB)) { +- struct ethhdr *eh = (struct ethhdr *)skb->data; ++ struct ethhdr *eh; + + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) + return -ENOMEM; + ++ eh = (struct ethhdr *)skb->data; + if (likely(ntohs(eh->h_proto) >= ETH_P_802_3_MIN)) + skb->protocol = eh->h_proto; + else diff --git a/queue-3.17/ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch b/queue-3.17/ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch new file mode 100644 index 00000000000..0aef99a3c01 --- /dev/null +++ b/queue-3.17/ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch @@ -0,0 +1,42 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Jiri Pirko +Date: Mon, 13 Oct 2014 16:34:10 +0200 +Subject: ipv4: fix nexthop attlen check in fib_nh_match + +From: Jiri Pirko + +[ Upstream commit f76936d07c4eeb36d8dbb64ebd30ab46ff85d9f7 ] + +fib_nh_match does not match nexthops correctly. Example: + +ip route add 172.16.10/24 nexthop via 192.168.122.12 dev eth0 \ + nexthop via 192.168.122.13 dev eth0 +ip route del 172.16.10/24 nexthop via 192.168.122.14 dev eth0 \ + nexthop via 192.168.122.15 dev eth0 + +Del command is successful and route is removed. After this patch +applied, the route is correctly matched and result is: +RTNETLINK answers: No such process + +Please consider this for stable trees as well. + +Fixes: 4e902c57417c4 ("[IPv4]: FIB configuration using struct fib_config") +Signed-off-by: Jiri Pirko +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/fib_semantics.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -535,7 +535,7 @@ int fib_nh_match(struct fib_config *cfg, + return 1; + + attrlen = rtnh_attrlen(rtnh); +- if (attrlen < 0) { ++ if (attrlen > 0) { + struct nlattr *nla, *attrs = rtnh_attrs(rtnh); + + nla = nla_find(attrs, attrlen, RTA_GATEWAY); diff --git a/queue-3.17/macvlan-fix-a-race-on-port-dismantle-and-possible-skb-leaks.patch b/queue-3.17/macvlan-fix-a-race-on-port-dismantle-and-possible-skb-leaks.patch new file mode 100644 index 00000000000..97073a83153 --- /dev/null +++ b/queue-3.17/macvlan-fix-a-race-on-port-dismantle-and-possible-skb-leaks.patch @@ -0,0 +1,54 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Eric Dumazet +Date: Wed, 22 Oct 2014 19:43:46 -0700 +Subject: macvlan: fix a race on port dismantle and possible skb leaks + +From: Eric Dumazet + +[ Upstream commit fe0ca7328d03d36aafecebb3af650e1bb2841c20 ] + +We need to cancel the work queue after rcu grace period, +otherwise it can be rescheduled by incoming packets. + +We need to purge queue if some skbs are still in it. + +We can use __skb_queue_head_init() variant in +macvlan_process_broadcast() + +Signed-off-by: Eric Dumazet +Fixes: 412ca1550cbec ("macvlan: Move broadcasts into a work queue") +Cc: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvlan.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -201,7 +201,7 @@ static void macvlan_process_broadcast(st + struct sk_buff *skb; + struct sk_buff_head list; + +- skb_queue_head_init(&list); ++ __skb_queue_head_init(&list); + + spin_lock_bh(&port->bc_queue.lock); + skb_queue_splice_tail_init(&port->bc_queue, &list); +@@ -941,9 +941,15 @@ static void macvlan_port_destroy(struct + { + struct macvlan_port *port = macvlan_port_get_rtnl(dev); + +- cancel_work_sync(&port->bc_work); + dev->priv_flags &= ~IFF_MACVLAN_PORT; + netdev_rx_handler_unregister(dev); ++ ++ /* After this point, no packet can schedule bc_work anymore, ++ * but we need to cancel it and purge left skbs if any. ++ */ ++ cancel_work_sync(&port->bc_work); ++ __skb_queue_purge(&port->bc_queue); ++ + kfree_rcu(port, rcu); + } + diff --git a/queue-3.17/mlx4-avoid-leaking-steering-rules-on-flow-creation-error-flow.patch b/queue-3.17/mlx4-avoid-leaking-steering-rules-on-flow-creation-error-flow.patch new file mode 100644 index 00000000000..78c5b54122e --- /dev/null +++ b/queue-3.17/mlx4-avoid-leaking-steering-rules-on-flow-creation-error-flow.patch @@ -0,0 +1,71 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Or Gerlitz +Date: Thu, 30 Oct 2014 15:59:28 +0200 +Subject: mlx4: Avoid leaking steering rules on flow creation error flow + +From: Or Gerlitz + +[ Upstream commit 571e1b2c7a4c2fd5faa1648462a6b65fa26530d7 ] + +If mlx4_ib_create_flow() attempts to create > 1 rules with the +firmware, and one of these registrations fail, we leaked the +already created flow rules. + +One example of the leak is when the registration of the VXLAN ghost +steering rule fails, we didn't unregister the original rule requested +by the user, introduced in commit d2fce8a9060d "mlx4: Set +user-space raw Ethernet QPs to properly handle VXLAN traffic". + +While here, add dump of the VXLAN portion of steering rules +so it can actually be seen when flow creation fails. + +Signed-off-by: Or Gerlitz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/hw/mlx4/main.c | 10 ++++++++-- + drivers/net/ethernet/mellanox/mlx4/mcg.c | 4 ++++ + 2 files changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx4/main.c ++++ b/drivers/infiniband/hw/mlx4/main.c +@@ -1173,18 +1173,24 @@ static struct ib_flow *mlx4_ib_create_fl + err = __mlx4_ib_create_flow(qp, flow_attr, domain, type[i], + &mflow->reg_id[i]); + if (err) +- goto err_free; ++ goto err_create_flow; + i++; + } + + if (i < ARRAY_SIZE(type) && flow_attr->type == IB_FLOW_ATTR_NORMAL) { + err = mlx4_ib_tunnel_steer_add(qp, flow_attr, &mflow->reg_id[i]); + if (err) +- goto err_free; ++ goto err_create_flow; ++ i++; + } + + return &mflow->ibflow; + ++err_create_flow: ++ while (i) { ++ (void)__mlx4_ib_destroy_flow(to_mdev(qp->device)->dev, mflow->reg_id[i]); ++ i--; ++ } + err_free: + kfree(mflow); + return ERR_PTR(err); +--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c ++++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c +@@ -955,6 +955,10 @@ static void mlx4_err_rule(struct mlx4_de + cur->ib.dst_gid_msk); + break; + ++ case MLX4_NET_TRANS_RULE_ID_VXLAN: ++ len += snprintf(buf + len, BUF_SIZE - len, ++ "VNID = %d ", be32_to_cpu(cur->vxlan.vni)); ++ break; + case MLX4_NET_TRANS_RULE_ID_IPV6: + break; + diff --git a/queue-3.17/net-fix-saving-tx-flow-hash-in-sock-for-outgoing-connections.patch b/queue-3.17/net-fix-saving-tx-flow-hash-in-sock-for-outgoing-connections.patch new file mode 100644 index 00000000000..f57fb3f554e --- /dev/null +++ b/queue-3.17/net-fix-saving-tx-flow-hash-in-sock-for-outgoing-connections.patch @@ -0,0 +1,72 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Sathya Perla +Date: Wed, 22 Oct 2014 21:42:01 +0530 +Subject: net: fix saving TX flow hash in sock for outgoing connections + +From: Sathya Perla + +[ Upstream commit 9e7ceb060754f134231f68cb29d5db31419fe1ed ] + +The commit "net: Save TX flow hash in sock and set in skbuf on xmit" +introduced the inet_set_txhash() and ip6_set_txhash() routines to calculate +and record flow hash(sk_txhash) in the socket structure. sk_txhash is used +to set skb->hash which is used to spread flows across multiple TXQs. + +But, the above routines are invoked before the source port of the connection +is created. Because of this all outgoing connections that just differ in the +source port get hashed into the same TXQ. + +This patch fixes this problem for IPv4/6 by invoking the the above routines +after the source port is available for the socket. + +Fixes: b73c3d0e4("net: Save TX flow hash in sock and set in skbuf on xmit") + +Signed-off-by: Sathya Perla +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_ipv4.c | 4 ++-- + net/ipv6/tcp_ipv6.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -208,8 +208,6 @@ int tcp_v4_connect(struct sock *sk, stru + inet->inet_dport = usin->sin_port; + inet->inet_daddr = daddr; + +- inet_set_txhash(sk); +- + inet_csk(sk)->icsk_ext_hdr_len = 0; + if (inet_opt) + inet_csk(sk)->icsk_ext_hdr_len = inet_opt->opt.optlen; +@@ -226,6 +224,8 @@ int tcp_v4_connect(struct sock *sk, stru + if (err) + goto failure; + ++ inet_set_txhash(sk); ++ + rt = ip_route_newports(fl4, rt, orig_sport, orig_dport, + inet->inet_sport, inet->inet_dport, sk); + if (IS_ERR(rt)) { +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -198,8 +198,6 @@ static int tcp_v6_connect(struct sock *s + sk->sk_v6_daddr = usin->sin6_addr; + np->flow_label = fl6.flowlabel; + +- ip6_set_txhash(sk); +- + /* + * TCP over IPv4 + */ +@@ -295,6 +293,8 @@ static int tcp_v6_connect(struct sock *s + if (err) + goto late_failure; + ++ ip6_set_txhash(sk); ++ + if (!tp->write_seq && likely(!tp->repair)) + tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32, + sk->sk_v6_daddr.s6_addr32, diff --git a/queue-3.17/net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch b/queue-3.17/net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch new file mode 100644 index 00000000000..7111eefb0d2 --- /dev/null +++ b/queue-3.17/net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch @@ -0,0 +1,41 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Or Gerlitz +Date: Thu, 30 Oct 2014 15:59:27 +0200 +Subject: net/mlx4_en: Don't attempt to TX offload the outer UDP checksum for VXLAN + +From: Or Gerlitz + +[ Upstream commit a4f2dacbf2a5045e34b98a35d9a3857800f25a7b ] + +For VXLAN/NVGRE encapsulation, the current HW doesn't support offloading +both the outer UDP TX checksum and the inner TCP/UDP TX checksum. + +The driver doesn't advertize SKB_GSO_UDP_TUNNEL_CSUM, however we are wrongly +telling the HW to offload the outer UDP checksum for encapsulated packets, +fix that. + +Fixes: 837052d0ccc5 ('net/mlx4_en: Add netdev support for TCP/IP + offloads of vxlan tunneling') +Signed-off-by: Or Gerlitz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx4/en_tx.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c +@@ -808,8 +808,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff + tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f; + tx_desc->ctrl.srcrb_flags = priv->ctrl_flags; + if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { +- tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM | +- MLX4_WQE_CTRL_TCP_UDP_CSUM); ++ if (!skb->encapsulation) ++ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM | ++ MLX4_WQE_CTRL_TCP_UDP_CSUM); ++ else ++ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM); + ring->tx_csum++; + } + diff --git a/queue-3.17/net-tso-fix-unaligned-access-to-crafted-tcp-header-in-helper-api.patch b/queue-3.17/net-tso-fix-unaligned-access-to-crafted-tcp-header-in-helper-api.patch new file mode 100644 index 00000000000..2c53a2ff455 --- /dev/null +++ b/queue-3.17/net-tso-fix-unaligned-access-to-crafted-tcp-header-in-helper-api.patch @@ -0,0 +1,42 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Karl Beldan +Date: Tue, 21 Oct 2014 16:06:05 +0200 +Subject: net: tso: fix unaligned access to crafted TCP header in helper API + +From: Karl Beldan + +[ Upstream commit a63ba13eec092b70d4e5522d692eaeb2f9747387 ] + +The crafted header start address is from a driver supplied buffer, which +one can reasonably expect to be aligned on a 4-bytes boundary. +However ATM the TSO helper API is only used by ethernet drivers and +the tcp header will then be aligned to a 2-bytes only boundary from the +header start address. + +Signed-off-by: Karl Beldan +Cc: Ezequiel Garcia +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/tso.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/core/tso.c ++++ b/net/core/tso.c +@@ -1,6 +1,7 @@ + #include + #include + #include ++#include + + /* Calculate expected number of TX descriptors */ + int tso_count_descs(struct sk_buff *skb) +@@ -23,7 +24,7 @@ void tso_build_hdr(struct sk_buff *skb, + iph->id = htons(tso->ip_id); + iph->tot_len = htons(size + hdr_len - mac_hdr_len); + tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb)); +- tcph->seq = htonl(tso->tcp_seq); ++ put_unaligned_be32(tso->tcp_seq, &tcph->seq); + tso->ip_id++; + + if (!is_last) { diff --git a/queue-3.17/netlink-re-add-locking-to-netlink_lookup-and-seq-walker.patch b/queue-3.17/netlink-re-add-locking-to-netlink_lookup-and-seq-walker.patch new file mode 100644 index 00000000000..324416af1f7 --- /dev/null +++ b/queue-3.17/netlink-re-add-locking-to-netlink_lookup-and-seq-walker.patch @@ -0,0 +1,153 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Thomas Graf +Date: Tue, 21 Oct 2014 22:05:38 +0200 +Subject: netlink: Re-add locking to netlink_lookup() and seq walker + +From: Thomas Graf + +[ Upstream commit 78fd1d0ab072d4d9b5f0b7c14a1516665170b565 ] + +The synchronize_rcu() in netlink_release() introduces unacceptable +latency. Reintroduce minimal lookup so we can drop the +synchronize_rcu() until socket destruction has been RCUfied. + +Cc: David S. Miller +Cc: Eric Dumazet +Reported-by: Steinar H. Gunderson +Reported-and-tested-by: Heiko Carstens +Signed-off-by: Thomas Graf +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/netlink/af_netlink.c | 37 +++++++++++++++++++++++++------------ + 1 file changed, 25 insertions(+), 12 deletions(-) + +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -96,6 +96,14 @@ static DECLARE_WAIT_QUEUE_HEAD(nl_table_ + static int netlink_dump(struct sock *sk); + static void netlink_skb_destructor(struct sk_buff *skb); + ++/* nl_table locking explained: ++ * Lookup and traversal are protected with nl_sk_hash_lock or nl_table_lock ++ * combined with an RCU read-side lock. Insertion and removal are protected ++ * with nl_sk_hash_lock while using RCU list modification primitives and may ++ * run in parallel to nl_table_lock protected lookups. Destruction of the ++ * Netlink socket may only occur *after* nl_table_lock has been acquired ++ * either during or after the socket has been removed from the list. ++ */ + DEFINE_RWLOCK(nl_table_lock); + EXPORT_SYMBOL_GPL(nl_table_lock); + static atomic_t nl_table_users = ATOMIC_INIT(0); +@@ -109,10 +117,10 @@ EXPORT_SYMBOL_GPL(nl_sk_hash_lock); + static int lockdep_nl_sk_hash_is_held(void) + { + #ifdef CONFIG_LOCKDEP +- return (debug_locks) ? lockdep_is_held(&nl_sk_hash_lock) : 1; +-#else +- return 1; ++ if (debug_locks) ++ return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock); + #endif ++ return 1; + } + + static ATOMIC_NOTIFIER_HEAD(netlink_chain); +@@ -1028,11 +1036,13 @@ static struct sock *netlink_lookup(struc + struct netlink_table *table = &nl_table[protocol]; + struct sock *sk; + ++ read_lock(&nl_table_lock); + rcu_read_lock(); + sk = __netlink_lookup(table, portid, net); + if (sk) + sock_hold(sk); + rcu_read_unlock(); ++ read_unlock(&nl_table_lock); + + return sk; + } +@@ -1257,9 +1267,6 @@ static int netlink_release(struct socket + } + netlink_table_ungrab(); + +- /* Wait for readers to complete */ +- synchronize_net(); +- + kfree(nlk->groups); + nlk->groups = NULL; + +@@ -1281,6 +1288,7 @@ static int netlink_autobind(struct socke + + retry: + cond_resched(); ++ netlink_table_grab(); + rcu_read_lock(); + if (__netlink_lookup(table, portid, net)) { + /* Bind collision, search negative portid values. */ +@@ -1288,9 +1296,11 @@ retry: + if (rover > -4097) + rover = -4097; + rcu_read_unlock(); ++ netlink_table_ungrab(); + goto retry; + } + rcu_read_unlock(); ++ netlink_table_ungrab(); + + err = netlink_insert(sk, net, portid); + if (err == -EADDRINUSE) +@@ -2921,14 +2931,16 @@ static struct sock *netlink_seq_socket_i + } + + static void *netlink_seq_start(struct seq_file *seq, loff_t *pos) +- __acquires(RCU) ++ __acquires(nl_table_lock) __acquires(RCU) + { ++ read_lock(&nl_table_lock); + rcu_read_lock(); + return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : SEQ_START_TOKEN; + } + + static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) + { ++ struct rhashtable *ht; + struct netlink_sock *nlk; + struct nl_seq_iter *iter; + struct net *net; +@@ -2943,19 +2955,19 @@ static void *netlink_seq_next(struct seq + iter = seq->private; + nlk = v; + +- rht_for_each_entry_rcu(nlk, nlk->node.next, node) ++ i = iter->link; ++ ht = &nl_table[i].hash; ++ rht_for_each_entry(nlk, nlk->node.next, ht, node) + if (net_eq(sock_net((struct sock *)nlk), net)) + return nlk; + +- i = iter->link; + j = iter->hash_idx + 1; + + do { +- struct rhashtable *ht = &nl_table[i].hash; + const struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht); + + for (; j < tbl->size; j++) { +- rht_for_each_entry_rcu(nlk, tbl->buckets[j], node) { ++ rht_for_each_entry(nlk, tbl->buckets[j], ht, node) { + if (net_eq(sock_net((struct sock *)nlk), net)) { + iter->link = i; + iter->hash_idx = j; +@@ -2971,9 +2983,10 @@ static void *netlink_seq_next(struct seq + } + + static void netlink_seq_stop(struct seq_file *seq, void *v) +- __releases(RCU) ++ __releases(RCU) __releases(nl_table_lock) + { + rcu_read_unlock(); ++ read_unlock(&nl_table_lock); + } + + diff --git a/queue-3.17/series b/queue-3.17/series index 1206dd90e4f..cf4daff2596 100644 --- a/queue-3.17/series +++ b/queue-3.17/series @@ -1,2 +1,26 @@ tracing-syscalls-ignore-numbers-outside-nr_syscalls-range.patch kvm-emulator-fix-execution-close-to-the-segment-limit.patch +x86-bpf_jit-fix-two-bugs-in-ebpf-jit-compiler.patch +ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch +vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch +vxlan-using-pskb_may_pull-as-early-as-possible.patch +vxlan-fix-a-free-after-use.patch +ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch +ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch +tipc-fix-bug-in-bundled-buffer-reception.patch +ax88179_178a-fix-bonding-failure.patch +netlink-re-add-locking-to-netlink_lookup-and-seq-walker.patch +net-tso-fix-unaligned-access-to-crafted-tcp-header-in-helper-api.patch +net-fix-saving-tx-flow-hash-in-sock-for-outgoing-connections.patch +hyperv-fix-the-total_data_buflen-in-send-path.patch +tcp-md5-do-not-use-alloc_percpu.patch +macvlan-fix-a-race-on-port-dismantle-and-possible-skb-leaks.patch +cxgb4-fix-missing-initialization-of-win0_lock.patch +ipv4-do-not-cache-routing-failures-due-to-disabled-forwarding.patch +net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch +mlx4-avoid-leaking-steering-rules-on-flow-creation-error-flow.patch +gre-use-inner-mac-length-when-computing-tunnel-length.patch +drivers-net-disable-ufo-through-virtio.patch +drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch +drivers-net-macvtap-and-tun-depend-on-inet.patch +stmmac-pci-set-default-of-the-filter-bins.patch diff --git a/queue-3.17/stmmac-pci-set-default-of-the-filter-bins.patch b/queue-3.17/stmmac-pci-set-default-of-the-filter-bins.patch new file mode 100644 index 00000000000..2d0b168276f --- /dev/null +++ b/queue-3.17/stmmac-pci-set-default-of-the-filter-bins.patch @@ -0,0 +1,45 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Andy Shevchenko +Date: Fri, 31 Oct 2014 18:28:03 +0200 +Subject: stmmac: pci: set default of the filter bins + +From: Andy Shevchenko + +[ Upstream commit 1e19e084eae727654052339757ab7f1eaff58bad ] + +The commit 3b57de958e2a brought the support for a different amount of the +filter bins, but didn't update the PCI driver accordingly. This patch appends +the default values when the device is enumerated via PCI bus. + +Fixes: 3b57de958e2a (net: stmmac: Support devicetree configs for mcast and ucast filter entries) +Signed-off-by: Andy Shevchenko +Cc: stable@vger.kernel.org +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +@@ -33,6 +33,7 @@ static struct stmmac_dma_cfg dma_cfg; + static void stmmac_default_data(void) + { + memset(&plat_dat, 0, sizeof(struct plat_stmmacenet_data)); ++ + plat_dat.bus_id = 1; + plat_dat.phy_addr = 0; + plat_dat.interface = PHY_INTERFACE_MODE_GMII; +@@ -47,6 +48,12 @@ static void stmmac_default_data(void) + dma_cfg.pbl = 32; + dma_cfg.burst_len = DMA_AXI_BLEN_256; + plat_dat.dma_cfg = &dma_cfg; ++ ++ /* Set default value for multicast hash bins */ ++ plat_dat.multicast_filter_bins = HASH_TABLE_SIZE; ++ ++ /* Set default value for unicast filter entries */ ++ plat_dat.unicast_filter_entries = 1; + } + + /** diff --git a/queue-3.17/tcp-md5-do-not-use-alloc_percpu.patch b/queue-3.17/tcp-md5-do-not-use-alloc_percpu.patch new file mode 100644 index 00000000000..6e41a9de518 --- /dev/null +++ b/queue-3.17/tcp-md5-do-not-use-alloc_percpu.patch @@ -0,0 +1,130 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Eric Dumazet +Date: Thu, 23 Oct 2014 12:58:58 -0700 +Subject: tcp: md5: do not use alloc_percpu() + +From: Eric Dumazet + +[ Upstream commit 349ce993ac706869d553a1816426d3a4bfda02b1 ] + +percpu tcp_md5sig_pool contains memory blobs that ultimately +go through sg_set_buf(). + +-> sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); + +This requires that whole area is in a physically contiguous portion +of memory. And that @buf is not backed by vmalloc(). + +Given that alloc_percpu() can use vmalloc() areas, this does not +fit the requirements. + +Replace alloc_percpu() by a static DEFINE_PER_CPU() as tcp_md5sig_pool +is small anyway, there is no gain to dynamically allocate it. + +Signed-off-by: Eric Dumazet +Fixes: 765cf9976e93 ("tcp: md5: remove one indirection level in tcp_md5sig_pool") +Reported-by: Crestez Dan Leonard +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 59 +++++++++++++++++++-------------------------------------- + 1 file changed, 20 insertions(+), 39 deletions(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2985,61 +2985,42 @@ EXPORT_SYMBOL(compat_tcp_getsockopt); + #endif + + #ifdef CONFIG_TCP_MD5SIG +-static struct tcp_md5sig_pool __percpu *tcp_md5sig_pool __read_mostly; ++static DEFINE_PER_CPU(struct tcp_md5sig_pool, tcp_md5sig_pool); + static DEFINE_MUTEX(tcp_md5sig_mutex); +- +-static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool __percpu *pool) +-{ +- int cpu; +- +- for_each_possible_cpu(cpu) { +- struct tcp_md5sig_pool *p = per_cpu_ptr(pool, cpu); +- +- if (p->md5_desc.tfm) +- crypto_free_hash(p->md5_desc.tfm); +- } +- free_percpu(pool); +-} ++static bool tcp_md5sig_pool_populated = false; + + static void __tcp_alloc_md5sig_pool(void) + { + int cpu; +- struct tcp_md5sig_pool __percpu *pool; +- +- pool = alloc_percpu(struct tcp_md5sig_pool); +- if (!pool) +- return; + + for_each_possible_cpu(cpu) { +- struct crypto_hash *hash; ++ if (!per_cpu(tcp_md5sig_pool, cpu).md5_desc.tfm) { ++ struct crypto_hash *hash; + +- hash = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC); +- if (IS_ERR_OR_NULL(hash)) +- goto out_free; +- +- per_cpu_ptr(pool, cpu)->md5_desc.tfm = hash; ++ hash = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR_OR_NULL(hash)) ++ return; ++ per_cpu(tcp_md5sig_pool, cpu).md5_desc.tfm = hash; ++ } + } +- /* before setting tcp_md5sig_pool, we must commit all writes +- * to memory. See ACCESS_ONCE() in tcp_get_md5sig_pool() ++ /* before setting tcp_md5sig_pool_populated, we must commit all writes ++ * to memory. See smp_rmb() in tcp_get_md5sig_pool() + */ + smp_wmb(); +- tcp_md5sig_pool = pool; +- return; +-out_free: +- __tcp_free_md5sig_pool(pool); ++ tcp_md5sig_pool_populated = true; + } + + bool tcp_alloc_md5sig_pool(void) + { +- if (unlikely(!tcp_md5sig_pool)) { ++ if (unlikely(!tcp_md5sig_pool_populated)) { + mutex_lock(&tcp_md5sig_mutex); + +- if (!tcp_md5sig_pool) ++ if (!tcp_md5sig_pool_populated) + __tcp_alloc_md5sig_pool(); + + mutex_unlock(&tcp_md5sig_mutex); + } +- return tcp_md5sig_pool != NULL; ++ return tcp_md5sig_pool_populated; + } + EXPORT_SYMBOL(tcp_alloc_md5sig_pool); + +@@ -3053,13 +3034,13 @@ EXPORT_SYMBOL(tcp_alloc_md5sig_pool); + */ + struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) + { +- struct tcp_md5sig_pool __percpu *p; +- + local_bh_disable(); +- p = ACCESS_ONCE(tcp_md5sig_pool); +- if (p) +- return __this_cpu_ptr(p); + ++ if (tcp_md5sig_pool_populated) { ++ /* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */ ++ smp_rmb(); ++ return this_cpu_ptr(&tcp_md5sig_pool); ++ } + local_bh_enable(); + return NULL; + } diff --git a/queue-3.17/tipc-fix-bug-in-bundled-buffer-reception.patch b/queue-3.17/tipc-fix-bug-in-bundled-buffer-reception.patch new file mode 100644 index 00000000000..cd7a10d9a9c --- /dev/null +++ b/queue-3.17/tipc-fix-bug-in-bundled-buffer-reception.patch @@ -0,0 +1,43 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Jon Paul Maloy +Date: Fri, 17 Oct 2014 15:25:28 -0400 +Subject: tipc: fix bug in bundled buffer reception + +From: Jon Paul Maloy + +[ Upstream commit 643566d4b47e2956110e79c0e6f65db9b9ea42c6 ] + +In commit ec8a2e5621db2da24badb3969eda7fd359e1869f ("tipc: same receive +code path for connection protocol and data messages") we omitted the +the possiblilty that an arriving message extracted from a bundle buffer +may be a multicast message. Such messages need to be to be delivered to +the socket via a separate function, tipc_sk_mcast_rcv(). As a result, +small multicast messages arriving as members of a bundle buffer will be +silently dropped. + +This commit corrects the error by considering this case in the function +tipc_link_bundle_rcv(). + +Signed-off-by: Jon Maloy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/link.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/net/tipc/link.c ++++ b/net/tipc/link.c +@@ -1936,7 +1936,12 @@ void tipc_link_bundle_rcv(struct sk_buff + } + omsg = buf_msg(obuf); + pos += align(msg_size(omsg)); +- if (msg_isdata(omsg) || (msg_user(omsg) == CONN_MANAGER)) { ++ if (msg_isdata(omsg)) { ++ if (unlikely(msg_type(omsg) == TIPC_MCAST_MSG)) ++ tipc_sk_mcast_rcv(obuf); ++ else ++ tipc_sk_rcv(obuf); ++ } else if (msg_user(omsg) == CONN_MANAGER) { + tipc_sk_rcv(obuf); + } else if (msg_user(omsg) == NAME_DISTRIBUTOR) { + tipc_named_rcv(obuf); diff --git a/queue-3.17/vxlan-fix-a-free-after-use.patch b/queue-3.17/vxlan-fix-a-free-after-use.patch new file mode 100644 index 00000000000..35835ef29b6 --- /dev/null +++ b/queue-3.17/vxlan-fix-a-free-after-use.patch @@ -0,0 +1,31 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Li RongQing +Date: Fri, 17 Oct 2014 14:06:16 +0800 +Subject: vxlan: fix a free after use + +From: Li RongQing + +[ Upstream commit 7a9f526fc3ee49b6034af2f243676ee0a27dcaa8 ] + +pskb_may_pull maybe change skb->data and make eth pointer oboslete, +so eth needs to reload + +Fixes: 91269e390d062 ("vxlan: using pskb_may_pull as early as possible") +Cc: Eric Dumazet +Signed-off-by: Li RongQing +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -1936,6 +1936,7 @@ static netdev_tx_t vxlan_xmit(struct sk_ + msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) + return neigh_reduce(dev, skb); + } ++ eth = eth_hdr(skb); + #endif + } + diff --git a/queue-3.17/vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch b/queue-3.17/vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch new file mode 100644 index 00000000000..ad3fd0069a3 --- /dev/null +++ b/queue-3.17/vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch @@ -0,0 +1,50 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Li RongQing +Date: Thu, 16 Oct 2014 08:49:41 +0800 +Subject: vxlan: fix a use after free in vxlan_encap_bypass + +From: Li RongQing + +[ Upstream commit ce6502a8f9572179f044a4d62667c4645256d6e4 ] + +when netif_rx() is done, the netif_rx handled skb maybe be freed, +and should not be used. + +Signed-off-by: Li RongQing +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -1717,6 +1717,8 @@ static void vxlan_encap_bypass(struct sk + struct pcpu_sw_netstats *tx_stats, *rx_stats; + union vxlan_addr loopback; + union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip; ++ struct net_device *dev = skb->dev; ++ int len = skb->len; + + tx_stats = this_cpu_ptr(src_vxlan->dev->tstats); + rx_stats = this_cpu_ptr(dst_vxlan->dev->tstats); +@@ -1740,16 +1742,16 @@ static void vxlan_encap_bypass(struct sk + + u64_stats_update_begin(&tx_stats->syncp); + tx_stats->tx_packets++; +- tx_stats->tx_bytes += skb->len; ++ tx_stats->tx_bytes += len; + u64_stats_update_end(&tx_stats->syncp); + + if (netif_rx(skb) == NET_RX_SUCCESS) { + u64_stats_update_begin(&rx_stats->syncp); + rx_stats->rx_packets++; +- rx_stats->rx_bytes += skb->len; ++ rx_stats->rx_bytes += len; + u64_stats_update_end(&rx_stats->syncp); + } else { +- skb->dev->stats.rx_dropped++; ++ dev->stats.rx_dropped++; + } + } + diff --git a/queue-3.17/vxlan-using-pskb_may_pull-as-early-as-possible.patch b/queue-3.17/vxlan-using-pskb_may_pull-as-early-as-possible.patch new file mode 100644 index 00000000000..f583f674b36 --- /dev/null +++ b/queue-3.17/vxlan-using-pskb_may_pull-as-early-as-possible.patch @@ -0,0 +1,42 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Li RongQing +Date: Thu, 16 Oct 2014 09:17:18 +0800 +Subject: vxlan: using pskb_may_pull as early as possible + +From: Li RongQing + +[ Upstream commit 91269e390d062b526432f2ef1352b8df82e0e0bc ] + +pskb_may_pull should be used to check if skb->data has enough space, +skb->len can not ensure that. + +Cc: Cong Wang +Signed-off-by: Li RongQing +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -1440,9 +1440,6 @@ static int neigh_reduce(struct net_devic + if (!in6_dev) + goto out; + +- if (!pskb_may_pull(skb, skb->len)) +- goto out; +- + iphdr = ipv6_hdr(skb); + saddr = &iphdr->saddr; + daddr = &iphdr->daddr; +@@ -1929,7 +1926,8 @@ static netdev_tx_t vxlan_xmit(struct sk_ + return arp_reduce(dev, skb); + #if IS_ENABLED(CONFIG_IPV6) + else if (ntohs(eth->h_proto) == ETH_P_IPV6 && +- skb->len >= sizeof(struct ipv6hdr) + sizeof(struct nd_msg) && ++ pskb_may_pull(skb, sizeof(struct ipv6hdr) ++ + sizeof(struct nd_msg)) && + ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) { + struct nd_msg *msg; + diff --git a/queue-3.17/x86-bpf_jit-fix-two-bugs-in-ebpf-jit-compiler.patch b/queue-3.17/x86-bpf_jit-fix-two-bugs-in-ebpf-jit-compiler.patch new file mode 100644 index 00000000000..aeef299a24d --- /dev/null +++ b/queue-3.17/x86-bpf_jit-fix-two-bugs-in-ebpf-jit-compiler.patch @@ -0,0 +1,121 @@ +From foo@baz Fri Nov 7 11:36:50 PST 2014 +From: Alexei Starovoitov +Date: Fri, 10 Oct 2014 20:30:23 -0700 +Subject: x86: bpf_jit: fix two bugs in eBPF JIT compiler + +From: Alexei Starovoitov + +[ Upstream commit e0ee9c12157dc74e49e4731e0d07512e7d1ceb95 ] + +1. +JIT compiler using multi-pass approach to converge to final image size, +since x86 instructions are variable length. It starts with large +gaps between instructions (so some jumps may use imm32 instead of imm8) +and iterates until total program size is the same as in previous pass. +This algorithm works only if program size is strictly decreasing. +Programs that use LD_ABS insn need additional code in prologue, but it +was not emitted during 1st pass, so there was a chance that 2nd pass would +adjust imm32->imm8 jump offsets to the same number of bytes as increase in +prologue, which may cause algorithm to erroneously decide that size converged. +Fix it by always emitting largest prologue in the first pass which +is detected by oldproglen==0 check. +Also change error check condition 'proglen != oldproglen' to fail gracefully. + +2. +while staring at the code realized that 64-byte buffer may not be enough +when 1st insn is large, so increase it to 128 to avoid buffer overflow +(theoretical maximum size of prologue+div is 109) and add runtime check. + +Fixes: 622582786c9e ("net: filter: x86: internal BPF JIT") +Reported-by: Darrick J. Wong +Signed-off-by: Alexei Starovoitov +Tested-by: Darrick J. Wong +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/net/bpf_jit_comp.c | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -211,12 +211,17 @@ struct jit_context { + bool seen_ld_abs; + }; + ++/* maximum number of bytes emitted while JITing one eBPF insn */ ++#define BPF_MAX_INSN_SIZE 128 ++#define BPF_INSN_SAFETY 64 ++ + static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, + int oldproglen, struct jit_context *ctx) + { + struct bpf_insn *insn = bpf_prog->insnsi; + int insn_cnt = bpf_prog->len; +- u8 temp[64]; ++ bool seen_ld_abs = ctx->seen_ld_abs | (oldproglen == 0); ++ u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY]; + int i; + int proglen = 0; + u8 *prog = temp; +@@ -254,7 +259,7 @@ static int do_jit(struct bpf_prog *bpf_p + EMIT2(0x31, 0xc0); /* xor eax, eax */ + EMIT3(0x4D, 0x31, 0xED); /* xor r13, r13 */ + +- if (ctx->seen_ld_abs) { ++ if (seen_ld_abs) { + /* r9d : skb->len - skb->data_len (headlen) + * r10 : skb->data + */ +@@ -655,7 +660,7 @@ xadd: if (is_imm8(insn->off)) + case BPF_JMP | BPF_CALL: + func = (u8 *) __bpf_call_base + imm32; + jmp_offset = func - (image + addrs[i]); +- if (ctx->seen_ld_abs) { ++ if (seen_ld_abs) { + EMIT2(0x41, 0x52); /* push %r10 */ + EMIT2(0x41, 0x51); /* push %r9 */ + /* need to adjust jmp offset, since +@@ -669,7 +674,7 @@ xadd: if (is_imm8(insn->off)) + return -EINVAL; + } + EMIT1_off32(0xE8, jmp_offset); +- if (ctx->seen_ld_abs) { ++ if (seen_ld_abs) { + EMIT2(0x41, 0x59); /* pop %r9 */ + EMIT2(0x41, 0x5A); /* pop %r10 */ + } +@@ -774,7 +779,8 @@ emit_jmp: + goto common_load; + case BPF_LD | BPF_ABS | BPF_W: + func = CHOOSE_LOAD_FUNC(imm32, sk_load_word); +-common_load: ctx->seen_ld_abs = true; ++common_load: ++ ctx->seen_ld_abs = seen_ld_abs = true; + jmp_offset = func - (image + addrs[i]); + if (!func || !is_simm32(jmp_offset)) { + pr_err("unsupported bpf func %d addr %p image %p\n", +@@ -848,6 +854,11 @@ common_load: ctx->seen_ld_abs = true; + } + + ilen = prog - temp; ++ if (ilen > BPF_MAX_INSN_SIZE) { ++ pr_err("bpf_jit_compile fatal insn size error\n"); ++ return -EFAULT; ++ } ++ + if (image) { + if (unlikely(proglen + ilen > oldproglen)) { + pr_err("bpf_jit_compile fatal error\n"); +@@ -904,9 +915,11 @@ void bpf_int_jit_compile(struct bpf_prog + goto out; + } + if (image) { +- if (proglen != oldproglen) ++ if (proglen != oldproglen) { + pr_err("bpf_jit: proglen=%d != oldproglen=%d\n", + proglen, oldproglen); ++ goto out; ++ } + break; + } + if (proglen == oldproglen) {