]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Nov 2014 19:43:17 +0000 (11:43 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Nov 2014 19:43:17 +0000 (11:43 -0800)
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

13 files changed:
queue-3.14/ax88179_178a-fix-bonding-failure.patch [new file with mode: 0644]
queue-3.14/drivers-net-disable-ufo-through-virtio.patch [new file with mode: 0644]
queue-3.14/drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch [new file with mode: 0644]
queue-3.14/drivers-net-macvtap-and-tun-depend-on-inet.patch [new file with mode: 0644]
queue-3.14/gre-use-inner-mac-length-when-computing-tunnel-length.patch [new file with mode: 0644]
queue-3.14/ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch [new file with mode: 0644]
queue-3.14/ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch [new file with mode: 0644]
queue-3.14/ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch [new file with mode: 0644]
queue-3.14/series
queue-3.14/tcp-md5-do-not-use-alloc_percpu.patch [new file with mode: 0644]
queue-3.14/vxlan-fix-a-free-after-use.patch [new file with mode: 0644]
queue-3.14/vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch [new file with mode: 0644]
queue-3.14/vxlan-using-pskb_may_pull-as-early-as-possible.patch [new file with mode: 0644]

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 (file)
index 0000000..fc61b37
--- /dev/null
@@ -0,0 +1,59 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Ian Morgan <imorgan@primordial.ca>
+Date: Sun, 19 Oct 2014 08:05:13 -0400
+Subject: ax88179_178a: fix bonding failure
+
+From: Ian Morgan <imorgan@primordial.ca>
+
+[ 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 <imorgan@primordial.ca>
+
+ drivers/net/usb/ax88179_178a.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..a0436bd
--- /dev/null
@@ -0,0 +1,217 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 30 Oct 2014 18:27:12 +0000
+Subject: drivers/net: Disable UFO through virtio
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ 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 <ben@decadent.org.uk>
+Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..a5fc82a
--- /dev/null
@@ -0,0 +1,137 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 30 Oct 2014 18:27:17 +0000
+Subject: drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ 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 <ben@decadent.org.uk>
+Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/idr.h>
+ #include <linux/fs.h>
++#include <net/ipv6.h>
+ #include <net/net_namespace.h>
+ #include <net/rtnetlink.h>
+ #include <net/sock.h>
+@@ -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 <linux/nsproxy.h>
+ #include <linux/virtio_net.h>
+ #include <linux/rcupdate.h>
++#include <net/ipv6.h>
+ #include <net/net_namespace.h>
+ #include <net/netns/generic.h>
+ #include <net/rtnetlink.h>
+@@ -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 <linux/export.h>
++#include <net/ip.h>
+ #include <net/ipv6.h>
+ #include <net/ip6_fib.h>
+ #include <net/addrconf.h>
++/* 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 (file)
index 0000000..f2eb45e
--- /dev/null
@@ -0,0 +1,43 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 31 Oct 2014 03:10:31 +0000
+Subject: drivers/net: macvtap and tun depend on INET
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ 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 <fengguang.wu@intel.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+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 <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f4bdc8b
--- /dev/null
@@ -0,0 +1,35 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Tom Herbert <therbert@google.com>
+Date: Thu, 30 Oct 2014 08:40:56 -0700
+Subject: gre: Use inner mac length when computing tunnel length
+
+From: Tom Herbert <therbert@google.com>
+
+[ 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 <therbert@google.com>
+Acked-by: Alexander Duyck <alexander.h.duyck@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..19bd52c
--- /dev/null
@@ -0,0 +1,56 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Vasily Averin <vvs@parallels.com>
+Date: Wed, 15 Oct 2014 16:24:02 +0400
+Subject: ipv4: dst_entry leak in ip_send_unicast_reply()
+
+From: Vasily Averin <vvs@parallels.com>
+
+[ 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 <vvs@parallels.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2aa74ac
--- /dev/null
@@ -0,0 +1,38 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+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 <roy.qing.li@gmail.com>
+
+[ 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 <pshelar@nicira.com>
+Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
+Acked-by: Pravin B Shelar <pshelar@nicira.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..45dafaa
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Jiri Pirko <jiri@resnulli.us>
+Date: Mon, 13 Oct 2014 16:34:10 +0200
+Subject: ipv4: fix nexthop attlen check in fib_nh_match
+
+From: Jiri Pirko <jiri@resnulli.us>
+
+[ 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 <jiri@resnulli.us>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
index 52685951e1478b6559aa5e12180548334ea1101b..940f8a1fdfa2f74dcbdf7b8aafe61acd20102f86 100644 (file)
@@ -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 (file)
index 0000000..0e6ccdc
--- /dev/null
@@ -0,0 +1,130 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 23 Oct 2014 12:58:58 -0700
+Subject: tcp: md5: do not use alloc_percpu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Fixes: 765cf9976e93 ("tcp: md5: remove one indirection level in tcp_md5sig_pool")
+Reported-by: Crestez Dan Leonard <cdleonard@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..4eb17a7
--- /dev/null
@@ -0,0 +1,31 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Fri, 17 Oct 2014 14:06:16 +0800
+Subject: vxlan: fix a free after use
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ 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 <edumazet@google.com>
+Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..aaf32be
--- /dev/null
@@ -0,0 +1,50 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Thu, 16 Oct 2014 08:49:41 +0800
+Subject: vxlan: fix a use after free in vxlan_encap_bypass
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ 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 <roy.qing.li@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..55763b5
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Fri Nov  7 11:37:05 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Thu, 16 Oct 2014 09:17:18 +0800
+Subject: vxlan: using pskb_may_pull as early as possible
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ 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 <xiyou.wangcong@gmail.com>
+Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;