From: Greg Kroah-Hartman Date: Mon, 17 Jul 2017 16:51:19 +0000 (+0200) Subject: 4.11-stable patches X-Git-Tag: v4.12.3~35 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=71a4ec43a0c0dfc35d8a78ae2ad45fb63a561f3c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.11-stable patches added patches: bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch geneve-fix-hlist-corruption.patch ipv6-avoid-unregistering-inet6_dev-for-loopback.patch ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch liquidio-fix-bug-in-soft-reset-failure-detection.patch mlxsw-spectrum_router-fix-null-pointer-dereference.patch net-account-for-current-skb-length-when-deciding-about-ufo.patch net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch net-dp83640-avoid-null-pointer-dereference.patch net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch net-phy-micrel-configure-intterupts-after-autoneg-workaround.patch net-prevent-sign-extension-in-dev_get_stats.patch net-sched-fix-one-possible-panic-when-no-destroy-callback.patch netvsc-don-t-access-netdev-num_rx_queues-directly.patch rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch rocker-move-dereference-before-free.patch sfc-don-t-read-beyond-unicast-address-list.patch sfc-fix-mcdi-command-size-for-filter-operations.patch tap-convert-a-mutex-to-a-spinlock.patch tcp-reset-sk_rx_dst-in-tcp_disconnect.patch virtio-net-serialize-tx-routine-during-reset.patch vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch vxlan-fix-hlist-corruption.patch --- diff --git a/queue-4.11/bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch b/queue-4.11/bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch new file mode 100644 index 00000000000..17f81b09625 --- /dev/null +++ b/queue-4.11/bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch @@ -0,0 +1,156 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Daniel Borkmann +Date: Thu, 29 Jun 2017 03:04:59 +0200 +Subject: bpf: prevent leaking pointer via xadd on unpriviledged + +From: Daniel Borkmann + + +[ Upstream commit 6bdf6abc56b53103324dfd270a86580306e1a232 ] + +Leaking kernel addresses on unpriviledged is generally disallowed, +for example, verifier rejects the following: + + 0: (b7) r0 = 0 + 1: (18) r2 = 0xffff897e82304400 + 3: (7b) *(u64 *)(r1 +48) = r2 + R2 leaks addr into ctx + +Doing pointer arithmetic on them is also forbidden, so that they +don't turn into unknown value and then get leaked out. However, +there's xadd as a special case, where we don't check the src reg +for being a pointer register, e.g. the following will pass: + + 0: (b7) r0 = 0 + 1: (7b) *(u64 *)(r1 +48) = r0 + 2: (18) r2 = 0xffff897e82304400 ; map + 4: (db) lock *(u64 *)(r1 +48) += r2 + 5: (95) exit + +We could store the pointer into skb->cb, loose the type context, +and then read it out from there again to leak it eventually out +of a map value. Or more easily in a different variant, too: + + 0: (bf) r6 = r1 + 1: (7a) *(u64 *)(r10 -8) = 0 + 2: (bf) r2 = r10 + 3: (07) r2 += -8 + 4: (18) r1 = 0x0 + 6: (85) call bpf_map_lookup_elem#1 + 7: (15) if r0 == 0x0 goto pc+3 + R0=map_value(ks=8,vs=8,id=0),min_value=0,max_value=0 R6=ctx R10=fp + 8: (b7) r3 = 0 + 9: (7b) *(u64 *)(r0 +0) = r3 + 10: (db) lock *(u64 *)(r0 +0) += r6 + 11: (b7) r0 = 0 + 12: (95) exit + + from 7 to 11: R0=inv,min_value=0,max_value=0 R6=ctx R10=fp + 11: (b7) r0 = 0 + 12: (95) exit + +Prevent this by checking xadd src reg for pointer types. Also +add a couple of test cases related to this. + +Fixes: 1be7f75d1668 ("bpf: enable non-root eBPF programs") +Fixes: 17a5267067f3 ("bpf: verifier (add verifier core)") +Signed-off-by: Daniel Borkmann +Acked-by: Alexei Starovoitov +Acked-by: Martin KaFai Lau +Acked-by: Edward Cree +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/verifier.c | 5 ++ + tools/testing/selftests/bpf/test_verifier.c | 66 ++++++++++++++++++++++++++++ + 2 files changed, 71 insertions(+) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -951,6 +951,11 @@ static int check_xadd(struct bpf_verifie + if (err) + return err; + ++ if (is_pointer_value(env, insn->src_reg)) { ++ verbose("R%d leaks addr into mem\n", insn->src_reg); ++ return -EACCES; ++ } ++ + /* check whether atomic_add can read the memory */ + err = check_mem_access(env, insn->dst_reg, insn->off, + BPF_SIZE(insn->code), BPF_READ, -1); +--- a/tools/testing/selftests/bpf/test_verifier.c ++++ b/tools/testing/selftests/bpf/test_verifier.c +@@ -3518,6 +3518,72 @@ static struct bpf_test tests[] = { + .errstr = "invalid bpf_context access", + }, + { ++ "leak pointer into ctx 1", ++ .insns = { ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, ++ offsetof(struct __sk_buff, cb[0])), ++ BPF_LD_MAP_FD(BPF_REG_2, 0), ++ BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_2, ++ offsetof(struct __sk_buff, cb[0])), ++ BPF_EXIT_INSN(), ++ }, ++ .fixup_map1 = { 2 }, ++ .errstr_unpriv = "R2 leaks addr into mem", ++ .result_unpriv = REJECT, ++ .result = ACCEPT, ++ }, ++ { ++ "leak pointer into ctx 2", ++ .insns = { ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, ++ offsetof(struct __sk_buff, cb[0])), ++ BPF_STX_XADD(BPF_DW, BPF_REG_1, BPF_REG_10, ++ offsetof(struct __sk_buff, cb[0])), ++ BPF_EXIT_INSN(), ++ }, ++ .errstr_unpriv = "R10 leaks addr into mem", ++ .result_unpriv = REJECT, ++ .result = ACCEPT, ++ }, ++ { ++ "leak pointer into ctx 3", ++ .insns = { ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_LD_MAP_FD(BPF_REG_2, 0), ++ BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, ++ offsetof(struct __sk_buff, cb[0])), ++ BPF_EXIT_INSN(), ++ }, ++ .fixup_map1 = { 1 }, ++ .errstr_unpriv = "R2 leaks addr into ctx", ++ .result_unpriv = REJECT, ++ .result = ACCEPT, ++ }, ++ { ++ "leak pointer into map val", ++ .insns = { ++ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), ++ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), ++ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), ++ BPF_LD_MAP_FD(BPF_REG_1, 0), ++ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, ++ BPF_FUNC_map_lookup_elem), ++ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), ++ BPF_MOV64_IMM(BPF_REG_3, 0), ++ BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), ++ BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_6, 0), ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .fixup_map1 = { 4 }, ++ .errstr_unpriv = "R6 leaks addr into mem", ++ .result_unpriv = REJECT, ++ .result = ACCEPT, ++ }, ++ { + "helper access to map: full range", + .insns = { + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), diff --git a/queue-4.11/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch b/queue-4.11/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch new file mode 100644 index 00000000000..9de2e5392cd --- /dev/null +++ b/queue-4.11/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch @@ -0,0 +1,43 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Arend van Spriel +Date: Fri, 7 Jul 2017 21:09:06 +0100 +Subject: brcmfmac: fix possible buffer overflow in brcmf_cfg80211_mgmt_tx() + +From: Arend van Spriel + + +[ Upstream commit 8f44c9a41386729fea410e688959ddaa9d51be7c ] + +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)); + +Cc: stable@vger.kernel.org # 3.9.x +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 +@@ -4835,6 +4835,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.11/bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch b/queue-4.11/bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch new file mode 100644 index 00000000000..021b91bdac1 --- /dev/null +++ b/queue-4.11/bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch @@ -0,0 +1,57 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Eduardo Valentin +Date: Tue, 11 Jul 2017 14:55:12 -0700 +Subject: bridge: mdb: fix leak on complete_info ptr on fail path + +From: Eduardo Valentin + + +[ Upstream commit 1bfb159673957644951ab0a8d2aec44b93ddb1ae ] + +We currently get the following kmemleak report: +unreferenced object 0xffff8800039d9820 (size 32): + comm "softirq", pid 0, jiffies 4295212383 (age 792.416s) + hex dump (first 32 bytes): + 00 0c e0 03 00 88 ff ff ff 02 00 00 00 00 00 00 ................ + 00 00 00 01 ff 11 00 02 86 dd 00 00 ff ff ff ff ................ + backtrace: + [] kmemleak_alloc+0x4a/0xa0 + [] kmem_cache_alloc_trace+0xb8/0x1c0 + [] __br_mdb_notify+0x2a3/0x300 [bridge] + [] br_mdb_notify+0x6e/0x70 [bridge] + [] br_multicast_add_group+0x109/0x150 [bridge] + [] br_ip6_multicast_add_group+0x58/0x60 [bridge] + [] br_multicast_rcv+0x1d5/0xdb0 [bridge] + [] br_handle_frame_finish+0xcf/0x510 [bridge] + [] br_nf_hook_thresh.part.27+0xb/0x10 [br_netfilter] + [] br_nf_hook_thresh+0x48/0xb0 [br_netfilter] + [] br_nf_pre_routing_finish_ipv6+0x109/0x1d0 [br_netfilter] + [] br_nf_pre_routing_ipv6+0xd0/0x14c [br_netfilter] + [] br_nf_pre_routing+0x197/0x3d0 [br_netfilter] + [] nf_iterate+0x52/0x60 + [] nf_hook_slow+0x5c/0xb0 + [] br_handle_frame+0x1a4/0x2c0 [bridge] + +This happens when switchdev_port_obj_add() fails. This patch +frees complete_info object in the fail path. + +Reviewed-by: Vallish Vaidyeshwara +Signed-off-by: Eduardo Valentin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_mdb.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/bridge/br_mdb.c ++++ b/net/bridge/br_mdb.c +@@ -323,7 +323,8 @@ static void __br_mdb_notify(struct net_d + __mdb_entry_to_br_ip(entry, &complete_info->ip); + mdb.obj.complete_priv = complete_info; + mdb.obj.complete = br_mdb_complete; +- switchdev_port_obj_add(port_dev, &mdb.obj); ++ if (switchdev_port_obj_add(port_dev, &mdb.obj)) ++ kfree(complete_info); + } + } else if (port_dev && type == RTM_DELMDB) { + switchdev_port_obj_del(port_dev, &mdb.obj); diff --git a/queue-4.11/cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch b/queue-4.11/cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch new file mode 100644 index 00000000000..3b555868285 --- /dev/null +++ b/queue-4.11/cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch @@ -0,0 +1,162 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: "Guilherme G. Piccoli" +Date: Mon, 10 Jul 2017 10:55:46 -0300 +Subject: cxgb4: fix BUG() on interrupt deallocating path of ULD + +From: "Guilherme G. Piccoli" + + +[ Upstream commit 6a146f3a5894b751cef16feb3d7903e45e3c445c ] + +Since the introduction of ULD (Upper-Layer Drivers), the MSI-X +deallocating path changed in cxgb4: the driver frees the interrupts +of ULD when unregistering it or on shutdown PCI handler. + +Problem is that if a MSI-X is not freed before deallocated in the PCI +layer, it will trigger a BUG() due to still "alive" interrupt being +tentatively quiesced. + +The below trace was observed when doing a simple unbind of Chelsio's +adapter PCI function, like: + "echo 001e:80:00.4 > /sys/bus/pci/drivers/cxgb4/unbind" + +Trace: + + kernel BUG at drivers/pci/msi.c:352! + Oops: Exception in kernel mode, sig: 5 [#1] + ... + NIP [c0000000005a5e60] free_msi_irqs+0xa0/0x250 + LR [c0000000005a5e50] free_msi_irqs+0x90/0x250 + Call Trace: + [c0000000005a5e50] free_msi_irqs+0x90/0x250 (unreliable) + [c0000000005a72c4] pci_disable_msix+0x124/0x180 + [d000000011e06708] disable_msi+0x88/0xb0 [cxgb4] + [d000000011e06948] free_some_resources+0xa8/0x160 [cxgb4] + [d000000011e06d60] remove_one+0x170/0x3c0 [cxgb4] + [c00000000058a910] pci_device_remove+0x70/0x110 + [c00000000064ef04] device_release_driver_internal+0x1f4/0x2c0 + ... + +This patch fixes the issue by refactoring the shutdown path of ULD on +cxgb4 driver, by properly freeing and disabling interrupts on PCI +remove handler too. + +Fixes: 0fbc81b3ad51 ("Allocate resources dynamically for all cxgb4 ULD's") +Reported-by: Harsha Thyagaraja +Signed-off-by: Guilherme G. Piccoli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 16 ++++++--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c | 42 ++++++++++++++---------- + 2 files changed, 36 insertions(+), 22 deletions(-) + +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -2076,12 +2076,12 @@ static void detach_ulds(struct adapter * + + mutex_lock(&uld_mutex); + list_del(&adap->list_node); ++ + for (i = 0; i < CXGB4_ULD_MAX; i++) +- if (adap->uld && adap->uld[i].handle) { ++ if (adap->uld && adap->uld[i].handle) + adap->uld[i].state_change(adap->uld[i].handle, + CXGB4_STATE_DETACH); +- adap->uld[i].handle = NULL; +- } ++ + if (netevent_registered && list_empty(&adapter_list)) { + unregister_netevent_notifier(&cxgb4_netevent_nb); + netevent_registered = false; +@@ -5089,8 +5089,10 @@ static void remove_one(struct pci_dev *p + */ + destroy_workqueue(adapter->workq); + +- if (is_uld(adapter)) ++ if (is_uld(adapter)) { + detach_ulds(adapter); ++ t4_uld_clean_up(adapter); ++ } + + disable_interrupts(adapter); + +@@ -5167,7 +5169,11 @@ static void shutdown_one(struct pci_dev + if (adapter->port[i]->reg_state == NETREG_REGISTERED) + cxgb_close(adapter->port[i]); + +- t4_uld_clean_up(adapter); ++ if (is_uld(adapter)) { ++ detach_ulds(adapter); ++ t4_uld_clean_up(adapter); ++ } ++ + disable_interrupts(adapter); + disable_msi(adapter); + +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c +@@ -589,22 +589,37 @@ void t4_uld_mem_free(struct adapter *ada + kfree(adap->uld); + } + ++/* This function should be called with uld_mutex taken. */ ++static void cxgb4_shutdown_uld_adapter(struct adapter *adap, enum cxgb4_uld type) ++{ ++ if (adap->uld[type].handle) { ++ adap->uld[type].handle = NULL; ++ adap->uld[type].add = NULL; ++ release_sge_txq_uld(adap, type); ++ ++ if (adap->flags & FULL_INIT_DONE) ++ quiesce_rx_uld(adap, type); ++ ++ if (adap->flags & USING_MSIX) ++ free_msix_queue_irqs_uld(adap, type); ++ ++ free_sge_queues_uld(adap, type); ++ free_queues_uld(adap, type); ++ } ++} ++ + void t4_uld_clean_up(struct adapter *adap) + { + unsigned int i; + +- if (!adap->uld) +- return; ++ mutex_lock(&uld_mutex); + for (i = 0; i < CXGB4_ULD_MAX; i++) { + if (!adap->uld[i].handle) + continue; +- if (adap->flags & FULL_INIT_DONE) +- quiesce_rx_uld(adap, i); +- if (adap->flags & USING_MSIX) +- free_msix_queue_irqs_uld(adap, i); +- free_sge_queues_uld(adap, i); +- free_queues_uld(adap, i); ++ ++ cxgb4_shutdown_uld_adapter(adap, i); + } ++ mutex_unlock(&uld_mutex); + } + + static void uld_init(struct adapter *adap, struct cxgb4_lld_info *lld) +@@ -782,15 +797,8 @@ int cxgb4_unregister_uld(enum cxgb4_uld + continue; + if (type == CXGB4_ULD_ISCSIT && is_t4(adap->params.chip)) + continue; +- adap->uld[type].handle = NULL; +- adap->uld[type].add = NULL; +- release_sge_txq_uld(adap, type); +- if (adap->flags & FULL_INIT_DONE) +- quiesce_rx_uld(adap, type); +- if (adap->flags & USING_MSIX) +- free_msix_queue_irqs_uld(adap, type); +- free_sge_queues_uld(adap, type); +- free_queues_uld(adap, type); ++ ++ cxgb4_shutdown_uld_adapter(adap, type); + } + mutex_unlock(&uld_mutex); + diff --git a/queue-4.11/geneve-fix-hlist-corruption.patch b/queue-4.11/geneve-fix-hlist-corruption.patch new file mode 100644 index 00000000000..abc4d7d85a0 --- /dev/null +++ b/queue-4.11/geneve-fix-hlist-corruption.patch @@ -0,0 +1,132 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Jiri Benc +Date: Sun, 2 Jul 2017 19:00:58 +0200 +Subject: geneve: fix hlist corruption + +From: Jiri Benc + + +[ Upstream commit 4b4c21fad6ae6bd58ff1566f23b0f4f70fdc9a30 ] + +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: 8ed66f0e8235 ("geneve: implement support for IPv6-based tunnels") +Cc: John W. Linville +Signed-off-by: Jiri Benc +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/geneve.c | 48 ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -45,9 +45,17 @@ struct geneve_net { + + static unsigned int geneve_net_id; + ++struct geneve_dev_node { ++ struct hlist_node hlist; ++ struct geneve_dev *geneve; ++}; ++ + /* Pseudo network device */ + struct geneve_dev { +- struct hlist_node hlist; /* vni hash table */ ++ struct geneve_dev_node hlist4; /* vni hash table for IPv4 socket */ ++#if IS_ENABLED(CONFIG_IPV6) ++ struct geneve_dev_node hlist6; /* vni hash table for IPv6 socket */ ++#endif + struct net *net; /* netns for packet i/o */ + struct net_device *dev; /* netdev for geneve tunnel */ + struct ip_tunnel_info info; +@@ -123,16 +131,16 @@ static struct geneve_dev *geneve_lookup( + __be32 addr, u8 vni[]) + { + struct hlist_head *vni_list_head; +- struct geneve_dev *geneve; ++ struct geneve_dev_node *node; + __u32 hash; + + /* Find the device for this VNI */ + hash = geneve_net_vni_hash(vni); + vni_list_head = &gs->vni_list[hash]; +- hlist_for_each_entry_rcu(geneve, vni_list_head, hlist) { +- if (eq_tun_id_and_vni((u8 *)&geneve->info.key.tun_id, vni) && +- addr == geneve->info.key.u.ipv4.dst) +- return geneve; ++ hlist_for_each_entry_rcu(node, vni_list_head, hlist) { ++ if (eq_tun_id_and_vni((u8 *)&node->geneve->info.key.tun_id, vni) && ++ addr == node->geneve->info.key.u.ipv4.dst) ++ return node->geneve; + } + return NULL; + } +@@ -142,16 +150,16 @@ static struct geneve_dev *geneve6_lookup + struct in6_addr addr6, u8 vni[]) + { + struct hlist_head *vni_list_head; +- struct geneve_dev *geneve; ++ struct geneve_dev_node *node; + __u32 hash; + + /* Find the device for this VNI */ + hash = geneve_net_vni_hash(vni); + vni_list_head = &gs->vni_list[hash]; +- hlist_for_each_entry_rcu(geneve, vni_list_head, hlist) { +- if (eq_tun_id_and_vni((u8 *)&geneve->info.key.tun_id, vni) && +- ipv6_addr_equal(&addr6, &geneve->info.key.u.ipv6.dst)) +- return geneve; ++ hlist_for_each_entry_rcu(node, vni_list_head, hlist) { ++ if (eq_tun_id_and_vni((u8 *)&node->geneve->info.key.tun_id, vni) && ++ ipv6_addr_equal(&addr6, &node->geneve->info.key.u.ipv6.dst)) ++ return node->geneve; + } + return NULL; + } +@@ -579,6 +587,7 @@ static int geneve_sock_add(struct geneve + { + struct net *net = geneve->net; + struct geneve_net *gn = net_generic(net, geneve_net_id); ++ struct geneve_dev_node *node; + struct geneve_sock *gs; + __u8 vni[3]; + __u32 hash; +@@ -597,15 +606,20 @@ static int geneve_sock_add(struct geneve + out: + gs->collect_md = geneve->collect_md; + #if IS_ENABLED(CONFIG_IPV6) +- if (ipv6) ++ if (ipv6) { + rcu_assign_pointer(geneve->sock6, gs); +- else ++ node = &geneve->hlist6; ++ } else + #endif ++ { + rcu_assign_pointer(geneve->sock4, gs); ++ node = &geneve->hlist4; ++ } ++ node->geneve = geneve; + + tunnel_id_to_vni(geneve->info.key.tun_id, vni); + hash = geneve_net_vni_hash(vni); +- hlist_add_head_rcu(&geneve->hlist, &gs->vni_list[hash]); ++ hlist_add_head_rcu(&node->hlist, &gs->vni_list[hash]); + return 0; + } + +@@ -632,8 +646,10 @@ static int geneve_stop(struct net_device + { + struct geneve_dev *geneve = netdev_priv(dev); + +- if (!hlist_unhashed(&geneve->hlist)) +- hlist_del_rcu(&geneve->hlist); ++ hlist_del_init_rcu(&geneve->hlist4.hlist); ++#if IS_ENABLED(CONFIG_IPV6) ++ hlist_del_init_rcu(&geneve->hlist6.hlist); ++#endif + geneve_sock_release(geneve); + return 0; + } diff --git a/queue-4.11/ipv6-avoid-unregistering-inet6_dev-for-loopback.patch b/queue-4.11/ipv6-avoid-unregistering-inet6_dev-for-loopback.patch new file mode 100644 index 00000000000..59c49329d7e --- /dev/null +++ b/queue-4.11/ipv6-avoid-unregistering-inet6_dev-for-loopback.patch @@ -0,0 +1,65 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: WANG Cong +Date: Wed, 21 Jun 2017 14:34:58 -0700 +Subject: ipv6: avoid unregistering inet6_dev for loopback + +From: WANG Cong + + +[ Upstream commit 60abc0be96e00ca71bac083215ac91ad2e575096 ] + +The per netns loopback_dev->ip6_ptr is unregistered and set to +NULL when its mtu is set to smaller than IPV6_MIN_MTU, this +leads to that we could set rt->rt6i_idev NULL after a +rt6_uncached_list_flush_dev() and then crash after another +call. + +In this case we should just bring its inet6_dev down, rather +than unregistering it, at least prior to commit 176c39af29bc +("netns: fix addrconf_ifdown kernel panic") we always +override the case for loopback. + +Thanks a lot to Andrey for finding a reliable reproducer. + +Fixes: 176c39af29bc ("netns: fix addrconf_ifdown kernel panic") +Reported-by: Andrey Konovalov +Cc: Andrey Konovalov +Cc: Daniel Lezcano +Cc: David Ahern +Signed-off-by: Cong Wang +Acked-by: David Ahern +Tested-by: Andrey Konovalov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3334,6 +3334,7 @@ static int addrconf_notify(struct notifi + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct netdev_notifier_changeupper_info *info; + struct inet6_dev *idev = __in6_dev_get(dev); ++ struct net *net = dev_net(dev); + int run_pending = 0; + int err; + +@@ -3349,7 +3350,7 @@ static int addrconf_notify(struct notifi + case NETDEV_CHANGEMTU: + /* if MTU under IPV6_MIN_MTU stop IPv6 on this interface. */ + if (dev->mtu < IPV6_MIN_MTU) { +- addrconf_ifdown(dev, 1); ++ addrconf_ifdown(dev, dev != net->loopback_dev); + break; + } + +@@ -3465,7 +3466,7 @@ static int addrconf_notify(struct notifi + * IPV6_MIN_MTU stop IPv6 on this interface. + */ + if (dev->mtu < IPV6_MIN_MTU) +- addrconf_ifdown(dev, 1); ++ addrconf_ifdown(dev, dev != net->loopback_dev); + } + break; + diff --git a/queue-4.11/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch b/queue-4.11/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch new file mode 100644 index 00000000000..be49fdd0f91 --- /dev/null +++ b/queue-4.11/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch @@ -0,0 +1,76 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +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 + + +[ Upstream commit ec8add2a4c9df723c94a863b8fcd6d93c472deed ] + +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 +@@ -1888,15 +1888,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; +@@ -1909,6 +1901,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.11/liquidio-fix-bug-in-soft-reset-failure-detection.patch b/queue-4.11/liquidio-fix-bug-in-soft-reset-failure-detection.patch new file mode 100644 index 00000000000..63aa095339d --- /dev/null +++ b/queue-4.11/liquidio-fix-bug-in-soft-reset-failure-detection.patch @@ -0,0 +1,51 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Derek Chickles +Date: Wed, 5 Jul 2017 11:59:27 -0700 +Subject: liquidio: fix bug in soft reset failure detection + +From: Derek Chickles + + +[ Upstream commit 05a6b4cae8c0cc1680c9dd33a97a49a13c0f01bc ] + +The code that detects a failed soft reset of Octeon is comparing the wrong +value against the reset value of the Octeon SLI_SCRATCH_1 register, +resulting in an inability to detect a soft reset failure. Fix it by using +the correct value in the comparison, which is any non-zero value. + +Fixes: f21fb3ed364b ("Add support of Cavium Liquidio ethernet adapters") +Fixes: c0eab5b3580a ("liquidio: CN23XX firmware download") +Signed-off-by: Derek Chickles +Signed-off-by: Satanand Burla +Signed-off-by: Raghu Vatsavayi +Signed-off-by: Felix Manlunas +Reviewed-by: Leon Romanovsky +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c | 2 +- + drivers/net/ethernet/cavium/liquidio/cn66xx_device.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c ++++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c +@@ -221,7 +221,7 @@ static int cn23xx_pf_soft_reset(struct o + /* Wait for 100ms as Octeon resets. */ + mdelay(100); + +- if (octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1) == 0x1234ULL) { ++ if (octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1)) { + dev_err(&oct->pci_dev->dev, "OCTEON[%d]: Soft reset failed\n", + oct->octeon_id); + return 1; +--- a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c ++++ b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c +@@ -44,7 +44,7 @@ int lio_cn6xxx_soft_reset(struct octeon_ + /* Wait for 10ms as Octeon resets. */ + mdelay(100); + +- if (octeon_read_csr64(oct, CN6XXX_SLI_SCRATCH1) == 0x1234ULL) { ++ if (octeon_read_csr64(oct, CN6XXX_SLI_SCRATCH1)) { + dev_err(&oct->pci_dev->dev, "Soft reset failed\n"); + return 1; + } diff --git a/queue-4.11/mlxsw-spectrum_router-fix-null-pointer-dereference.patch b/queue-4.11/mlxsw-spectrum_router-fix-null-pointer-dereference.patch new file mode 100644 index 00000000000..d691d3d37d4 --- /dev/null +++ b/queue-4.11/mlxsw-spectrum_router-fix-null-pointer-dereference.patch @@ -0,0 +1,53 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Ido Schimmel +Date: Wed, 28 Jun 2017 09:03:12 +0300 +Subject: mlxsw: spectrum_router: Fix NULL pointer dereference + +From: Ido Schimmel + + +[ Upstream commit 6b27c8adf27edf1dabe2cdcfaa101ef7e2712415 ] + +In case a VLAN device is enslaved to a bridge we shouldn't create a +router interface (RIF) for it when it's configured with an IP address. +This is already handled by the driver for other types of netdevs, such +as physical ports and LAG devices. + +If this IP address is then removed and the interface is subsequently +unlinked from the bridge, a NULL pointer dereference can happen, as the +original 802.1d FID was replaced with an rFID which was then deleted. + +To reproduce: +$ ip link set dev enp3s0np9 up +$ ip link add name enp3s0np9.111 link enp3s0np9 type vlan id 111 +$ ip link set dev enp3s0np9.111 up +$ ip link add name br0 type bridge +$ ip link set dev br0 up +$ ip link set enp3s0np9.111 master br0 +$ ip address add dev enp3s0np9.111 192.168.0.1/24 +$ ip address del dev enp3s0np9.111 192.168.0.1/24 +$ ip link set dev enp3s0np9.111 nomaster + +Fixes: 99724c18fc66 ("mlxsw: spectrum: Introduce support for router interfaces") +Signed-off-by: Ido Schimmel +Reported-by: Petr Machata +Tested-by: Petr Machata +Reviewed-by: Petr Machata +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +@@ -3829,6 +3829,9 @@ static int mlxsw_sp_inetaddr_vlan_event( + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(vlan_dev); + u16 vid = vlan_dev_vlan_id(vlan_dev); + ++ if (netif_is_bridge_port(vlan_dev)) ++ return 0; ++ + if (mlxsw_sp_port_dev_check(real_dev)) + return mlxsw_sp_inetaddr_vport_event(vlan_dev, real_dev, event, + vid); diff --git a/queue-4.11/net-account-for-current-skb-length-when-deciding-about-ufo.patch b/queue-4.11/net-account-for-current-skb-length-when-deciding-about-ufo.patch new file mode 100644 index 00000000000..363cccbd9f1 --- /dev/null +++ b/queue-4.11/net-account-for-current-skb-length-when-deciding-about-ufo.patch @@ -0,0 +1,77 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Michal Kubeček +Date: Mon, 19 Jun 2017 13:03:43 +0200 +Subject: net: account for current skb length when deciding about UFO + +From: Michal Kubeček + + +[ Upstream commit a5cb659bbc1c8644efa0c3138a757a1e432a4880 ] + +Our customer encountered stuck NFS writes for blocks starting at specific +offsets w.r.t. page boundary caused by networking stack sending packets via +UFO enabled device with wrong checksum. The problem can be reproduced by +composing a long UDP datagram from multiple parts using MSG_MORE flag: + + sendto(sd, buff, 1000, MSG_MORE, ...); + sendto(sd, buff, 1000, MSG_MORE, ...); + sendto(sd, buff, 3000, 0, ...); + +Assume this packet is to be routed via a device with MTU 1500 and +NETIF_F_UFO enabled. When second sendto() gets into __ip_append_data(), +this condition is tested (among others) to decide whether to call +ip_ufo_append_data(): + + ((length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb)) + +At the moment, we already have skb with 1028 bytes of data which is not +marked for GSO so that the test is false (fragheaderlen is usually 20). +Thus we append second 1000 bytes to this skb without invoking UFO. Third +sendto(), however, has sufficient length to trigger the UFO path so that we +end up with non-UFO skb followed by a UFO one. Later on, udp_send_skb() +uses udp_csum() to calculate the checksum but that assumes all fragments +have correct checksum in skb->csum which is not true for UFO fragments. + +When checking against MTU, we need to add skb->len to length of new segment +if we already have a partially filled skb and fragheaderlen only if there +isn't one. + +In the IPv6 case, skb can only be null if this is the first segment so that +we have to use headersize (length of the first IPv6 header) rather than +fragheaderlen (length of IPv6 header of further fragments) for skb == NULL. + +Fixes: e89e9cf539a2 ("[IPv4/IPv6]: UFO Scatter-gather approach") +Fixes: e4c5e13aa45c ("ipv6: Should use consistent conditional judgement for + ip6 fragment between __ip6_append_data and ip6_finish_output") +Signed-off-by: Michal Kubecek +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 3 ++- + net/ipv6/ip6_output.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -964,7 +964,8 @@ static int __ip_append_data(struct sock + csummode = CHECKSUM_PARTIAL; + + cork->length += length; +- if ((((length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb))) && ++ if ((((length + (skb ? skb->len : fragheaderlen)) > mtu) || ++ (skb && skb_is_gso(skb))) && + (sk->sk_protocol == IPPROTO_UDP) && + (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) && + (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) { +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1390,7 +1390,7 @@ emsgsize: + */ + + cork->length += length; +- if ((((length + fragheaderlen) > mtu) || ++ if ((((length + (skb ? skb->len : headersize)) > mtu) || + (skb && skb_is_gso(skb))) && + (sk->sk_protocol == IPPROTO_UDP) && + (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) && diff --git a/queue-4.11/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch b/queue-4.11/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch new file mode 100644 index 00000000000..35ec497f889 --- /dev/null +++ b/queue-4.11/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch @@ -0,0 +1,174 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +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 + + +[ Upstream commit 9af9959e142c274f4a30fefb71d97d2b028b337f ] + +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 +@@ -7591,7 +7591,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.11/net-dp83640-avoid-null-pointer-dereference.patch b/queue-4.11/net-dp83640-avoid-null-pointer-dereference.patch new file mode 100644 index 00000000000..1459e5178bc --- /dev/null +++ b/queue-4.11/net-dp83640-avoid-null-pointer-dereference.patch @@ -0,0 +1,43 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Richard Cochran +Date: Fri, 23 Jun 2017 17:51:31 +0200 +Subject: net: dp83640: Avoid NULL pointer dereference. + +From: Richard Cochran + + +[ Upstream commit db9d8b29d19d2801793e4419f4c6272bf8951c62 ] + +The function, skb_complete_tx_timestamp(), used to allow passing in a +NULL pointer for the time stamps, but that was changed in commit +62bccb8cdb69051b95a55ab0c489e3cab261c8ef ("net-timestamp: Make the +clone operation stand-alone from phy timestamping"), and the existing +call sites, all of which are in the dp83640 driver, were fixed up. + +Even though the kernel-doc was subsequently updated in commit +7a76a021cd5a292be875fbc616daf03eab1e6996 ("net-timestamp: Update +skb_complete_tx_timestamp comment"), still a bug fix from Manfred +Rudigier came into the driver using the old semantics. Probably +Manfred derived that patch from an older kernel version. + +This fix should be applied to the stable trees as well. + +Fixes: 81e8f2e930fe ("net: dp83640: Fix tx timestamp overflow handling.") +Signed-off-by: Richard Cochran +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/dp83640.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/phy/dp83640.c ++++ b/drivers/net/phy/dp83640.c +@@ -908,7 +908,7 @@ static void decode_txts(struct dp83640_p + if (overflow) { + pr_debug("tx timestamp queue overflow, count %d\n", overflow); + while (skb) { +- skb_complete_tx_timestamp(skb, NULL); ++ kfree_skb(skb); + skb = skb_dequeue(&dp83640->tx_queue); + } + return; diff --git a/queue-4.11/net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch b/queue-4.11/net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch new file mode 100644 index 00000000000..44decf75d02 --- /dev/null +++ b/queue-4.11/net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch @@ -0,0 +1,87 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Michal Kubeček +Date: Thu, 29 Jun 2017 11:13:36 +0200 +Subject: net: handle NAPI_GRO_FREE_STOLEN_HEAD case also in napi_frags_finish() + +From: Michal Kubeček + + +[ Upstream commit e44699d2c28067f69698ccb68dd3ddeacfebc434 ] + +Recently I started seeing warnings about pages with refcount -1. The +problem was traced to packets being reused after their head was merged into +a GRO packet by skb_gro_receive(). While bisecting the issue pointed to +commit c21b48cc1bbf ("net: adjust skb->truesize in ___pskb_trim()") and +I have never seen it on a kernel with it reverted, I believe the real +problem appeared earlier when the option to merge head frag in GRO was +implemented. + +Handling NAPI_GRO_FREE_STOLEN_HEAD state was only added to GRO_MERGED_FREE +branch of napi_skb_finish() so that if the driver uses napi_gro_frags() +and head is merged (which in my case happens after the skb_condense() +call added by the commit mentioned above), the skb is reused including the +head that has been merged. As a result, we release the page reference +twice and eventually end up with negative page refcount. + +To fix the problem, handle NAPI_GRO_FREE_STOLEN_HEAD in napi_frags_finish() +the same way it's done in napi_skb_finish(). + +Fixes: d7e8883cfcf4 ("net: make GRO aware of skb->head_frag") +Signed-off-by: Michal Kubecek +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4627,6 +4627,13 @@ struct packet_offload *gro_find_complete + } + EXPORT_SYMBOL(gro_find_complete_by_type); + ++static void napi_skb_free_stolen_head(struct sk_buff *skb) ++{ ++ skb_dst_drop(skb); ++ secpath_reset(skb); ++ kmem_cache_free(skbuff_head_cache, skb); ++} ++ + static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb) + { + switch (ret) { +@@ -4640,13 +4647,10 @@ static gro_result_t napi_skb_finish(gro_ + break; + + case GRO_MERGED_FREE: +- if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) { +- skb_dst_drop(skb); +- secpath_reset(skb); +- kmem_cache_free(skbuff_head_cache, skb); +- } else { ++ if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) ++ napi_skb_free_stolen_head(skb); ++ else + __kfree_skb(skb); +- } + break; + + case GRO_HELD: +@@ -4718,10 +4722,16 @@ static gro_result_t napi_frags_finish(st + break; + + case GRO_DROP: +- case GRO_MERGED_FREE: + napi_reuse_skb(napi, skb); + break; + ++ case GRO_MERGED_FREE: ++ if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) ++ napi_skb_free_stolen_head(skb); ++ else ++ napi_reuse_skb(napi, skb); ++ break; ++ + case GRO_MERGED: + case GRO_CONSUMED: + break; diff --git a/queue-4.11/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch b/queue-4.11/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch new file mode 100644 index 00000000000..c29521209bd --- /dev/null +++ b/queue-4.11/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch @@ -0,0 +1,92 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: David Ahern +Date: Wed, 5 Jul 2017 14:41:46 -0600 +Subject: net: ipv6: Compare lwstate in detecting duplicate nexthops + +From: David Ahern + + +[ Upstream commit f06b7549b79e29a672336d4e134524373fb7a232 ] + +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 +@@ -233,4 +234,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 +@@ -784,10 +784,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 +@@ -3047,17 +3047,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.11/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch b/queue-4.11/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch new file mode 100644 index 00000000000..de4328374df --- /dev/null +++ b/queue-4.11/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch @@ -0,0 +1,97 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Mohamad Haj Yahia +Date: Thu, 30 Mar 2017 17:09:00 +0300 +Subject: net/mlx5: Cancel delayed recovery work when unloading the driver + +From: Mohamad Haj Yahia + + +[ Upstream commit 2a0165a034ac024b60cca49c61e46f4afa2e4d98 ] + +Draining the health workqueue will ignore future health works including +the one that report hardware failure and thus we can't enter error state +Instead cancel the recovery flow and make sure only recovery flow won't +be scheduled. + +Fixes: 5e44fca50470 ('net/mlx5: Only cancel recovery work when cleaning up device') +Signed-off-by: Mohamad Haj Yahia +Signed-off-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/health.c | 15 ++++++++++++++- + drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- + include/linux/mlx5/driver.h | 1 + + 3 files changed, 16 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c +@@ -67,6 +67,7 @@ enum { + + enum { + MLX5_DROP_NEW_HEALTH_WORK, ++ MLX5_DROP_NEW_RECOVERY_WORK, + }; + + static u8 get_nic_state(struct mlx5_core_dev *dev) +@@ -193,7 +194,7 @@ static void health_care(struct work_stru + mlx5_handle_bad_state(dev); + + spin_lock(&health->wq_lock); +- if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) ++ if (!test_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags)) + schedule_delayed_work(&health->recover_work, recover_delay); + else + dev_err(&dev->pdev->dev, +@@ -314,6 +315,7 @@ void mlx5_start_health_poll(struct mlx5_ + init_timer(&health->timer); + health->sick = 0; + clear_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags); ++ clear_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags); + health->health = &dev->iseg->health; + health->health_counter = &dev->iseg->health_counter; + +@@ -336,11 +338,22 @@ void mlx5_drain_health_wq(struct mlx5_co + + spin_lock(&health->wq_lock); + set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags); ++ set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags); + spin_unlock(&health->wq_lock); + cancel_delayed_work_sync(&health->recover_work); + cancel_work_sync(&health->work); + } + ++void mlx5_drain_health_recovery(struct mlx5_core_dev *dev) ++{ ++ struct mlx5_core_health *health = &dev->priv.health; ++ ++ spin_lock(&health->wq_lock); ++ set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags); ++ spin_unlock(&health->wq_lock); ++ cancel_delayed_work_sync(&dev->priv.health.recover_work); ++} ++ + void mlx5_health_cleanup(struct mlx5_core_dev *dev) + { + struct mlx5_core_health *health = &dev->priv.health; +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -1236,7 +1236,7 @@ static int mlx5_unload_one(struct mlx5_c + int err = 0; + + if (cleanup) +- mlx5_drain_health_wq(dev); ++ mlx5_drain_health_recovery(dev); + + mutex_lock(&dev->intf_state_mutex); + if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) { +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -928,6 +928,7 @@ int mlx5_health_init(struct mlx5_core_de + void mlx5_start_health_poll(struct mlx5_core_dev *dev); + void mlx5_stop_health_poll(struct mlx5_core_dev *dev); + void mlx5_drain_health_wq(struct mlx5_core_dev *dev); ++void mlx5_drain_health_recovery(struct mlx5_core_dev *dev); + int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size, + struct mlx5_buf *buf, int node); + int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf); diff --git a/queue-4.11/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch b/queue-4.11/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch new file mode 100644 index 00000000000..3add031c458 --- /dev/null +++ b/queue-4.11/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch @@ -0,0 +1,32 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +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 + + +[ Upstream commit 8ff93de7668bd81bc8efa819d1184ebd48fae72d ] + +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 +@@ -2771,8 +2771,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.11/net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch b/queue-4.11/net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch new file mode 100644 index 00000000000..584d78f0391 --- /dev/null +++ b/queue-4.11/net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch @@ -0,0 +1,40 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Huy Nguyen +Date: Thu, 29 Jun 2017 16:50:01 -0500 +Subject: net/mlx5e: Initialize CEE's getpermhwaddr address buffer to 0xff + +From: Huy Nguyen + + +[ Upstream commit d968f0f2e4404152f37ed2384b4a2269dd2dae5a ] + +Latest change in open-lldp code uses bytes 6-11 of perm_addr buffer +as the Ethernet source address for the host TLV packet. +Since our driver does not fill these bytes, they stay at zero and +the open-lldp code ends up sending the TLV packet with zero source +address and the switch drops this packet. + +The fix is to initialize these bytes to 0xff. The open-lldp code +considers 0xff:ff:ff:ff:ff:ff as the invalid address and falls back to +use the host's mac address as the Ethernet source address. + +Fixes: 3a6a931dfb8e ("net/mlx5e: Support DCBX CEE API") +Signed-off-by: Huy Nguyen +Reviewed-by: Daniel Jurgens +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +@@ -464,6 +464,8 @@ static void mlx5e_dcbnl_getpermhwaddr(st + if (!perm_addr) + return; + ++ memset(perm_addr, 0xff, MAX_ADDR_LEN); ++ + mlx5_query_nic_vport_mac_address(priv->mdev, 0, perm_addr); + } + diff --git a/queue-4.11/net-phy-micrel-configure-intterupts-after-autoneg-workaround.patch b/queue-4.11/net-phy-micrel-configure-intterupts-after-autoneg-workaround.patch new file mode 100644 index 00000000000..e5c618d480a --- /dev/null +++ b/queue-4.11/net-phy-micrel-configure-intterupts-after-autoneg-workaround.patch @@ -0,0 +1,38 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Zach Brown +Date: Tue, 20 Jun 2017 12:48:11 -0500 +Subject: net/phy: micrel: configure intterupts after autoneg workaround + +From: Zach Brown + + +[ Upstream commit b866203d872d5deeafcecd25ea429d6748b5bd56 ] + +The commit ("net/phy: micrel: Add workaround for bad autoneg") fixes an +autoneg failure case by resetting the hardware. This turns off +intterupts. Things will work themselves out if the phy polls, as it will +figure out it's state during a poll. However if the phy uses only +intterupts, the phy will stall, since interrupts are off. This patch +fixes the issue by calling config_intr after resetting the phy. + +Fixes: d2fd719bcb0e ("net/phy: micrel: Add workaround for bad autoneg ") +Signed-off-by: Zach Brown +Reviewed-by: Andrew Lunn +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/micrel.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -611,6 +611,8 @@ static int ksz9031_read_status(struct ph + if ((regval & 0xFF) == 0xFF) { + phy_init_hw(phydev); + phydev->link = 0; ++ if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev)) ++ phydev->drv->config_intr(phydev); + } + + return 0; diff --git a/queue-4.11/net-prevent-sign-extension-in-dev_get_stats.patch b/queue-4.11/net-prevent-sign-extension-in-dev_get_stats.patch new file mode 100644 index 00000000000..b19993eaf87 --- /dev/null +++ b/queue-4.11/net-prevent-sign-extension-in-dev_get_stats.patch @@ -0,0 +1,43 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Eric Dumazet +Date: Tue, 27 Jun 2017 07:02:20 -0700 +Subject: net: prevent sign extension in dev_get_stats() + +From: Eric Dumazet + + +[ Upstream commit 6f64ec74515925cced6df4571638b5a099a49aae ] + +Similar to the fix provided by Dominik Heidler in commit +9b3dc0a17d73 ("l2tp: cast l2tp traffic counter to unsigned") +we need to take care of 32bit kernels in dev_get_stats(). + +When using atomic_long_read(), we add a 'long' to u64 and +might misinterpret high order bit, unless we cast to unsigned. + +Fixes: caf586e5f23ce ("net: add a core netdev->rx_dropped counter") +Fixes: 015f0688f57ca ("net: net: add a core netdev->tx_dropped counter") +Fixes: 6e7333d315a76 ("net: add rx_nohandler stat counter") +Signed-off-by: Eric Dumazet +Cc: Jarod Wilson +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -7623,9 +7623,9 @@ struct rtnl_link_stats64 *dev_get_stats( + } else { + netdev_stats_to_stats64(storage, &dev->stats); + } +- storage->rx_dropped += atomic_long_read(&dev->rx_dropped); +- storage->tx_dropped += atomic_long_read(&dev->tx_dropped); +- storage->rx_nohandler += atomic_long_read(&dev->rx_nohandler); ++ storage->rx_dropped += (unsigned long)atomic_long_read(&dev->rx_dropped); ++ storage->tx_dropped += (unsigned long)atomic_long_read(&dev->tx_dropped); ++ storage->rx_nohandler += (unsigned long)atomic_long_read(&dev->rx_nohandler); + return storage; + } + EXPORT_SYMBOL(dev_get_stats); diff --git a/queue-4.11/net-sched-fix-one-possible-panic-when-no-destroy-callback.patch b/queue-4.11/net-sched-fix-one-possible-panic-when-no-destroy-callback.patch new file mode 100644 index 00000000000..1d0c89f79ad --- /dev/null +++ b/queue-4.11/net-sched-fix-one-possible-panic-when-no-destroy-callback.patch @@ -0,0 +1,44 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Gao Feng +Date: Wed, 28 Jun 2017 12:53:54 +0800 +Subject: net: sched: Fix one possible panic when no destroy callback + +From: Gao Feng + + +[ Upstream commit c1a4872ebfb83b1af7144f7b29ac8c4b344a12a8 ] + +When qdisc fail to init, qdisc_create would invoke the destroy callback +to cleanup. But there is no check if the callback exists really. So it +would cause the panic if there is no real destroy callback like the qdisc +codel, fq, and so on. + +Take codel as an example following: +When a malicious user constructs one invalid netlink msg, it would cause +codel_init->codel_change->nla_parse_nested failed. +Then kernel would invoke the destroy callback directly but qdisc codel +doesn't define one. It causes one panic as a result. + +Now add one the check for destroy to avoid the possible panic. + +Fixes: 87b60cfacf9f ("net_sched: fix error recovery at qdisc creation") +Signed-off-by: Gao Feng +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_api.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1008,7 +1008,8 @@ static struct Qdisc *qdisc_create(struct + return sch; + } + /* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */ +- ops->destroy(sch); ++ if (ops->destroy) ++ ops->destroy(sch); + err_out3: + dev_put(dev); + kfree((char *) sch - sch->padded); diff --git a/queue-4.11/netvsc-don-t-access-netdev-num_rx_queues-directly.patch b/queue-4.11/netvsc-don-t-access-netdev-num_rx_queues-directly.patch new file mode 100644 index 00000000000..8f46a385629 --- /dev/null +++ b/queue-4.11/netvsc-don-t-access-netdev-num_rx_queues-directly.patch @@ -0,0 +1,52 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Arnd Bergmann +Date: Thu, 22 Jun 2017 00:16:37 +0200 +Subject: netvsc: don't access netdev->num_rx_queues directly + +From: Arnd Bergmann + + +[ Upstream commit b92b7d3312033a08cae2c879b9243c42ad7de94b ] + +This structure member is hidden behind CONFIG_SYSFS, and we +get a build error when that is disabled: + +drivers/net/hyperv/netvsc_drv.c: In function 'netvsc_set_channels': +drivers/net/hyperv/netvsc_drv.c:754:49: error: 'struct net_device' has no member named 'num_rx_queues'; did you mean 'num_tx_queues'? +drivers/net/hyperv/netvsc_drv.c: In function 'netvsc_set_rxfh': +drivers/net/hyperv/netvsc_drv.c:1181:25: error: 'struct net_device' has no member named 'num_rx_queues'; did you mean 'num_tx_queues'? + +As the value is only set once to the argument of alloc_netdev_mq(), +we can compare against that constant directly. + +Fixes: ff4a44199012 ("netvsc: allow get/set of RSS indirection table") +Fixes: 2b01888d1b45 ("netvsc: allow more flexible setting of number of channels") +Signed-off-by: Arnd Bergmann +Reviewed-by: Haiyang Zhang +Signed-off-by: Stephen Hemminger +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hyperv/netvsc_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -753,7 +753,7 @@ static int netvsc_set_channels(struct ne + channels->rx_count || channels->tx_count || channels->other_count) + return -EINVAL; + +- if (count > net->num_tx_queues || count > net->num_rx_queues) ++ if (count > net->num_tx_queues || count > VRSS_CHANNEL_MAX) + return -EINVAL; + + if (net_device_ctx->start_remove || !nvdev || nvdev->destroy) +@@ -1142,7 +1142,7 @@ static int netvsc_set_rxfh(struct net_de + + if (indir) { + for (i = 0; i < ITAB_NUM; i++) +- if (indir[i] >= dev->num_rx_queues) ++ if (indir[i] >= VRSS_CHANNEL_MAX) + return -EINVAL; + + for (i = 0; i < ITAB_NUM; i++) diff --git a/queue-4.11/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch b/queue-4.11/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch new file mode 100644 index 00000000000..e67dbef9a8c --- /dev/null +++ b/queue-4.11/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch @@ -0,0 +1,38 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +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 + + +[ Upstream commit 0933a578cd55b02dc80f219dc8f2efb17ec61c9a ] + +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 +@@ -125,7 +125,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.11/rocker-move-dereference-before-free.patch b/queue-4.11/rocker-move-dereference-before-free.patch new file mode 100644 index 00000000000..5601e63eba1 --- /dev/null +++ b/queue-4.11/rocker-move-dereference-before-free.patch @@ -0,0 +1,33 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Dan Carpenter +Date: Wed, 28 Jun 2017 14:44:21 +0300 +Subject: rocker: move dereference before free + +From: Dan Carpenter + + +[ Upstream commit acb4b7df48b539cb391287921de57e4e5fae3460 ] + +My static checker complains that ofdpa_neigh_del() can sometimes free +"found". It just makes sense to use it first before deleting it. + +Fixes: ecf244f753e0 ("rocker: fix maybe-uninitialized warning") +Signed-off-by: Dan Carpenter +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/rocker/rocker_ofdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c ++++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c +@@ -1505,8 +1505,8 @@ static int ofdpa_port_ipv4_nh(struct ofd + *index = entry->index; + resolved = false; + } else if (removing) { +- ofdpa_neigh_del(trans, found); + *index = found->index; ++ ofdpa_neigh_del(trans, found); + } else if (updating) { + ofdpa_neigh_update(found, trans, NULL, false); + resolved = !is_zero_ether_addr(found->eth_dst); diff --git a/queue-4.11/series b/queue-4.11/series new file mode 100644 index 00000000000..6afae6f875a --- /dev/null +++ b/queue-4.11/series @@ -0,0 +1,30 @@ +net-phy-micrel-configure-intterupts-after-autoneg-workaround.patch +ipv6-avoid-unregistering-inet6_dev-for-loopback.patch +netvsc-don-t-access-netdev-num_rx_queues-directly.patch +sfc-fix-mcdi-command-size-for-filter-operations.patch +net-account-for-current-skb-length-when-deciding-about-ufo.patch +net-dp83640-avoid-null-pointer-dereference.patch +tcp-reset-sk_rx_dst-in-tcp_disconnect.patch +net-prevent-sign-extension-in-dev_get_stats.patch +virtio-net-serialize-tx-routine-during-reset.patch +net-sched-fix-one-possible-panic-when-no-destroy-callback.patch +mlxsw-spectrum_router-fix-null-pointer-dereference.patch +rocker-move-dereference-before-free.patch +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 +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 +geneve-fix-hlist-corruption.patch +net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch +liquidio-fix-bug-in-soft-reset-failure-detection.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 +net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch +cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch +tap-convert-a-mutex-to-a-spinlock.patch +bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch +brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch +sfc-don-t-read-beyond-unicast-address-list.patch diff --git a/queue-4.11/sfc-don-t-read-beyond-unicast-address-list.patch b/queue-4.11/sfc-don-t-read-beyond-unicast-address-list.patch new file mode 100644 index 00000000000..7563f347df1 --- /dev/null +++ b/queue-4.11/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 +@@ -5033,12 +5033,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) { +@@ -5049,6 +5046,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) +@@ -5056,11 +5055,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.11/sfc-fix-mcdi-command-size-for-filter-operations.patch b/queue-4.11/sfc-fix-mcdi-command-size-for-filter-operations.patch new file mode 100644 index 00000000000..3482d40bc84 --- /dev/null +++ b/queue-4.11/sfc-fix-mcdi-command-size-for-filter-operations.patch @@ -0,0 +1,64 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Martin Habets +Date: Thu, 22 Jun 2017 10:50:41 +0100 +Subject: sfc: Fix MCDI command size for filter operations + +From: Martin Habets + + +[ Upstream commit bb53f4d4f5116d3dae76bb12fb16bc73771f958a ] + +The 8000 series adapters uses catch-all filters for encapsulated traffic +to support filtering VXLAN, NVGRE and GENEVE traffic. +This new filter functionality requires a longer MCDI command. +This patch increases the size of buffers on stack that were missed, which +fixes a kernel panic from the stack protector. + +Fixes: 9b41080125176 ("sfc: insert catch-all filters for encapsulated traffic") +Signed-off-by: Martin Habets +Acked-by: Edward Cree +Acked-by: Bert Kenward bkenward@solarflare.com +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/sfc/ef10.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/sfc/ef10.c ++++ b/drivers/net/ethernet/sfc/ef10.c +@@ -4171,7 +4171,7 @@ found: + * recipients + */ + if (is_mc_recip) { +- MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_IN_LEN); ++ MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN); + unsigned int depth, i; + + memset(inbuf, 0, sizeof(inbuf)); +@@ -4319,7 +4319,7 @@ static int efx_ef10_filter_remove_intern + efx_ef10_filter_set_entry(table, filter_idx, NULL, 0); + } else { + efx_mcdi_display_error(efx, MC_CMD_FILTER_OP, +- MC_CMD_FILTER_OP_IN_LEN, ++ MC_CMD_FILTER_OP_EXT_IN_LEN, + NULL, 0, rc); + } + } +@@ -4452,7 +4452,7 @@ static s32 efx_ef10_filter_rfs_insert(st + struct efx_filter_spec *spec) + { + struct efx_ef10_filter_table *table = efx->filter_state; +- MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_IN_LEN); ++ MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN); + struct efx_filter_spec *saved_spec; + unsigned int hash, i, depth = 1; + bool replacing = false; +@@ -4939,7 +4939,7 @@ not_restored: + static void efx_ef10_filter_table_remove(struct efx_nic *efx) + { + struct efx_ef10_filter_table *table = efx->filter_state; +- MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_IN_LEN); ++ MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN); + struct efx_filter_spec *spec; + unsigned int filter_idx; + int rc; diff --git a/queue-4.11/tap-convert-a-mutex-to-a-spinlock.patch b/queue-4.11/tap-convert-a-mutex-to-a-spinlock.patch new file mode 100644 index 00000000000..c9a6447a32c --- /dev/null +++ b/queue-4.11/tap-convert-a-mutex-to-a-spinlock.patch @@ -0,0 +1,95 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: WANG Cong +Date: Mon, 10 Jul 2017 10:05:50 -0700 +Subject: tap: convert a mutex to a spinlock + +From: WANG Cong + + +[ Upstream commit ffa423fb3251f8737303ffc3b0659e86e501808e ] + +We are not allowed to block on the RCU reader side, so can't +just hold the mutex as before. As a quick fix, convert it to +a spinlock. + +Fixes: d9f1f61c0801 ("tap: Extending tap device create/destroy APIs") +Reported-by: Christian Borntraeger +Tested-by: Christian Borntraeger +Cc: Sainath Grandhi +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tap.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/net/tap.c ++++ b/drivers/net/tap.c +@@ -106,7 +106,7 @@ struct major_info { + struct rcu_head rcu; + dev_t major; + struct idr minor_idr; +- struct mutex minor_lock; ++ spinlock_t minor_lock; + const char *device_name; + struct list_head next; + }; +@@ -416,15 +416,15 @@ int tap_get_minor(dev_t major, struct ta + goto unlock; + } + +- mutex_lock(&tap_major->minor_lock); +- retval = idr_alloc(&tap_major->minor_idr, tap, 1, TAP_NUM_DEVS, GFP_KERNEL); ++ spin_lock(&tap_major->minor_lock); ++ retval = idr_alloc(&tap_major->minor_idr, tap, 1, TAP_NUM_DEVS, GFP_ATOMIC); + if (retval >= 0) { + tap->minor = retval; + } else if (retval == -ENOSPC) { + netdev_err(tap->dev, "Too many tap devices\n"); + retval = -EINVAL; + } +- mutex_unlock(&tap_major->minor_lock); ++ spin_unlock(&tap_major->minor_lock); + + unlock: + rcu_read_unlock(); +@@ -442,12 +442,12 @@ void tap_free_minor(dev_t major, struct + goto unlock; + } + +- mutex_lock(&tap_major->minor_lock); ++ spin_lock(&tap_major->minor_lock); + if (tap->minor) { + idr_remove(&tap_major->minor_idr, tap->minor); + tap->minor = 0; + } +- mutex_unlock(&tap_major->minor_lock); ++ spin_unlock(&tap_major->minor_lock); + + unlock: + rcu_read_unlock(); +@@ -467,13 +467,13 @@ static struct tap_dev *dev_get_by_tap_fi + goto unlock; + } + +- mutex_lock(&tap_major->minor_lock); ++ spin_lock(&tap_major->minor_lock); + tap = idr_find(&tap_major->minor_idr, minor); + if (tap) { + dev = tap->dev; + dev_hold(dev); + } +- mutex_unlock(&tap_major->minor_lock); ++ spin_unlock(&tap_major->minor_lock); + + unlock: + rcu_read_unlock(); +@@ -1227,7 +1227,7 @@ static int tap_list_add(dev_t major, con + tap_major->major = MAJOR(major); + + idr_init(&tap_major->minor_idr); +- mutex_init(&tap_major->minor_lock); ++ spin_lock_init(&tap_major->minor_lock); + + tap_major->device_name = device_name; + diff --git a/queue-4.11/tcp-reset-sk_rx_dst-in-tcp_disconnect.patch b/queue-4.11/tcp-reset-sk_rx_dst-in-tcp_disconnect.patch new file mode 100644 index 00000000000..e9afeddde01 --- /dev/null +++ b/queue-4.11/tcp-reset-sk_rx_dst-in-tcp_disconnect.patch @@ -0,0 +1,40 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: WANG Cong +Date: Sat, 24 Jun 2017 23:50:30 -0700 +Subject: tcp: reset sk_rx_dst in tcp_disconnect() + +From: WANG Cong + + +[ Upstream commit d747a7a51b00984127a88113cdbbc26f91e9d815 ] + +We have to reset the sk->sk_rx_dst when we disconnect a TCP +connection, because otherwise when we re-connect it this +dst reference is simply overridden in tcp_finish_connect(). + +This fixes a dst leak which leads to a loopback dev refcnt +leak. It is a long-standing bug, Kevin reported a very similar +(if not same) bug before. Thanks to Andrei for providing such +a reliable reproducer which greatly narrows down the problem. + +Fixes: 41063e9dd119 ("ipv4: Early TCP socket demux.") +Reported-by: Andrei Vagin +Reported-by: Kevin Xu +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2325,6 +2325,8 @@ int tcp_disconnect(struct sock *sk, int + tcp_init_send_head(sk); + memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); + __sk_dst_reset(sk); ++ dst_release(sk->sk_rx_dst); ++ sk->sk_rx_dst = NULL; + tcp_saved_syn_free(tp); + + /* Clean up fastopen related fields */ diff --git a/queue-4.11/virtio-net-serialize-tx-routine-during-reset.patch b/queue-4.11/virtio-net-serialize-tx-routine-during-reset.patch new file mode 100644 index 00000000000..e5ab856d6ef --- /dev/null +++ b/queue-4.11/virtio-net-serialize-tx-routine-during-reset.patch @@ -0,0 +1,39 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +From: Jason Wang +Date: Wed, 28 Jun 2017 09:51:03 +0800 +Subject: virtio-net: serialize tx routine during reset + +From: Jason Wang + + +[ Upstream commit 713a98d90c5ea072c1bb00ef40617aee2cef2232 ] + +We don't hold any tx lock when trying to disable TX during reset, this +would lead a use after free since ndo_start_xmit() tries to access +the virtqueue which has already been freed. Fix this by using +netif_tx_disable() before freeing the vqs, this could make sure no tx +after vq freeing. + +Reported-by: Jean-Philippe Menil +Tested-by: Jean-Philippe Menil +Fixes commit f600b6905015 ("virtio_net: Add XDP support") +Cc: John Fastabend +Signed-off-by: Jason Wang +Acked-by: Michael S. Tsirkin +Acked-by: Robert McCabe +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/virtio_net.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -1709,6 +1709,7 @@ static void virtnet_freeze_down(struct v + flush_work(&vi->config_work); + + netif_device_detach(vi->dev); ++ netif_tx_disable(vi->dev); + cancel_delayed_work_sync(&vi->refill); + + if (netif_running(vi->dev)) { diff --git a/queue-4.11/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch b/queue-4.11/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch new file mode 100644 index 00000000000..51ca1f4fc73 --- /dev/null +++ b/queue-4.11/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch @@ -0,0 +1,117 @@ +From foo@baz Mon Jul 17 18:47:09 CEST 2017 +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 + + +[ Upstream commit f630c38ef0d785101363a8992bbd4f302180f86f ] + +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 +@@ -788,15 +788,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; + } +@@ -1247,6 +1242,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.11/vxlan-fix-hlist-corruption.patch b/queue-4.11/vxlan-fix-hlist-corruption.patch new file mode 100644 index 00000000000..20e3cdb779d --- /dev/null +++ b/queue-4.11/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 +@@ -228,15 +228,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; +@@ -2361,17 +2361,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); + } + +@@ -2817,6 +2822,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); +@@ -2834,12 +2840,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) diff --git a/queue-4.12/series b/queue-4.12/series new file mode 100644 index 00000000000..c212446d037 --- /dev/null +++ b/queue-4.12/series @@ -0,0 +1,19 @@ +staging-android-uapi-drop-definitions-of-removed-ion_ioc_-free-share-ioctls.patch +net-mlx5-fix-driver-load-error-flow-when-firmware-is-stuck.patch +net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.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 +geneve-fix-hlist-corruption.patch +net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch +liquidio-fix-bug-in-soft-reset-failure-detection.patch +net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch +vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch +virtio-net-fix-leaking-of-ctx-array.patch +rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch +net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch +cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch +tap-convert-a-mutex-to-a-spinlock.patch +bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch +brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch +sfc-don-t-read-beyond-unicast-address-list.patch diff --git a/queue-4.4/series b/queue-4.4/series new file mode 100644 index 00000000000..e69de29bb2d