]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Jul 2017 09:38:55 +0000 (11:38 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Jul 2017 09:38:55 +0000 (11:38 +0200)
added patches:
brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch
ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch
rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch
vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch

queue-4.4/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch [new file with mode: 0644]
queue-4.4/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch [new file with mode: 0644]
queue-4.4/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch [new file with mode: 0644]
queue-4.4/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch [new file with mode: 0644]

diff --git a/queue-4.4/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch b/queue-4.4/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch
new file mode 100644 (file)
index 0000000..4899197
--- /dev/null
@@ -0,0 +1,45 @@
+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");
diff --git a/queue-4.4/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch b/queue-4.4/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
new file mode 100644 (file)
index 0000000..c3cffb7
--- /dev/null
@@ -0,0 +1,80 @@
+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);
+       }
diff --git a/queue-4.4/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch b/queue-4.4/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch
new file mode 100644 (file)
index 0000000..e664de4
--- /dev/null
@@ -0,0 +1,95 @@
+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;
+       }
diff --git a/queue-4.4/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch b/queue-4.4/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch
new file mode 100644 (file)
index 0000000..ef670af
--- /dev/null
@@ -0,0 +1,38 @@
+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)
index 14b147e0a5f6959c5e23153c490137c670593daa..12a3e21dd75b7f1f0da2cf038cee17e7ac8f903e 100644 (file)
@@ -7,3 +7,8 @@ tcp-reset-sk_rx_dst-in-tcp_disconnect.patch
 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
diff --git a/queue-4.4/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch b/queue-4.4/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch
new file mode 100644 (file)
index 0000000..293defc
--- /dev/null
@@ -0,0 +1,125 @@
+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);
+ }