From: Greg Kroah-Hartman Date: Tue, 18 Jul 2017 09:52:44 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.12.3~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8c2865adaea963ea6a237b686a53b26b8a089203;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch sfc-don-t-read-beyond-unicast-address-list.patch vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch vxlan-fix-hlist-corruption.patch --- diff --git a/queue-4.9/brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch b/queue-4.9/brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch new file mode 100644 index 00000000000..ca39cb4cfaa --- /dev/null +++ b/queue-4.9/brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch @@ -0,0 +1,40 @@ +From 57c00f2fac512837f8de73474ec1f54020015bae Mon Sep 17 00:00:00 2001 +From: Christophe Jaillet +Date: Wed, 21 Jun 2017 07:45:53 +0200 +Subject: brcmfmac: Fix a memory leak in error handling path in 'brcmf_cfg80211_attach' + +From: Christophe Jaillet + +commit 57c00f2fac512837f8de73474ec1f54020015bae upstream. + +If 'wiphy_new()' fails, we leak 'ops'. Add a new label in the error +handling path to free it in such a case. + +Fixes: 5c22fb85102a7 ("brcmfmac: add wowl gtk rekeying offload support") +Signed-off-by: Christophe JAILLET +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6876,7 +6876,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info)); + if (!wiphy) { + brcmf_err("Could not allocate wiphy device\n"); +- return NULL; ++ goto ops_out; + } + memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN); + set_wiphy_dev(wiphy, busdev); +@@ -7010,6 +7010,7 @@ priv_out: + ifp->vif = NULL; + wiphy_out: + brcmf_free_wiphy(wiphy); ++ops_out: + kfree(ops); + return NULL; + } diff --git a/queue-4.9/brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch b/queue-4.9/brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch new file mode 100644 index 00000000000..6bfe5e31822 --- /dev/null +++ b/queue-4.9/brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch @@ -0,0 +1,58 @@ +From 5ea59db8a375216e6c915c5586f556766673b5a7 Mon Sep 17 00:00:00 2001 +From: "Peter S. Housel" +Date: Mon, 12 Jun 2017 11:46:22 +0100 +Subject: brcmfmac: Fix glom_skb leak in brcmf_sdiod_recv_chain + +From: Peter S. Housel + +commit 5ea59db8a375216e6c915c5586f556766673b5a7 upstream. + +An earlier change to this function (3bdae810721b) fixed a leak in the +case of an unsuccessful call to brcmf_sdiod_buffrw(). However, the +glom_skb buffer, used for emulating a scattering read, is never used +or referenced after its contents are copied into the destination +buffers, and therefore always needs to be freed by the end of the +function. + +Fixes: 3bdae810721b ("brcmfmac: Fix glob_skb leak in brcmf_sdiod_recv_chain") +Fixes: a413e39a38573 ("brcmfmac: fix brcmf_sdcard_recv_chain() for host without sg support") +Signed-off-by: Peter S. Housel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -705,7 +705,7 @@ done: + int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, + struct sk_buff_head *pktq, uint totlen) + { +- struct sk_buff *glom_skb; ++ struct sk_buff *glom_skb = NULL; + struct sk_buff *skb; + u32 addr = sdiodev->sbwad; + int err = 0; +@@ -726,10 +726,8 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + return -ENOMEM; + err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, + glom_skb); +- if (err) { +- brcmu_pkt_buf_free_skb(glom_skb); ++ if (err) + goto done; +- } + + skb_queue_walk(pktq, skb) { + memcpy(skb->data, glom_skb->data, skb->len); +@@ -740,6 +738,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + pktq); + + done: ++ brcmu_pkt_buf_free_skb(glom_skb); + return err; + } + diff --git a/queue-4.9/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch b/queue-4.9/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch new file mode 100644 index 00000000000..37b43019ad9 --- /dev/null +++ b/queue-4.9/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch @@ -0,0 +1,45 @@ +From 8f44c9a41386729fea410e688959ddaa9d51be7c Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +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 + +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(郭大兴)" +Signed-off-by: Arend van Spriel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -4928,6 +4928,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.9/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch b/queue-4.9/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch new file mode 100644 index 00000000000..3eef138140c --- /dev/null +++ b/queue-4.9/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch @@ -0,0 +1,76 @@ +From ec8add2a4c9df723c94a863b8fcd6d93c472deed Mon Sep 17 00:00:00 2001 +From: Sabrina Dubroca +Date: Thu, 29 Jun 2017 16:56:54 +0200 +Subject: ipv6: dad: don't remove dynamic addresses if link is down + +From: Sabrina Dubroca + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/addrconf.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1875,15 +1875,7 @@ static void addrconf_dad_stop(struct ine + if (dad_failed) + ifp->flags |= IFA_F_DADFAILED; + +- if (ifp->flags&IFA_F_PERMANENT) { +- spin_lock_bh(&ifp->lock); +- addrconf_del_dad_work(ifp); +- ifp->flags |= IFA_F_TENTATIVE; +- 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; +@@ -1896,6 +1888,14 @@ 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; ++ 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.9/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch b/queue-4.9/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch new file mode 100644 index 00000000000..6c06b36a057 --- /dev/null +++ b/queue-4.9/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch @@ -0,0 +1,174 @@ +From 9af9959e142c274f4a30fefb71d97d2b028b337f Mon Sep 17 00:00:00 2001 +From: Alban Browaeys +Date: Mon, 3 Jul 2017 03:20:13 +0200 +Subject: net: core: Fix slab-out-of-bounds in netdev_stats_to_stats64 + +From: Alban Browaeys + +commit 9af9959e142c274f4a30fefb71d97d2b028b337f upstream. + +commit 9256645af098 ("net/core: relax BUILD_BUG_ON in +netdev_stats_to_stats64") made an attempt to read beyond +the size of the source a possibility. + +Fix to only copy src size to dest. As dest might be bigger than src. + + ================================================================== + BUG: KASAN: slab-out-of-bounds in netdev_stats_to_stats64+0xe/0x30 at addr ffff8801be248b20 + Read of size 192 by task VBoxNetAdpCtl/6734 + CPU: 1 PID: 6734 Comm: VBoxNetAdpCtl Tainted: G O 4.11.4prahal+intel+ #118 + Hardware name: LENOVO 20CDCTO1WW/20CDCTO1WW, BIOS GQET52WW (1.32 ) 05/04/2017 + Call Trace: + dump_stack+0x63/0x86 + kasan_object_err+0x1c/0x70 + kasan_report+0x270/0x520 + ? netdev_stats_to_stats64+0xe/0x30 + ? sched_clock_cpu+0x1b/0x190 + ? __module_address+0x3e/0x3b0 + ? unwind_next_frame+0x1ea/0xb00 + check_memory_region+0x13c/0x1a0 + memcpy+0x23/0x50 + netdev_stats_to_stats64+0xe/0x30 + dev_get_stats+0x1b9/0x230 + rtnl_fill_stats+0x44/0xc00 + ? nla_put+0xc6/0x130 + rtnl_fill_ifinfo+0xe9e/0x3700 + ? rtnl_fill_vfinfo+0xde0/0xde0 + ? sched_clock+0x9/0x10 + ? sched_clock+0x9/0x10 + ? sched_clock_local+0x120/0x130 + ? __module_address+0x3e/0x3b0 + ? unwind_next_frame+0x1ea/0xb00 + ? sched_clock+0x9/0x10 + ? sched_clock+0x9/0x10 + ? sched_clock_cpu+0x1b/0x190 + ? VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp] + ? depot_save_stack+0x1d8/0x4a0 + ? depot_save_stack+0x34f/0x4a0 + ? depot_save_stack+0x34f/0x4a0 + ? save_stack+0xb1/0xd0 + ? save_stack_trace+0x16/0x20 + ? save_stack+0x46/0xd0 + ? kasan_slab_alloc+0x12/0x20 + ? __kmalloc_node_track_caller+0x10d/0x350 + ? __kmalloc_reserve.isra.36+0x2c/0xc0 + ? __alloc_skb+0xd0/0x560 + ? rtmsg_ifinfo_build_skb+0x61/0x120 + ? rtmsg_ifinfo.part.25+0x16/0xb0 + ? rtmsg_ifinfo+0x47/0x70 + ? register_netdev+0x15/0x30 + ? vboxNetAdpOsCreate+0xc0/0x1c0 [vboxnetadp] + ? vboxNetAdpCreate+0x210/0x400 [vboxnetadp] + ? VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp] + ? do_vfs_ioctl+0x17f/0xff0 + ? SyS_ioctl+0x74/0x80 + ? do_syscall_64+0x182/0x390 + ? __alloc_skb+0xd0/0x560 + ? __alloc_skb+0xd0/0x560 + ? save_stack_trace+0x16/0x20 + ? init_object+0x64/0xa0 + ? ___slab_alloc+0x1ae/0x5c0 + ? ___slab_alloc+0x1ae/0x5c0 + ? __alloc_skb+0xd0/0x560 + ? sched_clock+0x9/0x10 + ? kasan_unpoison_shadow+0x35/0x50 + ? kasan_kmalloc+0xad/0xe0 + ? __kmalloc_node_track_caller+0x246/0x350 + ? __alloc_skb+0xd0/0x560 + ? kasan_unpoison_shadow+0x35/0x50 + ? memset+0x31/0x40 + ? __alloc_skb+0x31f/0x560 + ? napi_consume_skb+0x320/0x320 + ? br_get_link_af_size_filtered+0xb7/0x120 [bridge] + ? if_nlmsg_size+0x440/0x630 + rtmsg_ifinfo_build_skb+0x83/0x120 + rtmsg_ifinfo.part.25+0x16/0xb0 + rtmsg_ifinfo+0x47/0x70 + register_netdevice+0xa2b/0xe50 + ? __kmalloc+0x171/0x2d0 + ? netdev_change_features+0x80/0x80 + register_netdev+0x15/0x30 + vboxNetAdpOsCreate+0xc0/0x1c0 [vboxnetadp] + vboxNetAdpCreate+0x210/0x400 [vboxnetadp] + ? vboxNetAdpComposeMACAddress+0x1d0/0x1d0 [vboxnetadp] + ? kasan_check_write+0x14/0x20 + VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp] + ? VBoxNetAdpLinuxOpen+0x20/0x20 [vboxnetadp] + ? lock_acquire+0x11c/0x270 + ? __audit_syscall_entry+0x2fb/0x660 + do_vfs_ioctl+0x17f/0xff0 + ? __audit_syscall_entry+0x2fb/0x660 + ? ioctl_preallocate+0x1d0/0x1d0 + ? __audit_syscall_entry+0x2fb/0x660 + ? kmem_cache_free+0xb2/0x250 + ? syscall_trace_enter+0x537/0xd00 + ? exit_to_usermode_loop+0x100/0x100 + SyS_ioctl+0x74/0x80 + ? do_sys_open+0x350/0x350 + ? do_vfs_ioctl+0xff0/0xff0 + do_syscall_64+0x182/0x390 + entry_SYSCALL64_slow_path+0x25/0x25 + RIP: 0033:0x7f7e39a1ae07 + RSP: 002b:00007ffc6f04c6d8 EFLAGS: 00000206 ORIG_RAX: 0000000000000010 + RAX: ffffffffffffffda RBX: 00007ffc6f04c730 RCX: 00007f7e39a1ae07 + RDX: 00007ffc6f04c730 RSI: 00000000c0207601 RDI: 0000000000000007 + RBP: 00007ffc6f04c700 R08: 00007ffc6f04c780 R09: 0000000000000008 + R10: 0000000000000541 R11: 0000000000000206 R12: 0000000000000007 + R13: 00000000c0207601 R14: 00007ffc6f04c730 R15: 0000000000000012 + Object at ffff8801be248008, in cache kmalloc-4096 size: 4096 + Allocated: + PID = 6734 + save_stack_trace+0x16/0x20 + save_stack+0x46/0xd0 + kasan_kmalloc+0xad/0xe0 + __kmalloc+0x171/0x2d0 + alloc_netdev_mqs+0x8a7/0xbe0 + vboxNetAdpOsCreate+0x65/0x1c0 [vboxnetadp] + vboxNetAdpCreate+0x210/0x400 [vboxnetadp] + VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp] + do_vfs_ioctl+0x17f/0xff0 + SyS_ioctl+0x74/0x80 + do_syscall_64+0x182/0x390 + return_from_SYSCALL_64+0x0/0x6a + Freed: + PID = 5600 + save_stack_trace+0x16/0x20 + save_stack+0x46/0xd0 + kasan_slab_free+0x73/0xc0 + kfree+0xe4/0x220 + kvfree+0x25/0x30 + single_release+0x74/0xb0 + __fput+0x265/0x6b0 + ____fput+0x9/0x10 + task_work_run+0xd5/0x150 + exit_to_usermode_loop+0xe2/0x100 + do_syscall_64+0x26c/0x390 + return_from_SYSCALL_64+0x0/0x6a + Memory state around the buggy address: + ffff8801be248a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff8801be248b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + >ffff8801be248b80: 00 00 00 00 00 00 00 00 00 00 00 07 fc fc fc fc + ^ + ffff8801be248c00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ffff8801be248c80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ================================================================== + +Signed-off-by: Alban Browaeys +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -7531,7 +7531,7 @@ void netdev_stats_to_stats64(struct rtnl + { + #if BITS_PER_LONG == 64 + BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats)); +- memcpy(stats64, netdev_stats, sizeof(*stats64)); ++ memcpy(stats64, netdev_stats, sizeof(*netdev_stats)); + /* zero out counters that only exist in rtnl_link_stats64 */ + memset((char *)stats64 + sizeof(*netdev_stats), 0, + sizeof(*stats64) - sizeof(*netdev_stats)); diff --git a/queue-4.9/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch b/queue-4.9/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch new file mode 100644 index 00000000000..558fb055020 --- /dev/null +++ b/queue-4.9/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch @@ -0,0 +1,95 @@ +From f06b7549b79e29a672336d4e134524373fb7a232 Mon Sep 17 00:00:00 2001 +From: David Ahern +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 + +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 +Reported-by: João Taveira Araújo +Reported-by: Lennert Buytenhek +Acked-by: Roopa Prabhu +Tested-by: Lennert Buytenhek +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -22,6 +22,7 @@ struct route_info { + #include + #include + #include ++#include + #include + #include + #include +@@ -232,4 +233,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 +@@ -771,10 +771,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 +@@ -2953,17 +2953,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.9/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch b/queue-4.9/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch new file mode 100644 index 00000000000..d6b1db42e94 --- /dev/null +++ b/queue-4.9/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch @@ -0,0 +1,32 @@ +From 8ff93de7668bd81bc8efa819d1184ebd48fae72d Mon Sep 17 00:00:00 2001 +From: Gal Pressman +Date: Sun, 25 Jun 2017 16:46:25 +0300 +Subject: net/mlx5e: Fix TX carrier errors report in get stats ndo + +From: Gal Pressman + +commit 8ff93de7668bd81bc8efa819d1184ebd48fae72d upstream. + +Symbol error during carrier counter from PPCNT was mistakenly reported as +TX carrier errors in get_stats ndo, although it's an RX counter. + +Fixes: 269e6b3af3bf ("net/mlx5e: Report additional error statistics in get stats ndo") +Signed-off-by: Gal Pressman +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -2671,8 +2671,6 @@ mlx5e_get_stats(struct net_device *dev, + PPORT_802_3_GET(pstats, a_frame_check_sequence_errors); + stats->rx_frame_errors = PPORT_802_3_GET(pstats, a_alignment_errors); + stats->tx_aborted_errors = PPORT_2863_GET(pstats, if_out_discards); +- stats->tx_carrier_errors = +- PPORT_802_3_GET(pstats, a_symbol_error_during_carrier); + stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors + + stats->rx_frame_errors; + stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors; diff --git a/queue-4.9/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch b/queue-4.9/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch new file mode 100644 index 00000000000..d51e91ac238 --- /dev/null +++ b/queue-4.9/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch @@ -0,0 +1,38 @@ +From 0933a578cd55b02dc80f219dc8f2efb17ec61c9a Mon Sep 17 00:00:00 2001 +From: Sowmini Varadhan +Date: Thu, 6 Jul 2017 08:15:06 -0700 +Subject: rds: tcp: use sock_create_lite() to create the accept socket + +From: Sowmini Varadhan + +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 +Acked-by: Santosh Shilimkar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -129,7 +129,7 @@ int rds_tcp_accept_one(struct socket *so + if (!sock) /* module unload or netns delete in progress */ + return -ENETUNREACH; + +- 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) diff --git a/queue-4.9/series b/queue-4.9/series index bf49ecaa937..1263b7add86 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -12,3 +12,14 @@ bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch liquidio-fix-bug-in-soft-reset-failure-detection.patch +net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch +ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch +vxlan-fix-hlist-corruption.patch +net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.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 +brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch +brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch +sfc-don-t-read-beyond-unicast-address-list.patch diff --git a/queue-4.9/sfc-don-t-read-beyond-unicast-address-list.patch b/queue-4.9/sfc-don-t-read-beyond-unicast-address-list.patch new file mode 100644 index 00000000000..c3c551be858 --- /dev/null +++ b/queue-4.9/sfc-don-t-read-beyond-unicast-address-list.patch @@ -0,0 +1,62 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Bert Kenward +Date: Wed, 12 Jul 2017 17:19:41 +0100 +Subject: sfc: don't read beyond unicast address list + +From: Bert Kenward + + +[ Upstream commit c70d68150f71b84cea6997a53493e17bf18a54db ] + +If we have more than 32 unicast MAC addresses assigned to an interface +we will read beyond the end of the address table in the driver when +adding filters. The next 256 entries store multicast addresses, so we +will end up attempting to insert duplicate filters, which is mostly +harmless. If we add more than 288 unicast addresses we will then read +past the multicast address table, which is likely to be more exciting. + +Fixes: 12fb0da45c9a ("sfc: clean fallbacks between promisc/normal in efx_ef10_filter_sync_rx_mode") +Signed-off-by: Bert Kenward +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/sfc/ef10.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/sfc/ef10.c ++++ b/drivers/net/ethernet/sfc/ef10.c +@@ -4399,12 +4399,9 @@ static void efx_ef10_filter_uc_addr_list + struct efx_ef10_filter_table *table = efx->filter_state; + struct net_device *net_dev = efx->net_dev; + struct netdev_hw_addr *uc; +- int addr_count; + unsigned int i; + +- addr_count = netdev_uc_count(net_dev); + table->uc_promisc = !!(net_dev->flags & IFF_PROMISC); +- table->dev_uc_count = 1 + addr_count; + ether_addr_copy(table->dev_uc_list[0].addr, net_dev->dev_addr); + i = 1; + netdev_for_each_uc_addr(uc, net_dev) { +@@ -4415,6 +4412,8 @@ static void efx_ef10_filter_uc_addr_list + ether_addr_copy(table->dev_uc_list[i].addr, uc->addr); + i++; + } ++ ++ table->dev_uc_count = i; + } + + static void efx_ef10_filter_mc_addr_list(struct efx_nic *efx) +@@ -4422,11 +4421,10 @@ static void efx_ef10_filter_mc_addr_list + struct efx_ef10_filter_table *table = efx->filter_state; + struct net_device *net_dev = efx->net_dev; + struct netdev_hw_addr *mc; +- unsigned int i, addr_count; ++ unsigned int i; + + table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI)); + +- addr_count = netdev_mc_count(net_dev); + i = 0; + netdev_for_each_mc_addr(mc, net_dev) { + if (i >= EFX_EF10_FILTER_DEV_MC_MAX) { diff --git a/queue-4.9/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch b/queue-4.9/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch new file mode 100644 index 00000000000..1657e79940b --- /dev/null +++ b/queue-4.9/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch @@ -0,0 +1,117 @@ +From f630c38ef0d785101363a8992bbd4f302180f86f Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Thu, 6 Jul 2017 15:24:40 +0300 +Subject: vrf: fix bug_on triggered by rx when destroying a vrf + +From: Nikolay Aleksandrov + +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 +Signed-off-by: Nikolay Aleksandrov +Acked-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/vrf.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -787,15 +787,10 @@ 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 net_device *port_dev; +- struct list_head *iter; + + vrf_rtable_release(dev, vrf); + vrf_rt6_release(dev, vrf); + +- netdev_for_each_lower_dev(dev, port_dev, iter) +- vrf_del_slave(dev, port_dev); +- + free_percpu(dev->dstats); + dev->dstats = NULL; + } +@@ -1232,6 +1227,12 @@ static int vrf_validate(struct nlattr *t + + static void vrf_dellink(struct net_device *dev, struct list_head *head) + { ++ struct net_device *port_dev; ++ struct list_head *iter; ++ ++ netdev_for_each_lower_dev(dev, port_dev, iter) ++ vrf_del_slave(dev, port_dev); ++ + unregister_netdevice_queue(dev, head); + } + diff --git a/queue-4.9/vxlan-fix-hlist-corruption.patch b/queue-4.9/vxlan-fix-hlist-corruption.patch new file mode 100644 index 00000000000..76cee4d32d6 --- /dev/null +++ b/queue-4.9/vxlan-fix-hlist-corruption.patch @@ -0,0 +1,119 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Jiri Benc +Date: Sun, 2 Jul 2017 19:00:57 +0200 +Subject: vxlan: fix hlist corruption + +From: Jiri Benc + + +[ Upstream commit 69e766612c4bcb79e19cebed9eed61d4222c1d47 ] + +It's not a good idea to add the same hlist_node to two different hash lists. +This leads to various hard to debug memory corruptions. + +Fixes: b1be00a6c39f ("vxlan: support both IPv4 and IPv6 sockets in a single vxlan device") +Signed-off-by: Jiri Benc +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan.c | 30 ++++++++++++++++++++---------- + include/net/vxlan.h | 10 +++++++++- + 2 files changed, 29 insertions(+), 11 deletions(-) + +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -227,15 +227,15 @@ static struct vxlan_sock *vxlan_find_soc + + static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, __be32 vni) + { +- struct vxlan_dev *vxlan; ++ struct vxlan_dev_node *node; + + /* For flow based devices, map all packets to VNI 0 */ + if (vs->flags & VXLAN_F_COLLECT_METADATA) + vni = 0; + +- hlist_for_each_entry_rcu(vxlan, vni_head(vs, vni), hlist) { +- if (vxlan->default_dst.remote_vni == vni) +- return vxlan; ++ hlist_for_each_entry_rcu(node, vni_head(vs, vni), hlist) { ++ if (node->vxlan->default_dst.remote_vni == vni) ++ return node->vxlan; + } + + return NULL; +@@ -2309,17 +2309,22 @@ static void vxlan_vs_del_dev(struct vxla + struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); + + spin_lock(&vn->sock_lock); +- hlist_del_init_rcu(&vxlan->hlist); ++ hlist_del_init_rcu(&vxlan->hlist4.hlist); ++#if IS_ENABLED(CONFIG_IPV6) ++ hlist_del_init_rcu(&vxlan->hlist6.hlist); ++#endif + spin_unlock(&vn->sock_lock); + } + +-static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan) ++static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan, ++ struct vxlan_dev_node *node) + { + struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); + __be32 vni = vxlan->default_dst.remote_vni; + ++ node->vxlan = vxlan; + spin_lock(&vn->sock_lock); +- hlist_add_head_rcu(&vxlan->hlist, vni_head(vs, vni)); ++ hlist_add_head_rcu(&node->hlist, vni_head(vs, vni)); + spin_unlock(&vn->sock_lock); + } + +@@ -2778,6 +2783,7 @@ static int __vxlan_sock_add(struct vxlan + { + struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id); + struct vxlan_sock *vs = NULL; ++ struct vxlan_dev_node *node; + + if (!vxlan->cfg.no_share) { + spin_lock(&vn->sock_lock); +@@ -2795,12 +2801,16 @@ static int __vxlan_sock_add(struct vxlan + if (IS_ERR(vs)) + return PTR_ERR(vs); + #if IS_ENABLED(CONFIG_IPV6) +- if (ipv6) ++ if (ipv6) { + rcu_assign_pointer(vxlan->vn6_sock, vs); +- else ++ node = &vxlan->hlist6; ++ } else + #endif ++ { + rcu_assign_pointer(vxlan->vn4_sock, vs); +- vxlan_vs_add_dev(vs, vxlan); ++ node = &vxlan->hlist4; ++ } ++ vxlan_vs_add_dev(vs, vxlan, node); + return 0; + } + +--- a/include/net/vxlan.h ++++ b/include/net/vxlan.h +@@ -221,9 +221,17 @@ struct vxlan_config { + bool no_share; + }; + ++struct vxlan_dev_node { ++ struct hlist_node hlist; ++ struct vxlan_dev *vxlan; ++}; ++ + /* Pseudo network device */ + struct vxlan_dev { +- struct hlist_node hlist; /* vni hash table */ ++ struct vxlan_dev_node hlist4; /* vni hash table for IPv4 socket */ ++#if IS_ENABLED(CONFIG_IPV6) ++ struct vxlan_dev_node hlist6; /* vni hash table for IPv6 socket */ ++#endif + struct list_head next; /* vxlan's per namespace list */ + struct vxlan_sock __rcu *vn4_sock; /* listening socket for IPv4 */ + #if IS_ENABLED(CONFIG_IPV6)