From: Greg Kroah-Hartman Date: Mon, 21 Jun 2021 11:02:23 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.4.128~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=261b803ce6f7c79b35e0f64620740ca9840b8ebe;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: cfg80211-avoid-double-free-of-pmsr-request.patch cfg80211-make-certificate-generation-more-robust.patch dmaengine-pl330-fix-wrong-usage-of-spinlock-flags-in-dma_cyclc.patch drm-amdgpu-gfx10-enlarge-cp_mec_doorbell_range_upper-to-cover-full-doorbell.patch drm-amdgpu-gfx9-fix-the-doorbell-missing-when-in-cgpg-issue.patch net-bridge-fix-vlan-tunnel-dst-null-pointer-dereference.patch net-bridge-fix-vlan-tunnel-dst-refcnt-when-egressing.patch net-ll_temac-fix-tx-bd-buffer-overwrite.patch net-ll_temac-make-sure-to-free-skb-when-it-is-completely-used.patch x86-fpu-reset-state-for-all-signal-restore-failures.patch x86-pkru-write-hardware-init-value-to-pkru-when-xstate-is-init.patch x86-process-check-pf_kthread-and-not-current-mm-for-kernel-threads.patch --- diff --git a/queue-5.4/cfg80211-avoid-double-free-of-pmsr-request.patch b/queue-5.4/cfg80211-avoid-double-free-of-pmsr-request.patch new file mode 100644 index 00000000000..ef775a586c3 --- /dev/null +++ b/queue-5.4/cfg80211-avoid-double-free-of-pmsr-request.patch @@ -0,0 +1,61 @@ +From 0288e5e16a2e18f0b7e61a2b70d9037fc6e4abeb Mon Sep 17 00:00:00 2001 +From: Avraham Stern +Date: Fri, 18 Jun 2021 13:41:31 +0300 +Subject: cfg80211: avoid double free of PMSR request + +From: Avraham Stern + +commit 0288e5e16a2e18f0b7e61a2b70d9037fc6e4abeb upstream. + +If cfg80211_pmsr_process_abort() moves all the PMSR requests that +need to be freed into a local list before aborting and freeing them. +As a result, it is possible that cfg80211_pmsr_complete() will run in +parallel and free the same PMSR request. + +Fix it by freeing the request in cfg80211_pmsr_complete() only if it +is still in the original pmsr list. + +Cc: stable@vger.kernel.org +Fixes: 9bb7e0f24e7e ("cfg80211: add peer measurement with FTM initiator API") +Signed-off-by: Avraham Stern +Signed-off-by: Luca Coelho +Link: https://lore.kernel.org/r/iwlwifi.20210618133832.1fbef57e269a.I00294bebdb0680b892f8d1d5c871fd9dbe785a5e@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/wireless/pmsr.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/net/wireless/pmsr.c ++++ b/net/wireless/pmsr.c +@@ -293,6 +293,7 @@ void cfg80211_pmsr_complete(struct wirel + gfp_t gfp) + { + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); ++ struct cfg80211_pmsr_request *tmp, *prev, *to_free = NULL; + struct sk_buff *msg; + void *hdr; + +@@ -323,9 +324,20 @@ free_msg: + nlmsg_free(msg); + free_request: + spin_lock_bh(&wdev->pmsr_lock); +- list_del(&req->list); ++ /* ++ * cfg80211_pmsr_process_abort() may have already moved this request ++ * to the free list, and will free it later. In this case, don't free ++ * it here. ++ */ ++ list_for_each_entry_safe(tmp, prev, &wdev->pmsr_list, list) { ++ if (tmp == req) { ++ list_del(&req->list); ++ to_free = req; ++ break; ++ } ++ } + spin_unlock_bh(&wdev->pmsr_lock); +- kfree(req); ++ kfree(to_free); + } + EXPORT_SYMBOL_GPL(cfg80211_pmsr_complete); + diff --git a/queue-5.4/cfg80211-make-certificate-generation-more-robust.patch b/queue-5.4/cfg80211-make-certificate-generation-more-robust.patch new file mode 100644 index 00000000000..f2b0b74f2bd --- /dev/null +++ b/queue-5.4/cfg80211-make-certificate-generation-more-robust.patch @@ -0,0 +1,35 @@ +From b5642479b0f7168fe16d156913533fe65ab4f8d5 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 18 Jun 2021 13:41:29 +0300 +Subject: cfg80211: make certificate generation more robust + +From: Johannes Berg + +commit b5642479b0f7168fe16d156913533fe65ab4f8d5 upstream. + +If all net/wireless/certs/*.hex files are deleted, the build +will hang at this point since the 'cat' command will have no +arguments. Do "echo | cat - ..." so that even if the "..." +part is empty, the whole thing won't hang. + +Cc: stable@vger.kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Luca Coelho +Link: https://lore.kernel.org/r/iwlwifi.20210618133832.c989056c3664.Ic3b77531d00b30b26dcd69c64e55ae2f60c3f31e@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/wireless/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/wireless/Makefile ++++ b/net/wireless/Makefile +@@ -28,7 +28,7 @@ $(obj)/shipped-certs.c: $(wildcard $(src + @$(kecho) " GEN $@" + @(echo '#include "reg.h"'; \ + echo 'const u8 shipped_regdb_certs[] = {'; \ +- cat $^ ; \ ++ echo | cat - $^ ; \ + echo '};'; \ + echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);'; \ + ) > $@ diff --git a/queue-5.4/dmaengine-pl330-fix-wrong-usage-of-spinlock-flags-in-dma_cyclc.patch b/queue-5.4/dmaengine-pl330-fix-wrong-usage-of-spinlock-flags-in-dma_cyclc.patch new file mode 100644 index 00000000000..b338de7f7d0 --- /dev/null +++ b/queue-5.4/dmaengine-pl330-fix-wrong-usage-of-spinlock-flags-in-dma_cyclc.patch @@ -0,0 +1,52 @@ +From 4ad5dd2d7876d79507a20f026507d1a93b8fff10 Mon Sep 17 00:00:00 2001 +From: Bumyong Lee +Date: Fri, 7 May 2021 15:36:47 +0900 +Subject: dmaengine: pl330: fix wrong usage of spinlock flags in dma_cyclc + +From: Bumyong Lee + +commit 4ad5dd2d7876d79507a20f026507d1a93b8fff10 upstream. + +flags varible which is the input parameter of pl330_prep_dma_cyclic() +should not be used by spinlock_irq[save/restore] function. + +Signed-off-by: Jongho Park +Signed-off-by: Bumyong Lee +Signed-off-by: Chanho Park +Link: https://lore.kernel.org/r/20210507063647.111209-1-chanho61.park@samsung.com +Fixes: f6f2421c0a1c ("dmaengine: pl330: Merge dma_pl330_dmac and pl330_dmac structs") +Cc: stable@vger.kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/pl330.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2690,13 +2690,15 @@ static struct dma_async_tx_descriptor *p + for (i = 0; i < len / period_len; i++) { + desc = pl330_get_desc(pch); + if (!desc) { ++ unsigned long iflags; ++ + dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", + __func__, __LINE__); + + if (!first) + return NULL; + +- spin_lock_irqsave(&pl330->pool_lock, flags); ++ spin_lock_irqsave(&pl330->pool_lock, iflags); + + while (!list_empty(&first->node)) { + desc = list_entry(first->node.next, +@@ -2706,7 +2708,7 @@ static struct dma_async_tx_descriptor *p + + list_move_tail(&first->node, &pl330->desc_pool); + +- spin_unlock_irqrestore(&pl330->pool_lock, flags); ++ spin_unlock_irqrestore(&pl330->pool_lock, iflags); + + return NULL; + } diff --git a/queue-5.4/drm-amdgpu-gfx10-enlarge-cp_mec_doorbell_range_upper-to-cover-full-doorbell.patch b/queue-5.4/drm-amdgpu-gfx10-enlarge-cp_mec_doorbell_range_upper-to-cover-full-doorbell.patch new file mode 100644 index 00000000000..86d0f111e7f --- /dev/null +++ b/queue-5.4/drm-amdgpu-gfx10-enlarge-cp_mec_doorbell_range_upper-to-cover-full-doorbell.patch @@ -0,0 +1,38 @@ +From 1c0b0efd148d5b24c4932ddb3fa03c8edd6097b3 Mon Sep 17 00:00:00 2001 +From: Yifan Zhang +Date: Thu, 10 Jun 2021 10:10:07 +0800 +Subject: drm/amdgpu/gfx10: enlarge CP_MEC_DOORBELL_RANGE_UPPER to cover full doorbell. + +From: Yifan Zhang + +commit 1c0b0efd148d5b24c4932ddb3fa03c8edd6097b3 upstream. + +If GC has entered CGPG, ringing doorbell > first page doesn't wakeup GC. +Enlarge CP_MEC_DOORBELL_RANGE_UPPER to workaround this issue. + +Signed-off-by: Yifan Zhang +Reviewed-by: Felix Kuehling +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +@@ -3416,8 +3416,12 @@ static int gfx_v10_0_kiq_init_register(s + if (ring->use_doorbell) { + WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_LOWER, + (adev->doorbell_index.kiq * 2) << 2); ++ /* If GC has entered CGPG, ringing doorbell > first page doesn't ++ * wakeup GC. Enlarge CP_MEC_DOORBELL_RANGE_UPPER to workaround ++ * this issue. ++ */ + WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER, +- (adev->doorbell_index.userqueue_end * 2) << 2); ++ (adev->doorbell.size - 4)); + } + + WREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL, diff --git a/queue-5.4/drm-amdgpu-gfx9-fix-the-doorbell-missing-when-in-cgpg-issue.patch b/queue-5.4/drm-amdgpu-gfx9-fix-the-doorbell-missing-when-in-cgpg-issue.patch new file mode 100644 index 00000000000..f7f4ab066d1 --- /dev/null +++ b/queue-5.4/drm-amdgpu-gfx9-fix-the-doorbell-missing-when-in-cgpg-issue.patch @@ -0,0 +1,38 @@ +From 4cbbe34807938e6e494e535a68d5ff64edac3f20 Mon Sep 17 00:00:00 2001 +From: Yifan Zhang +Date: Thu, 10 Jun 2021 09:55:01 +0800 +Subject: drm/amdgpu/gfx9: fix the doorbell missing when in CGPG issue. + +From: Yifan Zhang + +commit 4cbbe34807938e6e494e535a68d5ff64edac3f20 upstream. + +If GC has entered CGPG, ringing doorbell > first page doesn't wakeup GC. +Enlarge CP_MEC_DOORBELL_RANGE_UPPER to workaround this issue. + +Signed-off-by: Yifan Zhang +Reviewed-by: Felix Kuehling +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -3593,8 +3593,12 @@ static int gfx_v9_0_kiq_init_register(st + if (ring->use_doorbell) { + WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_LOWER, + (adev->doorbell_index.kiq * 2) << 2); ++ /* If GC has entered CGPG, ringing doorbell > first page doesn't ++ * wakeup GC. Enlarge CP_MEC_DOORBELL_RANGE_UPPER to workaround ++ * this issue. ++ */ + WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER, +- (adev->doorbell_index.userqueue_end * 2) << 2); ++ (adev->doorbell.size - 4)); + } + + WREG32_SOC15_RLC(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL, diff --git a/queue-5.4/net-bridge-fix-vlan-tunnel-dst-null-pointer-dereference.patch b/queue-5.4/net-bridge-fix-vlan-tunnel-dst-null-pointer-dereference.patch new file mode 100644 index 00000000000..94f30d17701 --- /dev/null +++ b/queue-5.4/net-bridge-fix-vlan-tunnel-dst-null-pointer-dereference.patch @@ -0,0 +1,135 @@ +From 58e2071742e38f29f051b709a5cca014ba51166f Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Thu, 10 Jun 2021 15:04:10 +0300 +Subject: net: bridge: fix vlan tunnel dst null pointer dereference + +From: Nikolay Aleksandrov + +commit 58e2071742e38f29f051b709a5cca014ba51166f upstream. + +This patch fixes a tunnel_dst null pointer dereference due to lockless +access in the tunnel egress path. When deleting a vlan tunnel the +tunnel_dst pointer is set to NULL without waiting a grace period (i.e. +while it's still usable) and packets egressing are dereferencing it +without checking. Use READ/WRITE_ONCE to annotate the lockless use of +tunnel_id, use RCU for accessing tunnel_dst and make sure it is read +only once and checked in the egress path. The dst is already properly RCU +protected so we don't need to do anything fancy than to make sure +tunnel_id and tunnel_dst are read only once and checked in the egress path. + +Cc: stable@vger.kernel.org +Fixes: 11538d039ac6 ("bridge: vlan dst_metadata hooks in ingress and egress paths") +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_private.h | 4 ++-- + net/bridge/br_vlan_tunnel.c | 38 ++++++++++++++++++++++++-------------- + 2 files changed, 26 insertions(+), 16 deletions(-) + +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -96,8 +96,8 @@ struct br_vlan_stats { + }; + + struct br_tunnel_info { +- __be64 tunnel_id; +- struct metadata_dst *tunnel_dst; ++ __be64 tunnel_id; ++ struct metadata_dst __rcu *tunnel_dst; + }; + + /* private vlan flags */ +--- a/net/bridge/br_vlan_tunnel.c ++++ b/net/bridge/br_vlan_tunnel.c +@@ -41,26 +41,33 @@ static struct net_bridge_vlan *br_vlan_t + br_vlan_tunnel_rht_params); + } + ++static void vlan_tunnel_info_release(struct net_bridge_vlan *vlan) ++{ ++ struct metadata_dst *tdst = rtnl_dereference(vlan->tinfo.tunnel_dst); ++ ++ WRITE_ONCE(vlan->tinfo.tunnel_id, 0); ++ RCU_INIT_POINTER(vlan->tinfo.tunnel_dst, NULL); ++ dst_release(&tdst->dst); ++} ++ + void vlan_tunnel_info_del(struct net_bridge_vlan_group *vg, + struct net_bridge_vlan *vlan) + { +- if (!vlan->tinfo.tunnel_dst) ++ if (!rcu_access_pointer(vlan->tinfo.tunnel_dst)) + return; + rhashtable_remove_fast(&vg->tunnel_hash, &vlan->tnode, + br_vlan_tunnel_rht_params); +- vlan->tinfo.tunnel_id = 0; +- dst_release(&vlan->tinfo.tunnel_dst->dst); +- vlan->tinfo.tunnel_dst = NULL; ++ vlan_tunnel_info_release(vlan); + } + + static int __vlan_tunnel_info_add(struct net_bridge_vlan_group *vg, + struct net_bridge_vlan *vlan, u32 tun_id) + { +- struct metadata_dst *metadata = NULL; ++ struct metadata_dst *metadata = rtnl_dereference(vlan->tinfo.tunnel_dst); + __be64 key = key32_to_tunnel_id(cpu_to_be32(tun_id)); + int err; + +- if (vlan->tinfo.tunnel_dst) ++ if (metadata) + return -EEXIST; + + metadata = __ip_tun_set_dst(0, 0, 0, 0, 0, TUNNEL_KEY, +@@ -69,8 +76,8 @@ static int __vlan_tunnel_info_add(struct + return -EINVAL; + + metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX | IP_TUNNEL_INFO_BRIDGE; +- vlan->tinfo.tunnel_dst = metadata; +- vlan->tinfo.tunnel_id = key; ++ rcu_assign_pointer(vlan->tinfo.tunnel_dst, metadata); ++ WRITE_ONCE(vlan->tinfo.tunnel_id, key); + + err = rhashtable_lookup_insert_fast(&vg->tunnel_hash, &vlan->tnode, + br_vlan_tunnel_rht_params); +@@ -79,9 +86,7 @@ static int __vlan_tunnel_info_add(struct + + return 0; + out: +- dst_release(&vlan->tinfo.tunnel_dst->dst); +- vlan->tinfo.tunnel_dst = NULL; +- vlan->tinfo.tunnel_id = 0; ++ vlan_tunnel_info_release(vlan); + + return err; + } +@@ -181,12 +186,15 @@ int br_handle_ingress_vlan_tunnel(struct + int br_handle_egress_vlan_tunnel(struct sk_buff *skb, + struct net_bridge_vlan *vlan) + { ++ struct metadata_dst *tunnel_dst; ++ __be64 tunnel_id; + int err; + +- if (!vlan || !vlan->tinfo.tunnel_id) ++ if (!vlan) + return 0; + +- if (unlikely(!skb_vlan_tag_present(skb))) ++ tunnel_id = READ_ONCE(vlan->tinfo.tunnel_id); ++ if (!tunnel_id || unlikely(!skb_vlan_tag_present(skb))) + return 0; + + skb_dst_drop(skb); +@@ -194,7 +202,9 @@ int br_handle_egress_vlan_tunnel(struct + if (err) + return err; + +- skb_dst_set(skb, dst_clone(&vlan->tinfo.tunnel_dst->dst)); ++ tunnel_dst = rcu_dereference(vlan->tinfo.tunnel_dst); ++ if (tunnel_dst) ++ skb_dst_set(skb, dst_clone(&tunnel_dst->dst)); + + return 0; + } diff --git a/queue-5.4/net-bridge-fix-vlan-tunnel-dst-refcnt-when-egressing.patch b/queue-5.4/net-bridge-fix-vlan-tunnel-dst-refcnt-when-egressing.patch new file mode 100644 index 00000000000..c422579096d --- /dev/null +++ b/queue-5.4/net-bridge-fix-vlan-tunnel-dst-refcnt-when-egressing.patch @@ -0,0 +1,87 @@ +From cfc579f9d89af4ada58c69b03bcaa4887840f3b3 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Thu, 10 Jun 2021 15:04:11 +0300 +Subject: net: bridge: fix vlan tunnel dst refcnt when egressing + +From: Nikolay Aleksandrov + +commit cfc579f9d89af4ada58c69b03bcaa4887840f3b3 upstream. + +The egress tunnel code uses dst_clone() and directly sets the result +which is wrong because the entry might have 0 refcnt or be already deleted, +causing number of problems. It also triggers the WARN_ON() in dst_hold()[1] +when a refcnt couldn't be taken. Fix it by using dst_hold_safe() and +checking if a reference was actually taken before setting the dst. + +[1] dmesg WARN_ON log and following refcnt errors + WARNING: CPU: 5 PID: 38 at include/net/dst.h:230 br_handle_egress_vlan_tunnel+0x10b/0x134 [bridge] + Modules linked in: 8021q garp mrp bridge stp llc bonding ipv6 virtio_net + CPU: 5 PID: 38 Comm: ksoftirqd/5 Kdump: loaded Tainted: G W 5.13.0-rc3+ #360 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014 + RIP: 0010:br_handle_egress_vlan_tunnel+0x10b/0x134 [bridge] + Code: e8 85 bc 01 e1 45 84 f6 74 90 45 31 f6 85 db 48 c7 c7 a0 02 19 a0 41 0f 94 c6 31 c9 31 d2 44 89 f6 e8 64 bc 01 e1 85 db 75 02 <0f> 0b 31 c9 31 d2 44 89 f6 48 c7 c7 70 02 19 a0 e8 4b bc 01 e1 49 + RSP: 0018:ffff8881003d39e8 EFLAGS: 00010246 + RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 + RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffffa01902a0 + RBP: ffff8881040c6700 R08: 0000000000000000 R09: 0000000000000001 + R10: 2ce93d0054fe0d00 R11: 54fe0d00000e0000 R12: ffff888109515000 + R13: 0000000000000000 R14: 0000000000000001 R15: 0000000000000401 + FS: 0000000000000000(0000) GS:ffff88822bf40000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007f42ba70f030 CR3: 0000000109926000 CR4: 00000000000006e0 + Call Trace: + br_handle_vlan+0xbc/0xca [bridge] + __br_forward+0x23/0x164 [bridge] + deliver_clone+0x41/0x48 [bridge] + br_handle_frame_finish+0x36f/0x3aa [bridge] + ? skb_dst+0x2e/0x38 [bridge] + ? br_handle_ingress_vlan_tunnel+0x3e/0x1c8 [bridge] + ? br_handle_frame_finish+0x3aa/0x3aa [bridge] + br_handle_frame+0x2c3/0x377 [bridge] + ? __skb_pull+0x33/0x51 + ? vlan_do_receive+0x4f/0x36a + ? br_handle_frame_finish+0x3aa/0x3aa [bridge] + __netif_receive_skb_core+0x539/0x7c6 + ? __list_del_entry_valid+0x16e/0x1c2 + __netif_receive_skb_list_core+0x6d/0xd6 + netif_receive_skb_list_internal+0x1d9/0x1fa + gro_normal_list+0x22/0x3e + dev_gro_receive+0x55b/0x600 + ? detach_buf_split+0x58/0x140 + napi_gro_receive+0x94/0x12e + virtnet_poll+0x15d/0x315 [virtio_net] + __napi_poll+0x2c/0x1c9 + net_rx_action+0xe6/0x1fb + __do_softirq+0x115/0x2d8 + run_ksoftirqd+0x18/0x20 + smpboot_thread_fn+0x183/0x19c + ? smpboot_unregister_percpu_thread+0x66/0x66 + kthread+0x10a/0x10f + ? kthread_mod_delayed_work+0xb6/0xb6 + ret_from_fork+0x22/0x30 + ---[ end trace 49f61b07f775fd2b ]--- + dst_release: dst:00000000c02d677a refcnt:-1 + dst_release underflow + +Cc: stable@vger.kernel.org +Fixes: 11538d039ac6 ("bridge: vlan dst_metadata hooks in ingress and egress paths") +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_vlan_tunnel.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/bridge/br_vlan_tunnel.c ++++ b/net/bridge/br_vlan_tunnel.c +@@ -203,8 +203,8 @@ int br_handle_egress_vlan_tunnel(struct + return err; + + tunnel_dst = rcu_dereference(vlan->tinfo.tunnel_dst); +- if (tunnel_dst) +- skb_dst_set(skb, dst_clone(&tunnel_dst->dst)); ++ if (tunnel_dst && dst_hold_safe(&tunnel_dst->dst)) ++ skb_dst_set(skb, &tunnel_dst->dst); + + return 0; + } diff --git a/queue-5.4/net-ll_temac-fix-tx-bd-buffer-overwrite.patch b/queue-5.4/net-ll_temac-fix-tx-bd-buffer-overwrite.patch new file mode 100644 index 00000000000..66970ea3df6 --- /dev/null +++ b/queue-5.4/net-ll_temac-fix-tx-bd-buffer-overwrite.patch @@ -0,0 +1,36 @@ +From c364df2489b8ef2f5e3159b1dff1ff1fdb16040d Mon Sep 17 00:00:00 2001 +From: Esben Haabendal +Date: Fri, 18 Jun 2021 12:52:33 +0200 +Subject: net: ll_temac: Fix TX BD buffer overwrite + +From: Esben Haabendal + +commit c364df2489b8ef2f5e3159b1dff1ff1fdb16040d upstream. + +Just as the initial check, we need to ensure num_frag+1 buffers available, +as that is the number of buffers we are going to use. + +This fixes a buffer overflow, which might be seen during heavy network +load. Complete lockup of TEMAC was reproducible within about 10 minutes of +a particular load. + +Fixes: 84823ff80f74 ("net: ll_temac: Fix race condition causing TX hang") +Cc: stable@vger.kernel.org # v5.4+ +Signed-off-by: Esben Haabendal +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -846,7 +846,7 @@ temac_start_xmit(struct sk_buff *skb, st + smp_mb(); + + /* Space might have just been freed - check again */ +- if (temac_check_tx_bd_space(lp, num_frag)) ++ if (temac_check_tx_bd_space(lp, num_frag + 1)) + return NETDEV_TX_BUSY; + + netif_wake_queue(ndev); diff --git a/queue-5.4/net-ll_temac-make-sure-to-free-skb-when-it-is-completely-used.patch b/queue-5.4/net-ll_temac-make-sure-to-free-skb-when-it-is-completely-used.patch new file mode 100644 index 00000000000..13717ad5a4c --- /dev/null +++ b/queue-5.4/net-ll_temac-make-sure-to-free-skb-when-it-is-completely-used.patch @@ -0,0 +1,49 @@ +From 6aa32217a9a446275440ee8724b1ecaf1838df47 Mon Sep 17 00:00:00 2001 +From: Esben Haabendal +Date: Fri, 18 Jun 2021 12:52:23 +0200 +Subject: net: ll_temac: Make sure to free skb when it is completely used + +From: Esben Haabendal + +commit 6aa32217a9a446275440ee8724b1ecaf1838df47 upstream. + +With the skb pointer piggy-backed on the TX BD, we have a simple and +efficient way to free the skb buffer when the frame has been transmitted. +But in order to avoid freeing the skb while there are still fragments from +the skb in use, we need to piggy-back on the TX BD of the skb, not the +first. + +Without this, we are doing use-after-free on the DMA side, when the first +BD of a multi TX BD packet is seen as completed in xmit_done, and the +remaining BDs are still being processed. + +Cc: stable@vger.kernel.org # v5.4+ +Signed-off-by: Esben Haabendal +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/xilinx/ll_temac_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -873,7 +873,6 @@ temac_start_xmit(struct sk_buff *skb, st + return NETDEV_TX_OK; + } + cur_p->phys = cpu_to_be32(skb_dma_addr); +- ptr_to_txbd((void *)skb, cur_p); + + for (ii = 0; ii < num_frag; ii++) { + if (++lp->tx_bd_tail >= TX_BD_NUM) +@@ -912,6 +911,11 @@ temac_start_xmit(struct sk_buff *skb, st + } + cur_p->app0 |= cpu_to_be32(STS_CTRL_APP0_EOP); + ++ /* Mark last fragment with skb address, so it can be consumed ++ * in temac_start_xmit_done() ++ */ ++ ptr_to_txbd((void *)skb, cur_p); ++ + tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; + lp->tx_bd_tail++; + if (lp->tx_bd_tail >= TX_BD_NUM) diff --git a/queue-5.4/series b/queue-5.4/series index cf6136737bd..0d7d0cc7e6b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -63,3 +63,15 @@ pci-add-acs-quirk-for-broadcom-bcm57414-nic.patch pci-work-around-huawei-intelligent-nic-vf-flr-erratum.patch kvm-x86-immediately-reset-the-mmu-context-when-the-smm-flag-is-cleared.patch arcv2-save-abi-registers-across-signal-handling.patch +x86-process-check-pf_kthread-and-not-current-mm-for-kernel-threads.patch +x86-pkru-write-hardware-init-value-to-pkru-when-xstate-is-init.patch +x86-fpu-reset-state-for-all-signal-restore-failures.patch +dmaengine-pl330-fix-wrong-usage-of-spinlock-flags-in-dma_cyclc.patch +cfg80211-make-certificate-generation-more-robust.patch +cfg80211-avoid-double-free-of-pmsr-request.patch +drm-amdgpu-gfx10-enlarge-cp_mec_doorbell_range_upper-to-cover-full-doorbell.patch +drm-amdgpu-gfx9-fix-the-doorbell-missing-when-in-cgpg-issue.patch +net-ll_temac-make-sure-to-free-skb-when-it-is-completely-used.patch +net-ll_temac-fix-tx-bd-buffer-overwrite.patch +net-bridge-fix-vlan-tunnel-dst-null-pointer-dereference.patch +net-bridge-fix-vlan-tunnel-dst-refcnt-when-egressing.patch diff --git a/queue-5.4/x86-fpu-reset-state-for-all-signal-restore-failures.patch b/queue-5.4/x86-fpu-reset-state-for-all-signal-restore-failures.patch new file mode 100644 index 00000000000..2fd6f8315ee --- /dev/null +++ b/queue-5.4/x86-fpu-reset-state-for-all-signal-restore-failures.patch @@ -0,0 +1,96 @@ +From efa165504943f2128d50f63de0c02faf6dcceb0d Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Wed, 9 Jun 2021 21:18:00 +0200 +Subject: x86/fpu: Reset state for all signal restore failures + +From: Thomas Gleixner + +commit efa165504943f2128d50f63de0c02faf6dcceb0d upstream. + +If access_ok() or fpregs_soft_set() fails in __fpu__restore_sig() then the +function just returns but does not clear the FPU state as it does for all +other fatal failures. + +Clear the FPU state for these failures as well. + +Fixes: 72a671ced66d ("x86, fpu: Unify signal handling code paths for x86 and x86_64 kernels") +Signed-off-by: Thomas Gleixner +Signed-off-by: Borislav Petkov +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/87mtryyhhz.ffs@nanos.tec.linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/fpu/signal.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +--- a/arch/x86/kernel/fpu/signal.c ++++ b/arch/x86/kernel/fpu/signal.c +@@ -289,13 +289,17 @@ static int __fpu__restore_sig(void __use + return 0; + } + +- if (!access_ok(buf, size)) +- return -EACCES; ++ if (!access_ok(buf, size)) { ++ ret = -EACCES; ++ goto out; ++ } + +- if (!static_cpu_has(X86_FEATURE_FPU)) +- return fpregs_soft_set(current, NULL, +- 0, sizeof(struct user_i387_ia32_struct), +- NULL, buf) != 0; ++ if (!static_cpu_has(X86_FEATURE_FPU)) { ++ ret = fpregs_soft_set(current, NULL, 0, ++ sizeof(struct user_i387_ia32_struct), ++ NULL, buf); ++ goto out; ++ } + + if (use_xsave()) { + struct _fpx_sw_bytes fx_sw_user; +@@ -333,7 +337,7 @@ static int __fpu__restore_sig(void __use + if (ia32_fxstate) { + ret = __copy_from_user(&env, buf, sizeof(env)); + if (ret) +- goto err_out; ++ goto out; + envp = &env; + } else { + /* +@@ -369,7 +373,7 @@ static int __fpu__restore_sig(void __use + ret = validate_xstate_header(&fpu->state.xsave.header); + } + if (ret) +- goto err_out; ++ goto out; + + sanitize_restored_xstate(&fpu->state, envp, xfeatures, fx_only); + +@@ -382,7 +386,7 @@ static int __fpu__restore_sig(void __use + ret = __copy_from_user(&fpu->state.fxsave, buf_fx, state_size); + if (ret) { + ret = -EFAULT; +- goto err_out; ++ goto out; + } + + sanitize_restored_xstate(&fpu->state, envp, xfeatures, fx_only); +@@ -397,7 +401,7 @@ static int __fpu__restore_sig(void __use + } else { + ret = __copy_from_user(&fpu->state.fsave, buf_fx, state_size); + if (ret) +- goto err_out; ++ goto out; + + fpregs_lock(); + ret = copy_kernel_to_fregs_err(&fpu->state.fsave); +@@ -408,7 +412,7 @@ static int __fpu__restore_sig(void __use + fpregs_deactivate(fpu); + fpregs_unlock(); + +-err_out: ++out: + if (ret) + fpu__clear(fpu); + return ret; diff --git a/queue-5.4/x86-pkru-write-hardware-init-value-to-pkru-when-xstate-is-init.patch b/queue-5.4/x86-pkru-write-hardware-init-value-to-pkru-when-xstate-is-init.patch new file mode 100644 index 00000000000..6b10c066dda --- /dev/null +++ b/queue-5.4/x86-pkru-write-hardware-init-value-to-pkru-when-xstate-is-init.patch @@ -0,0 +1,93 @@ +From 510b80a6a0f1a0d114c6e33bcea64747d127973c Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Tue, 8 Jun 2021 16:36:21 +0200 +Subject: x86/pkru: Write hardware init value to PKRU when xstate is init + +From: Thomas Gleixner + +commit 510b80a6a0f1a0d114c6e33bcea64747d127973c upstream. + +When user space brings PKRU into init state, then the kernel handling is +broken: + + T1 user space + xsave(state) + state.header.xfeatures &= ~XFEATURE_MASK_PKRU; + xrstor(state) + + T1 -> kernel + schedule() + XSAVE(S) -> T1->xsave.header.xfeatures[PKRU] == 0 + T1->flags |= TIF_NEED_FPU_LOAD; + + wrpkru(); + + schedule() + ... + pk = get_xsave_addr(&T1->fpu->state.xsave, XFEATURE_PKRU); + if (pk) + wrpkru(pk->pkru); + else + wrpkru(DEFAULT_PKRU); + +Because the xfeatures bit is 0 and therefore the value in the xsave +storage is not valid, get_xsave_addr() returns NULL and switch_to() +writes the default PKRU. -> FAIL #1! + +So that wrecks any copy_to/from_user() on the way back to user space +which hits memory which is protected by the default PKRU value. + +Assumed that this does not fail (pure luck) then T1 goes back to user +space and because TIF_NEED_FPU_LOAD is set it ends up in + + switch_fpu_return() + __fpregs_load_activate() + if (!fpregs_state_valid()) { + load_XSTATE_from_task(); + } + +But if nothing touched the FPU between T1 scheduling out and back in, +then the fpregs_state is still valid which means switch_fpu_return() +does nothing and just clears TIF_NEED_FPU_LOAD. Back to user space with +DEFAULT_PKRU loaded. -> FAIL #2! + +The fix is simple: if get_xsave_addr() returns NULL then set the +PKRU value to 0 instead of the restrictive default PKRU value in +init_pkru_value. + + [ bp: Massage in minor nitpicks from folks. ] + +Fixes: 0cecca9d03c9 ("x86/fpu: Eager switch PKRU state") +Signed-off-by: Thomas Gleixner +Signed-off-by: Borislav Petkov +Acked-by: Dave Hansen +Acked-by: Rik van Riel +Tested-by: Babu Moger +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20210608144346.045616965@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/fpu/internal.h | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/arch/x86/include/asm/fpu/internal.h ++++ b/arch/x86/include/asm/fpu/internal.h +@@ -608,9 +608,16 @@ static inline void switch_fpu_finish(str + * return to userland e.g. for a copy_to_user() operation. + */ + if (!(current->flags & PF_KTHREAD)) { ++ /* ++ * If the PKRU bit in xsave.header.xfeatures is not set, ++ * then the PKRU component was in init state, which means ++ * XRSTOR will set PKRU to 0. If the bit is not set then ++ * get_xsave_addr() will return NULL because the PKRU value ++ * in memory is not valid. This means pkru_val has to be ++ * set to 0 and not to init_pkru_value. ++ */ + pk = get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU); +- if (pk) +- pkru_val = pk->pkru; ++ pkru_val = pk ? pk->pkru : 0; + } + __write_pkru(pkru_val); + } diff --git a/queue-5.4/x86-process-check-pf_kthread-and-not-current-mm-for-kernel-threads.patch b/queue-5.4/x86-process-check-pf_kthread-and-not-current-mm-for-kernel-threads.patch new file mode 100644 index 00000000000..328ccf9bfba --- /dev/null +++ b/queue-5.4/x86-process-check-pf_kthread-and-not-current-mm-for-kernel-threads.patch @@ -0,0 +1,38 @@ +From 12f7764ac61200e32c916f038bdc08f884b0b604 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Tue, 8 Jun 2021 16:36:20 +0200 +Subject: x86/process: Check PF_KTHREAD and not current->mm for kernel threads + +From: Thomas Gleixner + +commit 12f7764ac61200e32c916f038bdc08f884b0b604 upstream. + +switch_fpu_finish() checks current->mm as indicator for kernel threads. +That's wrong because kernel threads can temporarily use a mm of a user +process via kthread_use_mm(). + +Check the task flags for PF_KTHREAD instead. + +Fixes: 0cecca9d03c9 ("x86/fpu: Eager switch PKRU state") +Signed-off-by: Thomas Gleixner +Signed-off-by: Borislav Petkov +Acked-by: Dave Hansen +Acked-by: Rik van Riel +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20210608144345.912645927@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/fpu/internal.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/include/asm/fpu/internal.h ++++ b/arch/x86/include/asm/fpu/internal.h +@@ -607,7 +607,7 @@ static inline void switch_fpu_finish(str + * PKRU state is switched eagerly because it needs to be valid before we + * return to userland e.g. for a copy_to_user() operation. + */ +- if (current->mm) { ++ if (!(current->flags & PF_KTHREAD)) { + pk = get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU); + if (pk) + pkru_val = pk->pkru;