--- /dev/null
+From 8f44c9a41386729fea410e688959ddaa9d51be7c Mon Sep 17 00:00:00 2001
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+Date: Fri, 7 Jul 2017 21:09:06 +0100
+Subject: brcmfmac: fix possible buffer overflow in brcmf_cfg80211_mgmt_tx()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+
+commit 8f44c9a41386729fea410e688959ddaa9d51be7c upstream.
+
+The lower level nl80211 code in cfg80211 ensures that "len" is between
+25 and NL80211_ATTR_FRAME (2304). We subtract DOT11_MGMT_HDR_LEN (24) from
+"len" so thats's max of 2280. However, the action_frame->data[] buffer is
+only BRCMF_FIL_ACTION_FRAME_SIZE (1800) bytes long so this memcpy() can
+overflow.
+
+ memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
+ le16_to_cpu(action_frame->len));
+
+Fixes: 18e2f61db3b70 ("brcmfmac: P2P action frame tx.")
+Reported-by: "freenerguo(郭大兴)" <freenerguo@tencent.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+@@ -4472,6 +4472,11 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip
+ cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
+ GFP_KERNEL);
+ } else if (ieee80211_is_action(mgmt->frame_control)) {
++ if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
++ brcmf_err("invalid action frame length\n");
++ err = -EINVAL;
++ goto exit;
++ }
+ af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
+ if (af_params == NULL) {
+ brcmf_err("unable to allocate frame\n");
--- /dev/null
+From ec8add2a4c9df723c94a863b8fcd6d93c472deed Mon Sep 17 00:00:00 2001
+From: Sabrina Dubroca <sd@queasysnail.net>
+Date: Thu, 29 Jun 2017 16:56:54 +0200
+Subject: ipv6: dad: don't remove dynamic addresses if link is down
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+commit ec8add2a4c9df723c94a863b8fcd6d93c472deed upstream.
+
+Currently, when the link for $DEV is down, this command succeeds but the
+address is removed immediately by DAD (1):
+
+ ip addr add 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800
+
+In the same situation, this will succeed and not remove the address (2):
+
+ ip addr add 1111::12/64 dev $DEV
+ ip addr change 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800
+
+The comment in addrconf_dad_begin() when !IF_READY makes it look like
+this is the intended behavior, but doesn't explain why:
+
+ * If the device is not ready:
+ * - keep it tentative if it is a permanent address.
+ * - otherwise, kill it.
+
+We clearly cannot prevent userspace from doing (2), but we can make (1)
+work consistently with (2).
+
+addrconf_dad_stop() is only called in two cases: if DAD failed, or to
+skip DAD when the link is down. In that second case, the fix is to avoid
+deleting the address, like we already do for permanent addresses.
+
+Fixes: 3c21edbd1137 ("[IPV6]: Defer IPv6 device initialization until the link becomes ready.")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv6/addrconf.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1772,17 +1772,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
+
+ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
+ {
+- if (ifp->flags&IFA_F_PERMANENT) {
+- spin_lock_bh(&ifp->lock);
+- addrconf_del_dad_work(ifp);
+- ifp->flags |= IFA_F_TENTATIVE;
+- if (dad_failed)
+- ifp->flags |= IFA_F_DADFAILED;
+- spin_unlock_bh(&ifp->lock);
+- if (dad_failed)
+- ipv6_ifa_notify(0, ifp);
+- in6_ifa_put(ifp);
+- } else if (ifp->flags&IFA_F_TEMPORARY) {
++ if (ifp->flags&IFA_F_TEMPORARY) {
+ struct inet6_ifaddr *ifpub;
+ spin_lock_bh(&ifp->lock);
+ ifpub = ifp->ifpub;
+@@ -1795,6 +1785,16 @@ static void addrconf_dad_stop(struct ine
+ spin_unlock_bh(&ifp->lock);
+ }
+ ipv6_del_addr(ifp);
++ } else if (ifp->flags&IFA_F_PERMANENT || !dad_failed) {
++ spin_lock_bh(&ifp->lock);
++ addrconf_del_dad_work(ifp);
++ ifp->flags |= IFA_F_TENTATIVE;
++ if (dad_failed)
++ ifp->flags |= IFA_F_DADFAILED;
++ spin_unlock_bh(&ifp->lock);
++ if (dad_failed)
++ ipv6_ifa_notify(0, ifp);
++ in6_ifa_put(ifp);
+ } else {
+ ipv6_del_addr(ifp);
+ }
--- /dev/null
+From f06b7549b79e29a672336d4e134524373fb7a232 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Wed, 5 Jul 2017 14:41:46 -0600
+Subject: net: ipv6: Compare lwstate in detecting duplicate nexthops
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: David Ahern <dsahern@gmail.com>
+
+commit f06b7549b79e29a672336d4e134524373fb7a232 upstream.
+
+Lennert reported a failure to add different mpls encaps in a multipath
+route:
+
+ $ ip -6 route add 1234::/16 \
+ nexthop encap mpls 10 via fe80::1 dev ens3 \
+ nexthop encap mpls 20 via fe80::1 dev ens3
+ RTNETLINK answers: File exists
+
+The problem is that the duplicate nexthop detection does not compare
+lwtunnel configuration. Add it.
+
+Fixes: 19e42e451506 ("ipv6: support for fib route lwtunnel encap attributes")
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Reported-by: João Taveira Araújo <joao.taveira@gmail.com>
+Reported-by: Lennert Buytenhek <buytenh@wantstofly.org>
+Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
+Tested-by: Lennert Buytenhek <buytenh@wantstofly.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/ip6_route.h | 8 ++++++++
+ net/ipv6/ip6_fib.c | 5 +----
+ net/ipv6/route.c | 8 +-------
+ 3 files changed, 10 insertions(+), 11 deletions(-)
+
+--- a/include/net/ip6_route.h
++++ b/include/net/ip6_route.h
+@@ -21,6 +21,7 @@ struct route_info {
+ #include <net/flow.h>
+ #include <net/ip6_fib.h>
+ #include <net/sock.h>
++#include <net/lwtunnel.h>
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
+ #include <linux/route.h>
+@@ -208,4 +209,11 @@ static inline struct in6_addr *rt6_nexth
+ return daddr;
+ }
+
++static inline bool rt6_duplicate_nexthop(struct rt6_info *a, struct rt6_info *b)
++{
++ return a->dst.dev == b->dst.dev &&
++ a->rt6i_idev == b->rt6i_idev &&
++ ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) &&
++ !lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate);
++}
+ #endif
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -767,10 +767,7 @@ static int fib6_add_rt2node(struct fib6_
+ goto next_iter;
+ }
+
+- if (iter->dst.dev == rt->dst.dev &&
+- iter->rt6i_idev == rt->rt6i_idev &&
+- ipv6_addr_equal(&iter->rt6i_gateway,
+- &rt->rt6i_gateway)) {
++ if (rt6_duplicate_nexthop(iter, rt)) {
+ if (rt->rt6i_nsiblings)
+ rt->rt6i_nsiblings = 0;
+ if (!(iter->rt6i_flags & RTF_EXPIRES))
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2833,17 +2833,11 @@ static int ip6_route_info_append(struct
+ struct rt6_info *rt, struct fib6_config *r_cfg)
+ {
+ struct rt6_nh *nh;
+- struct rt6_info *rtnh;
+ int err = -EEXIST;
+
+ list_for_each_entry(nh, rt6_nh_list, next) {
+ /* check if rt6_info already exists */
+- rtnh = nh->rt6_info;
+-
+- if (rtnh->dst.dev == rt->dst.dev &&
+- rtnh->rt6i_idev == rt->rt6i_idev &&
+- ipv6_addr_equal(&rtnh->rt6i_gateway,
+- &rt->rt6i_gateway))
++ if (rt6_duplicate_nexthop(nh->rt6_info, rt))
+ return err;
+ }
+
--- /dev/null
+From 0933a578cd55b02dc80f219dc8f2efb17ec61c9a Mon Sep 17 00:00:00 2001
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Date: Thu, 6 Jul 2017 08:15:06 -0700
+Subject: rds: tcp: use sock_create_lite() to create the accept socket
+
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+
+commit 0933a578cd55b02dc80f219dc8f2efb17ec61c9a upstream.
+
+There are two problems with calling sock_create_kern() from
+rds_tcp_accept_one()
+1. it sets up a new_sock->sk that is wasteful, because this ->sk
+ is going to get replaced by inet_accept() in the subsequent ->accept()
+2. The new_sock->sk is a leaked reference in sock_graft() which
+ expects to find a null parent->sk
+
+Avoid these problems by calling sock_create_lite().
+
+Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rds/tcp_listen.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/rds/tcp_listen.c
++++ b/net/rds/tcp_listen.c
+@@ -78,7 +78,7 @@ int rds_tcp_accept_one(struct socket *so
+ struct inet_sock *inet;
+ struct rds_tcp_connection *rs_tcp;
+
+- ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family,
++ ret = sock_create_lite(sock->sk->sk_family,
+ sock->sk->sk_type, sock->sk->sk_protocol,
+ &new_sock);
+ if (ret)
net-prevent-sign-extension-in-dev_get_stats.patch
bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch
net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch
+ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
+net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch
+vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch
+rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch
+brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch
--- /dev/null
+From f630c38ef0d785101363a8992bbd4f302180f86f Mon Sep 17 00:00:00 2001
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Date: Thu, 6 Jul 2017 15:24:40 +0300
+Subject: vrf: fix bug_on triggered by rx when destroying a vrf
+
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+
+commit f630c38ef0d785101363a8992bbd4f302180f86f upstream.
+
+When destroying a VRF device we cleanup the slaves in its ndo_uninit()
+function, but that causes packets to be switched (skb->dev == vrf being
+destroyed) even though we're pass the point where the VRF should be
+receiving any packets while it is being dismantled. This causes a BUG_ON
+to trigger if we have raw sockets (trace below).
+The reason is that the inetdev of the VRF has been destroyed but we're
+still sending packets up the stack with it, so let's free the slaves in
+the dellink callback as David Ahern suggested.
+
+Note that this fix doesn't prevent packets from going up when the VRF
+device is admin down.
+
+[ 35.631371] ------------[ cut here ]------------
+[ 35.631603] kernel BUG at net/ipv4/fib_frontend.c:285!
+[ 35.631854] invalid opcode: 0000 [#1] SMP
+[ 35.631977] Modules linked in:
+[ 35.632081] CPU: 2 PID: 22 Comm: ksoftirqd/2 Not tainted 4.12.0-rc7+ #45
+[ 35.632247] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
+[ 35.632477] task: ffff88005ad68000 task.stack: ffff88005ad64000
+[ 35.632632] RIP: 0010:fib_compute_spec_dst+0xfc/0x1ee
+[ 35.632769] RSP: 0018:ffff88005ad67978 EFLAGS: 00010202
+[ 35.632910] RAX: 0000000000000001 RBX: ffff880059a7f200 RCX: 0000000000000000
+[ 35.633084] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff82274af0
+[ 35.633256] RBP: ffff88005ad679f8 R08: 000000000001ef70 R09: 0000000000000046
+[ 35.633430] R10: ffff88005ad679f8 R11: ffff880037731cb0 R12: 0000000000000001
+[ 35.633603] R13: ffff8800599e3000 R14: 0000000000000000 R15: ffff8800599cb852
+[ 35.634114] FS: 0000000000000000(0000) GS:ffff88005d900000(0000) knlGS:0000000000000000
+[ 35.634306] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 35.634456] CR2: 00007f3563227095 CR3: 000000000201d000 CR4: 00000000000406e0
+[ 35.634632] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 35.634865] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 35.635055] Call Trace:
+[ 35.635271] ? __lock_acquire+0xf0d/0x1117
+[ 35.635522] ipv4_pktinfo_prepare+0x82/0x151
+[ 35.635831] raw_rcv_skb+0x17/0x3c
+[ 35.636062] raw_rcv+0xe5/0xf7
+[ 35.636287] raw_local_deliver+0x169/0x1d9
+[ 35.636534] ip_local_deliver_finish+0x87/0x1c4
+[ 35.636820] ip_local_deliver+0x63/0x7f
+[ 35.637058] ip_rcv_finish+0x340/0x3a1
+[ 35.637295] ip_rcv+0x314/0x34a
+[ 35.637525] __netif_receive_skb_core+0x49f/0x7c5
+[ 35.637780] ? lock_acquire+0x13f/0x1d7
+[ 35.638018] ? lock_acquire+0x15e/0x1d7
+[ 35.638259] __netif_receive_skb+0x1e/0x94
+[ 35.638502] ? __netif_receive_skb+0x1e/0x94
+[ 35.638748] netif_receive_skb_internal+0x74/0x300
+[ 35.639002] ? dev_gro_receive+0x2ed/0x411
+[ 35.639246] ? lock_is_held_type+0xc4/0xd2
+[ 35.639491] napi_gro_receive+0x105/0x1a0
+[ 35.639736] receive_buf+0xc32/0xc74
+[ 35.639965] ? detach_buf+0x67/0x153
+[ 35.640201] ? virtqueue_get_buf_ctx+0x120/0x176
+[ 35.640453] virtnet_poll+0x128/0x1c5
+[ 35.640690] net_rx_action+0x103/0x343
+[ 35.640932] __do_softirq+0x1c7/0x4b7
+[ 35.641171] run_ksoftirqd+0x23/0x5c
+[ 35.641403] smpboot_thread_fn+0x24f/0x26d
+[ 35.641646] ? sort_range+0x22/0x22
+[ 35.641878] kthread+0x129/0x131
+[ 35.642104] ? __list_add+0x31/0x31
+[ 35.642335] ? __list_add+0x31/0x31
+[ 35.642568] ret_from_fork+0x2a/0x40
+[ 35.642804] Code: 05 bd 87 a3 00 01 e8 1f ef 98 ff 4d 85 f6 48 c7 c7 f0 4a 27 82 41 0f 94 c4 31 c9 31 d2 41 0f b6 f4 e8 04 71 a1 ff 45 84 e4 74 02 <0f> 0b 0f b7 93 c4 00 00 00 4d 8b a5 80 05 00 00 48 03 93 d0 00
+[ 35.644342] RIP: fib_compute_spec_dst+0xfc/0x1ee RSP: ffff88005ad67978
+
+Fixes: 193125dbd8eb ("net: Introduce VRF device driver")
+Reported-by: Chris Cormier <chriscormier@cumulusnetworks.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Acked-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[backport to 4.4 - gregkh]
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/vrf.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -733,15 +733,15 @@ static int vrf_del_slave(struct net_devi
+ static void vrf_dev_uninit(struct net_device *dev)
+ {
+ struct net_vrf *vrf = netdev_priv(dev);
+- struct slave_queue *queue = &vrf->queue;
+- struct list_head *head = &queue->all_slaves;
+- struct slave *slave, *next;
++// struct slave_queue *queue = &vrf->queue;
++// struct list_head *head = &queue->all_slaves;
++// struct slave *slave, *next;
+
+ vrf_rtable_destroy(vrf);
+ vrf_rt6_destroy(vrf);
+
+- list_for_each_entry_safe(slave, next, head, list)
+- vrf_del_slave(dev, slave->dev);
++// list_for_each_entry_safe(slave, next, head, list)
++// vrf_del_slave(dev, slave->dev);
+
+ free_percpu(dev->dstats);
+ dev->dstats = NULL;
+@@ -914,6 +914,14 @@ static int vrf_validate(struct nlattr *t
+
+ static void vrf_dellink(struct net_device *dev, struct list_head *head)
+ {
++ struct net_vrf *vrf = netdev_priv(dev);
++ struct slave_queue *queue = &vrf->queue;
++ struct list_head *all_slaves = &queue->all_slaves;
++ struct slave *slave, *next;
++
++ list_for_each_entry_safe(slave, next, all_slaves, list)
++ vrf_del_slave(dev, slave->dev);
++
+ unregister_netdevice_queue(dev, head);
+ }
+