From fefa619b71b199648448ab17b442817bb2292de9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 7 Nov 2014 11:43:17 -0800 Subject: [PATCH] 3.14-stable patches added patches: ax88179_178a-fix-bonding-failure.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 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 tcp-md5-do-not-use-alloc_percpu.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 --- .../ax88179_178a-fix-bonding-failure.patch | 59 +++++ ...ivers-net-disable-ufo-through-virtio.patch | 217 ++++++++++++++++++ ...agment-idents-for-virtio-ufo-packets.patch | 137 +++++++++++ ...s-net-macvtap-and-tun-depend-on-inet.patch | 43 ++++ ...-length-when-computing-tunnel-length.patch | 35 +++ ..._entry-leak-in-ip_send_unicast_reply.patch | 56 +++++ ...l-use-after-free-in-ip_tunnel_core.c.patch | 38 +++ ...nexthop-attlen-check-in-fib_nh_match.patch | 42 ++++ queue-3.14/series | 12 + .../tcp-md5-do-not-use-alloc_percpu.patch | 130 +++++++++++ queue-3.14/vxlan-fix-a-free-after-use.patch | 31 +++ ...use-after-free-in-vxlan_encap_bypass.patch | 50 ++++ ...g-pskb_may_pull-as-early-as-possible.patch | 42 ++++ 13 files changed, 892 insertions(+) create mode 100644 queue-3.14/ax88179_178a-fix-bonding-failure.patch create mode 100644 queue-3.14/drivers-net-disable-ufo-through-virtio.patch create mode 100644 queue-3.14/drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch create mode 100644 queue-3.14/drivers-net-macvtap-and-tun-depend-on-inet.patch create mode 100644 queue-3.14/gre-use-inner-mac-length-when-computing-tunnel-length.patch create mode 100644 queue-3.14/ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch create mode 100644 queue-3.14/ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch create mode 100644 queue-3.14/ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch create mode 100644 queue-3.14/tcp-md5-do-not-use-alloc_percpu.patch create mode 100644 queue-3.14/vxlan-fix-a-free-after-use.patch create mode 100644 queue-3.14/vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch create mode 100644 queue-3.14/vxlan-using-pskb_may_pull-as-early-as-possible.patch diff --git a/queue-3.14/ax88179_178a-fix-bonding-failure.patch b/queue-3.14/ax88179_178a-fix-bonding-failure.patch new file mode 100644 index 00000000000..fc61b37e6c8 --- /dev/null +++ b/queue-3.14/ax88179_178a-fix-bonding-failure.patch @@ -0,0 +1,59 @@ +From foo@baz Fri Nov 7 11:37:05 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 +@@ -696,6 +696,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; +@@ -705,8 +706,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.14/drivers-net-disable-ufo-through-virtio.patch b/queue-3.14/drivers-net-disable-ufo-through-virtio.patch new file mode 100644 index 00000000000..a0436bda699 --- /dev/null +++ b/queue-3.14/drivers-net-disable-ufo-through-virtio.patch @@ -0,0 +1,217 @@ +From foo@baz Fri Nov 7 11:37:05 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; +@@ -1150,8 +1150,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); +@@ -1252,8 +1262,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", +@@ -1783,11 +1791,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 +@@ -496,8 +496,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; +@@ -836,8 +845,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) +@@ -1657,7 +1664,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? */ +@@ -1667,11 +1674,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)) +@@ -1711,8 +1716,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)) +@@ -1903,9 +1907,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.14/drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch b/queue-3.14/drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch new file mode 100644 index 00000000000..a5fc82af076 --- /dev/null +++ b/queue-3.14/drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch @@ -0,0 +1,137 @@ +From foo@baz Fri Nov 7 11:37:05 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 | 33 +++++++++++++++++++++++++++++++++ + 4 files changed, 43 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 +@@ -1140,6 +1141,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) { +@@ -1160,6 +1163,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: +@@ -1190,7 +1195,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 +@@ -660,6 +660,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); + + /* +--- a/net/ipv6/output_core.c ++++ b/net/ipv6/output_core.c +@@ -3,10 +3,43 @@ + * not configured or static. These functions are needed by GSO/GRO implementation. + */ + #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) + { diff --git a/queue-3.14/drivers-net-macvtap-and-tun-depend-on-inet.patch b/queue-3.14/drivers-net-macvtap-and-tun-depend-on-inet.patch new file mode 100644 index 00000000000..f2eb45ea895 --- /dev/null +++ b/queue-3.14/drivers-net-macvtap-and-tun-depend-on-inet.patch @@ -0,0 +1,43 @@ +From foo@baz Fri Nov 7 11:37:05 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 +@@ -205,6 +206,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.14/gre-use-inner-mac-length-when-computing-tunnel-length.patch b/queue-3.14/gre-use-inner-mac-length-when-computing-tunnel-length.patch new file mode 100644 index 00000000000..f4bdc8b3a43 --- /dev/null +++ b/queue-3.14/gre-use-inner-mac-length-when-computing-tunnel-length.patch @@ -0,0 +1,35 @@ +From foo@baz Fri Nov 7 11:37:05 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 +@@ -50,7 +50,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.14/ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch b/queue-3.14/ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch new file mode 100644 index 00000000000..19bd52c5ffa --- /dev/null +++ b/queue-3.14/ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch @@ -0,0 +1,56 @@ +From foo@baz Fri Nov 7 11:37:05 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 +@@ -1487,6 +1487,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; +@@ -1525,8 +1526,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) +@@ -1538,7 +1544,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.14/ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch b/queue-3.14/ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch new file mode 100644 index 00000000000..2aa74ac2651 --- /dev/null +++ b/queue-3.14/ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch @@ -0,0 +1,38 @@ +From foo@baz Fri Nov 7 11:37:05 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.14/ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch b/queue-3.14/ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch new file mode 100644 index 00000000000..45dafaab01b --- /dev/null +++ b/queue-3.14/ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch @@ -0,0 +1,42 @@ +From foo@baz Fri Nov 7 11:37:05 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.14/series b/queue-3.14/series index 52685951e14..940f8a1fdfa 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -1 +1,13 @@ tracing-syscalls-ignore-numbers-outside-nr_syscalls-range.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-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch +ax88179_178a-fix-bonding-failure.patch +tcp-md5-do-not-use-alloc_percpu.patch +gre-use-inner-mac-length-when-computing-tunnel-length.patch +ipv4-dst_entry-leak-in-ip_send_unicast_reply.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 diff --git a/queue-3.14/tcp-md5-do-not-use-alloc_percpu.patch b/queue-3.14/tcp-md5-do-not-use-alloc_percpu.patch new file mode 100644 index 00000000000..0e6ccdcbf36 --- /dev/null +++ b/queue-3.14/tcp-md5-do-not-use-alloc_percpu.patch @@ -0,0 +1,130 @@ +From foo@baz Fri Nov 7 11:37:05 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 +@@ -2954,61 +2954,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); + +@@ -3022,13 +3003,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.14/vxlan-fix-a-free-after-use.patch b/queue-3.14/vxlan-fix-a-free-after-use.patch new file mode 100644 index 00000000000..4eb17a717d0 --- /dev/null +++ b/queue-3.14/vxlan-fix-a-free-after-use.patch @@ -0,0 +1,31 @@ +From foo@baz Fri Nov 7 11:37:05 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 +@@ -1986,6 +1986,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.14/vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch b/queue-3.14/vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch new file mode 100644 index 00000000000..aaf32beb46e --- /dev/null +++ b/queue-3.14/vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch @@ -0,0 +1,50 @@ +From foo@baz Fri Nov 7 11:37:05 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 +@@ -1770,6 +1770,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); +@@ -1793,16 +1795,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.14/vxlan-using-pskb_may_pull-as-early-as-possible.patch b/queue-3.14/vxlan-using-pskb_may_pull-as-early-as-possible.patch new file mode 100644 index 00000000000..55763b559ea --- /dev/null +++ b/queue-3.14/vxlan-using-pskb_may_pull-as-early-as-possible.patch @@ -0,0 +1,42 @@ +From foo@baz Fri Nov 7 11:37:05 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 +@@ -1447,9 +1447,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; +@@ -1979,7 +1976,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; + -- 2.47.3