From: Greg Kroah-Hartman Date: Sat, 21 Jan 2023 10:34:04 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v4.14.304~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=11f5f4f83e990a4103b3faf3f9d67b9ead549d44;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: add-exception-protection-processing-for-vd-in-axi_chan_handle_err-function.patch bluetooth-hci_qca-fix-driver-shutdown-on-closed-serdev.patch bluetooth-hci_sync-fix-use-hci_op_le_read_buffer_size_v2.patch hugetlb-unshare-some-pmds-when-splitting-vmas.patch loongarch-add-hwcap_loongarch_cpucfg-to-elf_hwcap.patch mm-khugepaged-fix-collapse_pte_mapped_thp-to-allow-anon_vma.patch mm-shmem-restore-shmem_huge_deny-precedence-over-madv_collapse.patch nilfs2-fix-general-protection-fault-in-nilfs_btree_insert.patch nommu-fix-do_munmap-error-path.patch nommu-fix-memory-leak-in-do_mmap-error-path.patch nommu-fix-split_vma-map_count-error.patch proc-fix-pie-proc-empty-vm-proc-pid-vm-tests.patch wifi-brcmfmac-fix-regression-for-broadcom-pcie-wifi-devices.patch wifi-mac80211-fix-initialization-of-rx-link-and-rx-link_sta.patch wifi-mac80211-fix-mlo-ap_vlan-check.patch wifi-mac80211-reset-multiple-bssid-options-in-stop_ap.patch wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch zonefs-detect-append-writes-at-invalid-locations.patch --- diff --git a/queue-6.1/add-exception-protection-processing-for-vd-in-axi_chan_handle_err-function.patch b/queue-6.1/add-exception-protection-processing-for-vd-in-axi_chan_handle_err-function.patch new file mode 100644 index 00000000000..d24c457822e --- /dev/null +++ b/queue-6.1/add-exception-protection-processing-for-vd-in-axi_chan_handle_err-function.patch @@ -0,0 +1,99 @@ +From 57054fe516d59d03a7bcf1888e82479ccc244f87 Mon Sep 17 00:00:00 2001 +From: "Shawn.Shao" +Date: Thu, 12 Jan 2023 13:58:02 +0800 +Subject: Add exception protection processing for vd in axi_chan_handle_err function + +From: Shawn.Shao + +commit 57054fe516d59d03a7bcf1888e82479ccc244f87 upstream. + +Since there is no protection for vd, a kernel panic will be +triggered here in exceptional cases. + +You can refer to the processing of axi_chan_block_xfer_complete function + +The triggered kernel panic is as follows: + +[ 67.848444] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000060 +[ 67.848447] Mem abort info: +[ 67.848449] ESR = 0x96000004 +[ 67.848451] EC = 0x25: DABT (current EL), IL = 32 bits +[ 67.848454] SET = 0, FnV = 0 +[ 67.848456] EA = 0, S1PTW = 0 +[ 67.848458] Data abort info: +[ 67.848460] ISV = 0, ISS = 0x00000004 +[ 67.848462] CM = 0, WnR = 0 +[ 67.848465] user pgtable: 4k pages, 48-bit VAs, pgdp=00000800c4c0b000 +[ 67.848468] [0000000000000060] pgd=0000000000000000, p4d=0000000000000000 +[ 67.848472] Internal error: Oops: 96000004 [#1] SMP +[ 67.848475] Modules linked in: dmatest +[ 67.848479] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.100-emu_x2rc+ #11 +[ 67.848483] pstate: 62000085 (nZCv daIf -PAN -UAO +TCO BTYPE=--) +[ 67.848487] pc : axi_chan_handle_err+0xc4/0x230 +[ 67.848491] lr : axi_chan_handle_err+0x30/0x230 +[ 67.848493] sp : ffff0803fe55ae50 +[ 67.848495] x29: ffff0803fe55ae50 x28: ffff800011212200 +[ 67.848500] x27: ffff0800c42c0080 x26: ffff0800c097c080 +[ 67.848504] x25: ffff800010d33880 x24: ffff80001139d850 +[ 67.848508] x23: ffff0800c097c168 x22: 0000000000000000 +[ 67.848512] x21: 0000000000000080 x20: 0000000000002000 +[ 67.848517] x19: ffff0800c097c080 x18: 0000000000000000 +[ 67.848521] x17: 0000000000000000 x16: 0000000000000000 +[ 67.848525] x15: 0000000000000000 x14: 0000000000000000 +[ 67.848529] x13: 0000000000000000 x12: 0000000000000040 +[ 67.848533] x11: ffff0800c0400248 x10: ffff0800c040024a +[ 67.848538] x9 : ffff800010576cd4 x8 : ffff0800c0400270 +[ 67.848542] x7 : 0000000000000000 x6 : ffff0800c04003e0 +[ 67.848546] x5 : ffff0800c0400248 x4 : ffff0800c4294480 +[ 67.848550] x3 : dead000000000100 x2 : dead000000000122 +[ 67.848555] x1 : 0000000000000100 x0 : ffff0800c097c168 +[ 67.848559] Call trace: +[ 67.848562] axi_chan_handle_err+0xc4/0x230 +[ 67.848566] dw_axi_dma_interrupt+0xf4/0x590 +[ 67.848569] __handle_irq_event_percpu+0x60/0x220 +[ 67.848573] handle_irq_event+0x64/0x120 +[ 67.848576] handle_fasteoi_irq+0xc4/0x220 +[ 67.848580] __handle_domain_irq+0x80/0xe0 +[ 67.848583] gic_handle_irq+0xc0/0x138 +[ 67.848585] el1_irq+0xc8/0x180 +[ 67.848588] arch_cpu_idle+0x14/0x2c +[ 67.848591] default_idle_call+0x40/0x16c +[ 67.848594] do_idle+0x1f0/0x250 +[ 67.848597] cpu_startup_entry+0x2c/0x60 +[ 67.848600] rest_init+0xc0/0xcc +[ 67.848603] arch_call_rest_init+0x14/0x1c +[ 67.848606] start_kernel+0x4cc/0x500 +[ 67.848610] Code: eb0002ff 9a9f12d6 f2fbd5a2 f2fbd5a3 (a94602c1) +[ 67.848613] ---[ end trace 585a97036f88203a ]--- + +Signed-off-by: Shawn.Shao +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20230112055802.1764-1-shawn.shao@jaguarmicro.com +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +@@ -1018,6 +1018,11 @@ static noinline void axi_chan_handle_err + + /* The bad descriptor currently is in the head of vc list */ + vd = vchan_next_desc(&chan->vc); ++ if (!vd) { ++ dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n", ++ axi_chan_name(chan)); ++ goto out; ++ } + /* Remove the completed descriptor from issued list */ + list_del(&vd->node); + +@@ -1032,6 +1037,7 @@ static noinline void axi_chan_handle_err + /* Try to restart the controller */ + axi_chan_start_first_queued(chan); + ++out: + spin_unlock_irqrestore(&chan->vc.lock, flags); + } + diff --git a/queue-6.1/bluetooth-hci_qca-fix-driver-shutdown-on-closed-serdev.patch b/queue-6.1/bluetooth-hci_qca-fix-driver-shutdown-on-closed-serdev.patch new file mode 100644 index 00000000000..0efb7767dcf --- /dev/null +++ b/queue-6.1/bluetooth-hci_qca-fix-driver-shutdown-on-closed-serdev.patch @@ -0,0 +1,90 @@ +From 272970be3dabd24cbe50e393ffee8f04aec3b9a8 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Thu, 29 Dec 2022 11:28:29 +0100 +Subject: Bluetooth: hci_qca: Fix driver shutdown on closed serdev + +From: Krzysztof Kozlowski + +commit 272970be3dabd24cbe50e393ffee8f04aec3b9a8 upstream. + +The driver shutdown callback (which sends EDL_SOC_RESET to the device +over serdev) should not be invoked when HCI device is not open (e.g. if +hci_dev_open_sync() failed), because the serdev and its TTY are not open +either. Also skip this step if device is powered off +(qca_power_shutdown()). + +The shutdown callback causes use-after-free during system reboot with +Qualcomm Atheros Bluetooth: + + Unable to handle kernel paging request at virtual address + 0072662f67726fd7 + ... + CPU: 6 PID: 1 Comm: systemd-shutdow Tainted: G W + 6.1.0-rt5-00325-g8a5f56bcfcca #8 + Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) + Call trace: + tty_driver_flush_buffer+0x4/0x30 + serdev_device_write_flush+0x24/0x34 + qca_serdev_shutdown+0x80/0x130 [hci_uart] + device_shutdown+0x15c/0x260 + kernel_restart+0x48/0xac + +KASAN report: + + BUG: KASAN: use-after-free in tty_driver_flush_buffer+0x1c/0x50 + Read of size 8 at addr ffff16270c2e0018 by task systemd-shutdow/1 + + CPU: 7 PID: 1 Comm: systemd-shutdow Not tainted + 6.1.0-next-20221220-00014-gb85aaf97fb01-dirty #28 + Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) + Call trace: + dump_backtrace.part.0+0xdc/0xf0 + show_stack+0x18/0x30 + dump_stack_lvl+0x68/0x84 + print_report+0x188/0x488 + kasan_report+0xa4/0xf0 + __asan_load8+0x80/0xac + tty_driver_flush_buffer+0x1c/0x50 + ttyport_write_flush+0x34/0x44 + serdev_device_write_flush+0x48/0x60 + qca_serdev_shutdown+0x124/0x274 + device_shutdown+0x1e8/0x350 + kernel_restart+0x48/0xb0 + __do_sys_reboot+0x244/0x2d0 + __arm64_sys_reboot+0x54/0x70 + invoke_syscall+0x60/0x190 + el0_svc_common.constprop.0+0x7c/0x160 + do_el0_svc+0x44/0xf0 + el0_svc+0x2c/0x6c + el0t_64_sync_handler+0xbc/0x140 + el0t_64_sync+0x190/0x194 + +Fixes: 7e7bbddd029b ("Bluetooth: hci_qca: Fix qca6390 enable failure after warm reboot") +Cc: +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/hci_qca.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -2157,10 +2157,17 @@ static void qca_serdev_shutdown(struct d + int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS); + struct serdev_device *serdev = to_serdev_device(dev); + struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); ++ struct hci_uart *hu = &qcadev->serdev_hu; ++ struct hci_dev *hdev = hu->hdev; ++ struct qca_data *qca = hu->priv; + const u8 ibs_wake_cmd[] = { 0xFD }; + const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 }; + + if (qcadev->btsoc_type == QCA_QCA6390) { ++ if (test_bit(QCA_BT_OFF, &qca->flags) || ++ !test_bit(HCI_RUNNING, &hdev->flags)) ++ return; ++ + serdev_device_write_flush(serdev); + ret = serdev_device_write_buf(serdev, ibs_wake_cmd, + sizeof(ibs_wake_cmd)); diff --git a/queue-6.1/bluetooth-hci_sync-fix-use-hci_op_le_read_buffer_size_v2.patch b/queue-6.1/bluetooth-hci_sync-fix-use-hci_op_le_read_buffer_size_v2.patch new file mode 100644 index 00000000000..fc19efa6468 --- /dev/null +++ b/queue-6.1/bluetooth-hci_sync-fix-use-hci_op_le_read_buffer_size_v2.patch @@ -0,0 +1,47 @@ +From 3a4d29b6d631bb00236a98887e1039bbfc1b6ab5 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Mon, 19 Dec 2022 13:32:51 -0800 +Subject: Bluetooth: hci_sync: Fix use HCI_OP_LE_READ_BUFFER_SIZE_V2 + +From: Luiz Augusto von Dentz + +commit 3a4d29b6d631bb00236a98887e1039bbfc1b6ab5 upstream. + +Don't try to use HCI_OP_LE_READ_BUFFER_SIZE_V2 if controller don't +support ISO channels, but in order to check if ISO channels are +supported HCI_OP_LE_READ_LOCAL_FEATURES needs to be done earlier so the +features bits can be checked on hci_le_read_buffer_size_sync. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216817 +Fixes: c1631dbc00c1 ("Bluetooth: hci_sync: Fix hci_read_buffer_size_sync") +Cc: stable@vger.kernel.org # 6.1 +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_sync.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -3554,7 +3554,7 @@ static const struct hci_init_stage hci_i + static int hci_le_read_buffer_size_sync(struct hci_dev *hdev) + { + /* Use Read LE Buffer Size V2 if supported */ +- if (hdev->commands[41] & 0x20) ++ if (iso_capable(hdev) && hdev->commands[41] & 0x20) + return __hci_cmd_sync_status(hdev, + HCI_OP_LE_READ_BUFFER_SIZE_V2, + 0, NULL, HCI_CMD_TIMEOUT); +@@ -3579,10 +3579,10 @@ static int hci_le_read_supported_states_ + + /* LE Controller init stage 2 command sequence */ + static const struct hci_init_stage le_init2[] = { +- /* HCI_OP_LE_READ_BUFFER_SIZE */ +- HCI_INIT(hci_le_read_buffer_size_sync), + /* HCI_OP_LE_READ_LOCAL_FEATURES */ + HCI_INIT(hci_le_read_local_features_sync), ++ /* HCI_OP_LE_READ_BUFFER_SIZE */ ++ HCI_INIT(hci_le_read_buffer_size_sync), + /* HCI_OP_LE_READ_SUPPORTED_STATES */ + HCI_INIT(hci_le_read_supported_states_sync), + {} diff --git a/queue-6.1/hugetlb-unshare-some-pmds-when-splitting-vmas.patch b/queue-6.1/hugetlb-unshare-some-pmds-when-splitting-vmas.patch new file mode 100644 index 00000000000..778a9b42f26 --- /dev/null +++ b/queue-6.1/hugetlb-unshare-some-pmds-when-splitting-vmas.patch @@ -0,0 +1,123 @@ +From b30c14cd61025eeea2f2e8569606cd167ba9ad2d Mon Sep 17 00:00:00 2001 +From: James Houghton +Date: Wed, 4 Jan 2023 23:19:10 +0000 +Subject: hugetlb: unshare some PMDs when splitting VMAs + +From: James Houghton + +commit b30c14cd61025eeea2f2e8569606cd167ba9ad2d upstream. + +PMD sharing can only be done in PUD_SIZE-aligned pieces of VMAs; however, +it is possible that HugeTLB VMAs are split without unsharing the PMDs +first. + +Without this fix, it is possible to hit the uffd-wp-related WARN_ON_ONCE +in hugetlb_change_protection [1]. The key there is that +hugetlb_unshare_all_pmds will not attempt to unshare PMDs in +non-PUD_SIZE-aligned sections of the VMA. + +It might seem ideal to unshare in hugetlb_vm_op_open, but we need to +unshare in both the new and old VMAs, so unsharing in hugetlb_vm_op_split +seems natural. + +[1]: https://lore.kernel.org/linux-mm/CADrL8HVeOkj0QH5VZZbRzybNE8CG-tEGFshnA+bG9nMgcWtBSg@mail.gmail.com/ + +Link: https://lkml.kernel.org/r/20230104231910.1464197-1-jthoughton@google.com +Fixes: 6dfeaff93be1 ("hugetlb/userfaultfd: unshare all pmds for hugetlbfs when register wp") +Signed-off-by: James Houghton +Reviewed-by: Mike Kravetz +Acked-by: Peter Xu +Cc: Axel Rasmussen +Cc: Muchun Song +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/hugetlb.c | 44 +++++++++++++++++++++++++++++++++++--------- + 1 file changed, 35 insertions(+), 9 deletions(-) + +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -94,6 +94,8 @@ static int hugetlb_acct_memory(struct hs + static void hugetlb_vma_lock_free(struct vm_area_struct *vma); + static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma); + static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma); ++static void hugetlb_unshare_pmds(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end); + + static inline bool subpool_is_free(struct hugepage_subpool *spool) + { +@@ -4825,6 +4827,25 @@ static int hugetlb_vm_op_split(struct vm + { + if (addr & ~(huge_page_mask(hstate_vma(vma)))) + return -EINVAL; ++ ++ /* ++ * PMD sharing is only possible for PUD_SIZE-aligned address ranges ++ * in HugeTLB VMAs. If we will lose PUD_SIZE alignment due to this ++ * split, unshare PMDs in the PUD_SIZE interval surrounding addr now. ++ */ ++ if (addr & ~PUD_MASK) { ++ /* ++ * hugetlb_vm_op_split is called right before we attempt to ++ * split the VMA. We will need to unshare PMDs in the old and ++ * new VMAs, so let's unshare before we split. ++ */ ++ unsigned long floor = addr & PUD_MASK; ++ unsigned long ceil = floor + PUD_SIZE; ++ ++ if (floor >= vma->vm_start && ceil <= vma->vm_end) ++ hugetlb_unshare_pmds(vma, floor, ceil); ++ } ++ + return 0; + } + +@@ -7386,26 +7407,21 @@ void move_hugetlb_state(struct page *old + } + } + +-/* +- * This function will unconditionally remove all the shared pmd pgtable entries +- * within the specific vma for a hugetlbfs memory range. +- */ +-void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) ++static void hugetlb_unshare_pmds(struct vm_area_struct *vma, ++ unsigned long start, ++ unsigned long end) + { + struct hstate *h = hstate_vma(vma); + unsigned long sz = huge_page_size(h); + struct mm_struct *mm = vma->vm_mm; + struct mmu_notifier_range range; +- unsigned long address, start, end; ++ unsigned long address; + spinlock_t *ptl; + pte_t *ptep; + + if (!(vma->vm_flags & VM_MAYSHARE)) + return; + +- start = ALIGN(vma->vm_start, PUD_SIZE); +- end = ALIGN_DOWN(vma->vm_end, PUD_SIZE); +- + if (start >= end) + return; + +@@ -7437,6 +7453,16 @@ void hugetlb_unshare_all_pmds(struct vm_ + mmu_notifier_invalidate_range_end(&range); + } + ++/* ++ * This function will unconditionally remove all the shared pmd pgtable entries ++ * within the specific vma for a hugetlbfs memory range. ++ */ ++void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) ++{ ++ hugetlb_unshare_pmds(vma, ALIGN(vma->vm_start, PUD_SIZE), ++ ALIGN_DOWN(vma->vm_end, PUD_SIZE)); ++} ++ + #ifdef CONFIG_CMA + static bool cma_reserve_called __initdata; + diff --git a/queue-6.1/loongarch-add-hwcap_loongarch_cpucfg-to-elf_hwcap.patch b/queue-6.1/loongarch-add-hwcap_loongarch_cpucfg-to-elf_hwcap.patch new file mode 100644 index 00000000000..35189f71596 --- /dev/null +++ b/queue-6.1/loongarch-add-hwcap_loongarch_cpucfg-to-elf_hwcap.patch @@ -0,0 +1,31 @@ +From d52fec86a465355b379e839fa372ead0334d62e6 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Tue, 17 Jan 2023 11:42:16 +0800 +Subject: LoongArch: Add HWCAP_LOONGARCH_CPUCFG to elf_hwcap + +From: Huacai Chen + +commit d52fec86a465355b379e839fa372ead0334d62e6 upstream. + +HWCAP_LOONGARCH_CPUCFG is missing in elf_hwcap, so add it for glibc's +later use. + +Cc: stable@vger.kernel.org +Reported-by: Yinyu Cai +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + arch/loongarch/kernel/cpu-probe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/loongarch/kernel/cpu-probe.c ++++ b/arch/loongarch/kernel/cpu-probe.c +@@ -94,7 +94,7 @@ static void cpu_probe_common(struct cpui + c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR | + LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH; + +- elf_hwcap |= HWCAP_LOONGARCH_CRC32; ++ elf_hwcap = HWCAP_LOONGARCH_CPUCFG | HWCAP_LOONGARCH_CRC32; + + config = read_cpucfg(LOONGARCH_CPUCFG1); + if (config & CPUCFG1_UAL) { diff --git a/queue-6.1/mm-khugepaged-fix-collapse_pte_mapped_thp-to-allow-anon_vma.patch b/queue-6.1/mm-khugepaged-fix-collapse_pte_mapped_thp-to-allow-anon_vma.patch new file mode 100644 index 00000000000..b92fafa8f14 --- /dev/null +++ b/queue-6.1/mm-khugepaged-fix-collapse_pte_mapped_thp-to-allow-anon_vma.patch @@ -0,0 +1,80 @@ +From ab0c3f1251b4670978fde0bd54161795a139b060 Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +Date: Thu, 22 Dec 2022 12:41:50 -0800 +Subject: mm/khugepaged: fix collapse_pte_mapped_thp() to allow anon_vma + +From: Hugh Dickins + +commit ab0c3f1251b4670978fde0bd54161795a139b060 upstream. + +uprobe_write_opcode() uses collapse_pte_mapped_thp() to restore huge pmd, +when removing a breakpoint from hugepage text: vma->anon_vma is always set +in that case, so undo the prohibition. And MADV_COLLAPSE ought to be able +to collapse some page tables in a vma which happens to have anon_vma set +from CoWing elsewhere. + +Is anon_vma lock required? Almost not: if any page other than expected +subpage of the non-anon huge page is found in the page table, collapse is +aborted without making any change. However, it is possible that an anon +page was CoWed from this extent in another mm or vma, in which case a +concurrent lookup might look here: so keep it away while clearing pmd (but +perhaps we shall go back to using pmd_lock() there in future). + +Note that collapse_pte_mapped_thp() is exceptional in freeing a page table +without having cleared its ptes: I'm uneasy about that, and had thought +pte_clear()ing appropriate; but exclusive i_mmap lock does fix the +problem, and we would have to move the mmu_notification if clearing those +ptes. + +What this fixes is not a dangerous instability. But I suggest Cc stable +because uprobes "healing" has regressed in that way, so this should follow +8d3c106e19e8 into those stable releases where it was backported (and may +want adjustment there - I'll supply backports as needed). + +Link: https://lkml.kernel.org/r/b740c9fb-edba-92ba-59fb-7a5592e5dfc@google.com +Fixes: 8d3c106e19e8 ("mm/khugepaged: take the right locks for page table retraction") +Signed-off-by: Hugh Dickins +Acked-by: David Hildenbrand +Cc: Jann Horn +Cc: Yang Shi +Cc: Zach O'Keefe +Cc: Song Liu +Cc: [5.4+] +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/khugepaged.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/mm/khugepaged.c ++++ b/mm/khugepaged.c +@@ -1467,14 +1467,6 @@ int collapse_pte_mapped_thp(struct mm_st + if (!hugepage_vma_check(vma, vma->vm_flags, false, false, false)) + return SCAN_VMA_CHECK; + +- /* +- * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings +- * that got written to. Without this, we'd have to also lock the +- * anon_vma if one exists. +- */ +- if (vma->anon_vma) +- return SCAN_VMA_CHECK; +- + /* Keep pmd pgtable for uffd-wp; see comment in retract_page_tables() */ + if (userfaultfd_wp(vma)) + return SCAN_PTE_UFFD_WP; +@@ -1574,8 +1566,14 @@ int collapse_pte_mapped_thp(struct mm_st + } + + /* step 4: remove pte entries */ ++ /* we make no change to anon, but protect concurrent anon page lookup */ ++ if (vma->anon_vma) ++ anon_vma_lock_write(vma->anon_vma); ++ + collapse_and_free_pmd(mm, vma, haddr, pmd); + ++ if (vma->anon_vma) ++ anon_vma_unlock_write(vma->anon_vma); + i_mmap_unlock_write(vma->vm_file->f_mapping); + + maybe_install_pmd: diff --git a/queue-6.1/mm-shmem-restore-shmem_huge_deny-precedence-over-madv_collapse.patch b/queue-6.1/mm-shmem-restore-shmem_huge_deny-precedence-over-madv_collapse.patch new file mode 100644 index 00000000000..b5363ad62b6 --- /dev/null +++ b/queue-6.1/mm-shmem-restore-shmem_huge_deny-precedence-over-madv_collapse.patch @@ -0,0 +1,47 @@ +From 3de0c269adc6c2fac0bb1fb11965f0de699dc32b Mon Sep 17 00:00:00 2001 +From: Zach O'Keefe +Date: Sat, 24 Dec 2022 00:20:35 -0800 +Subject: mm/shmem: restore SHMEM_HUGE_DENY precedence over MADV_COLLAPSE + +From: Zach O'Keefe + +commit 3de0c269adc6c2fac0bb1fb11965f0de699dc32b upstream. + +SHMEM_HUGE_DENY is for emergency use by the admin, to disable allocation +of shmem huge pages if, for example, a dangerous bug is found in their +usage: see "deny" in Documentation/mm/transhuge.rst. An app using +madvise(,,MADV_COLLAPSE) should not be allowed to override it: restore its +precedence over shmem_huge_force. + +Restore SHMEM_HUGE_DENY precedence over MADV_COLLAPSE. + +Link: https://lkml.kernel.org/r/20221224082035.3197140-2-zokeefe@google.com +Fixes: 7c6c6cc4d3a2 ("mm/shmem: add flag to enforce shmem THP in hugepage_vma_check()") +Signed-off-by: Zach O'Keefe +Suggested-by: Hugh Dickins +Acked-by: David Hildenbrand +Cc: Yang Shi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/shmem.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -472,12 +472,10 @@ bool shmem_is_huge(struct vm_area_struct + if (vma && ((vma->vm_flags & VM_NOHUGEPAGE) || + test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))) + return false; +- if (shmem_huge_force) +- return true; +- if (shmem_huge == SHMEM_HUGE_FORCE) +- return true; + if (shmem_huge == SHMEM_HUGE_DENY) + return false; ++ if (shmem_huge_force || shmem_huge == SHMEM_HUGE_FORCE) ++ return true; + + switch (SHMEM_SB(inode->i_sb)->huge) { + case SHMEM_HUGE_ALWAYS: diff --git a/queue-6.1/nilfs2-fix-general-protection-fault-in-nilfs_btree_insert.patch b/queue-6.1/nilfs2-fix-general-protection-fault-in-nilfs_btree_insert.patch new file mode 100644 index 00000000000..f05a9d5595b --- /dev/null +++ b/queue-6.1/nilfs2-fix-general-protection-fault-in-nilfs_btree_insert.patch @@ -0,0 +1,102 @@ +From 7633355e5c7f29c049a9048e461427d1d8ed3051 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Thu, 5 Jan 2023 14:53:56 +0900 +Subject: nilfs2: fix general protection fault in nilfs_btree_insert() + +From: Ryusuke Konishi + +commit 7633355e5c7f29c049a9048e461427d1d8ed3051 upstream. + +If nilfs2 reads a corrupted disk image and tries to reads a b-tree node +block by calling __nilfs_btree_get_block() against an invalid virtual +block address, it returns -ENOENT because conversion of the virtual block +address to a disk block address fails. However, this return value is the +same as the internal code that b-tree lookup routines return to indicate +that the block being searched does not exist, so functions that operate on +that b-tree may misbehave. + +When nilfs_btree_insert() receives this spurious 'not found' code from +nilfs_btree_do_lookup(), it misunderstands that the 'not found' check was +successful and continues the insert operation using incomplete lookup path +data, causing the following crash: + + general protection fault, probably for non-canonical address + 0xdffffc0000000005: 0000 [#1] PREEMPT SMP KASAN + KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f] + ... + RIP: 0010:nilfs_btree_get_nonroot_node fs/nilfs2/btree.c:418 [inline] + RIP: 0010:nilfs_btree_prepare_insert fs/nilfs2/btree.c:1077 [inline] + RIP: 0010:nilfs_btree_insert+0x6d3/0x1c10 fs/nilfs2/btree.c:1238 + Code: bc 24 80 00 00 00 4c 89 f8 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 + ff e8 4b 02 92 fe 4d 8b 3f 49 83 c7 28 4c 89 f8 48 c1 e8 03 <42> 80 3c + 28 00 74 08 4c 89 ff e8 2e 02 92 fe 4d 8b 3f 49 83 c7 02 + ... + Call Trace: + + nilfs_bmap_do_insert fs/nilfs2/bmap.c:121 [inline] + nilfs_bmap_insert+0x20d/0x360 fs/nilfs2/bmap.c:147 + nilfs_get_block+0x414/0x8d0 fs/nilfs2/inode.c:101 + __block_write_begin_int+0x54c/0x1a80 fs/buffer.c:1991 + __block_write_begin fs/buffer.c:2041 [inline] + block_write_begin+0x93/0x1e0 fs/buffer.c:2102 + nilfs_write_begin+0x9c/0x110 fs/nilfs2/inode.c:261 + generic_perform_write+0x2e4/0x5e0 mm/filemap.c:3772 + __generic_file_write_iter+0x176/0x400 mm/filemap.c:3900 + generic_file_write_iter+0xab/0x310 mm/filemap.c:3932 + call_write_iter include/linux/fs.h:2186 [inline] + new_sync_write fs/read_write.c:491 [inline] + vfs_write+0x7dc/0xc50 fs/read_write.c:584 + ksys_write+0x177/0x2a0 fs/read_write.c:637 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + ... + + +This patch fixes the root cause of this problem by replacing the error +code that __nilfs_btree_get_block() returns on block address conversion +failure from -ENOENT to another internal code -EINVAL which means that the +b-tree metadata is corrupted. + +By returning -EINVAL, it propagates without glitches, and for all relevant +b-tree operations, functions in the upper bmap layer output an error +message indicating corrupted b-tree metadata via +nilfs_bmap_convert_error(), and code -EIO will be eventually returned as +it should be. + +Link: https://lkml.kernel.org/r/000000000000bd89e205f0e38355@google.com +Link: https://lkml.kernel.org/r/20230105055356.8811-1-konishi.ryusuke@gmail.com +Signed-off-by: Ryusuke Konishi +Reported-by: syzbot+ede796cecd5296353515@syzkaller.appspotmail.com +Tested-by: Ryusuke Konishi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/nilfs2/btree.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/fs/nilfs2/btree.c ++++ b/fs/nilfs2/btree.c +@@ -480,9 +480,18 @@ static int __nilfs_btree_get_block(const + ret = nilfs_btnode_submit_block(btnc, ptr, 0, REQ_OP_READ, &bh, + &submit_ptr); + if (ret) { +- if (ret != -EEXIST) +- return ret; +- goto out_check; ++ if (likely(ret == -EEXIST)) ++ goto out_check; ++ if (ret == -ENOENT) { ++ /* ++ * Block address translation failed due to invalid ++ * value of 'ptr'. In this case, return internal code ++ * -EINVAL (broken bmap) to notify bmap layer of fatal ++ * metadata corruption. ++ */ ++ ret = -EINVAL; ++ } ++ return ret; + } + + if (ra) { diff --git a/queue-6.1/nommu-fix-do_munmap-error-path.patch b/queue-6.1/nommu-fix-do_munmap-error-path.patch new file mode 100644 index 00000000000..c51543d8605 --- /dev/null +++ b/queue-6.1/nommu-fix-do_munmap-error-path.patch @@ -0,0 +1,42 @@ +From 80be727ec87225797771a39f3e6801baf291faaf Mon Sep 17 00:00:00 2001 +From: Liam Howlett +Date: Mon, 9 Jan 2023 20:57:21 +0000 +Subject: nommu: fix do_munmap() error path + +From: Liam Howlett + +commit 80be727ec87225797771a39f3e6801baf291faaf upstream. + +When removing a VMA from the tree fails due to no memory, do not free the +VMA since a reference still exists. + +Link: https://lkml.kernel.org/r/20230109205708.956103-1-Liam.Howlett@oracle.com +Fixes: 8220543df148 ("nommu: remove uses of VMA linked list") +Signed-off-by: Liam R. Howlett +Cc: Matthew Wilcox (Oracle) +Cc: Vlastimil Babka +Cc: Yu Zhao +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/nommu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/mm/nommu.c b/mm/nommu.c +index c8252f01d5db..844af5be7640 100644 +--- a/mm/nommu.c ++++ b/mm/nommu.c +@@ -1509,7 +1509,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, struct list + erase_whole_vma: + if (delete_vma_from_mm(vma)) + ret = -ENOMEM; +- delete_vma(mm, vma); ++ else ++ delete_vma(mm, vma); + return ret; + } + +-- +2.39.1 + diff --git a/queue-6.1/nommu-fix-memory-leak-in-do_mmap-error-path.patch b/queue-6.1/nommu-fix-memory-leak-in-do_mmap-error-path.patch new file mode 100644 index 00000000000..e191319c79c --- /dev/null +++ b/queue-6.1/nommu-fix-memory-leak-in-do_mmap-error-path.patch @@ -0,0 +1,49 @@ +From 7f31cced5724e6d414fe750aa1cd7e7b578ec22f Mon Sep 17 00:00:00 2001 +From: Liam Howlett +Date: Mon, 9 Jan 2023 20:55:21 +0000 +Subject: nommu: fix memory leak in do_mmap() error path + +From: Liam Howlett + +commit 7f31cced5724e6d414fe750aa1cd7e7b578ec22f upstream. + +The preallocation of the maple tree nodes may leak if the error path to +"error_just_free" is taken. Fix this by moving the freeing of the maple +tree nodes to a shared location for all error paths. + +Link: https://lkml.kernel.org/r/20230109205507.955577-1-Liam.Howlett@oracle.com +Fixes: 8220543df148 ("nommu: remove uses of VMA linked list") +Signed-off-by: Liam R. Howlett +Cc: Matthew Wilcox (Oracle) +Cc: Vlastimil Babka +Cc: Yu Zhao +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/nommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mm/nommu.c b/mm/nommu.c +index 214c70e1d059..c8252f01d5db 100644 +--- a/mm/nommu.c ++++ b/mm/nommu.c +@@ -1240,6 +1240,7 @@ unsigned long do_mmap(struct file *file, + error_just_free: + up_write(&nommu_region_sem); + error: ++ mas_destroy(&mas); + if (region->vm_file) + fput(region->vm_file); + kmem_cache_free(vm_region_jar, region); +@@ -1250,7 +1251,6 @@ unsigned long do_mmap(struct file *file, + + sharing_violation: + up_write(&nommu_region_sem); +- mas_destroy(&mas); + pr_warn("Attempt to share mismatched mappings\n"); + ret = -EINVAL; + goto error; +-- +2.39.1 + diff --git a/queue-6.1/nommu-fix-split_vma-map_count-error.patch b/queue-6.1/nommu-fix-split_vma-map_count-error.patch new file mode 100644 index 00000000000..3e56fd89682 --- /dev/null +++ b/queue-6.1/nommu-fix-split_vma-map_count-error.patch @@ -0,0 +1,67 @@ +From fd9edbdbdcde6b489ce59f326755ef16a2ffadd7 Mon Sep 17 00:00:00 2001 +From: Liam Howlett +Date: Mon, 9 Jan 2023 20:58:20 +0000 +Subject: nommu: fix split_vma() map_count error + +From: Liam Howlett + +commit fd9edbdbdcde6b489ce59f326755ef16a2ffadd7 upstream. + +During the maple tree conversion of nommu, an error in counting the VMAs +was introduced by counting the existing VMA again. The counting used to +be decremented by one and incremented by two, but now it only increments +by two. Fix the counting error by moving the increment outside the +setup_vma_to_mm() function to the callers. + +Link: https://lkml.kernel.org/r/20230109205809.956325-1-Liam.Howlett@oracle.com +Fixes: 8220543df148 ("nommu: remove uses of VMA linked list") +Signed-off-by: Liam R. Howlett +Cc: Matthew Wilcox (Oracle) +Cc: Vlastimil Babka +Cc: Yu Zhao +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/nommu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/mm/nommu.c b/mm/nommu.c +index 844af5be7640..5b83938ecb67 100644 +--- a/mm/nommu.c ++++ b/mm/nommu.c +@@ -559,7 +559,6 @@ void vma_mas_remove(struct vm_area_struct *vma, struct ma_state *mas) + + static void setup_vma_to_mm(struct vm_area_struct *vma, struct mm_struct *mm) + { +- mm->map_count++; + vma->vm_mm = mm; + + /* add the VMA to the mapping */ +@@ -587,6 +586,7 @@ static void mas_add_vma_to_mm(struct ma_state *mas, struct mm_struct *mm, + BUG_ON(!vma->vm_region); + + setup_vma_to_mm(vma, mm); ++ mm->map_count++; + + /* add the VMA to the tree */ + vma_mas_store(vma, mas); +@@ -1347,6 +1347,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, + if (vma->vm_file) + return -ENOMEM; + ++ mm = vma->vm_mm; + if (mm->map_count >= sysctl_max_map_count) + return -ENOMEM; + +@@ -1398,6 +1399,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, + mas_set_range(&mas, vma->vm_start, vma->vm_end - 1); + mas_store(&mas, vma); + vma_mas_store(new, &mas); ++ mm->map_count++; + return 0; + + err_mas_preallocate: +-- +2.39.1 + diff --git a/queue-6.1/proc-fix-pie-proc-empty-vm-proc-pid-vm-tests.patch b/queue-6.1/proc-fix-pie-proc-empty-vm-proc-pid-vm-tests.patch new file mode 100644 index 00000000000..b4cf14beea1 --- /dev/null +++ b/queue-6.1/proc-fix-pie-proc-empty-vm-proc-pid-vm-tests.patch @@ -0,0 +1,117 @@ +From 5316a017d093f644675a56523bcf5787ba8f4fef Mon Sep 17 00:00:00 2001 +From: Alexey Dobriyan +Date: Fri, 6 Jan 2023 22:30:14 +0300 +Subject: proc: fix PIE proc-empty-vm, proc-pid-vm tests + +From: Alexey Dobriyan + +commit 5316a017d093f644675a56523bcf5787ba8f4fef upstream. + +vsyscall detection code uses direct call to the beginning of +the vsyscall page: + + asm ("call %P0" :: "i" (0xffffffffff600000)) + +It generates "call rel32" instruction but it is not relocated if binary +is PIE, so binary segfaults into random userspace address and vsyscall +page status is detected incorrectly. + +Do more direct: + + asm ("call *%rax") + +which doesn't do need any relocaltions. + +Mark g_vsyscall as volatile for a good measure, I didn't find instruction +setting it to 0. Now the code is obviously correct: + + xor eax, eax + mov rdi, rbp + mov rsi, rbp + mov DWORD PTR [rip+0x2d15], eax # g_vsyscall = 0 + mov rax, 0xffffffffff600000 + call rax + mov DWORD PTR [rip+0x2d02], 1 # g_vsyscall = 1 + mov eax, DWORD PTR ds:0xffffffffff600000 + mov DWORD PTR [rip+0x2cf1], 2 # g_vsyscall = 2 + mov edi, [rip+0x2ceb] # exit(g_vsyscall) + call exit + +Note: fixed proc-empty-vm test oopses 5.19.0-28-generic kernel + but this is separate story. + +Link: https://lkml.kernel.org/r/Y7h2xvzKLg36DSq8@p183 +Fixes: 5bc73bb3451b9 ("proc: test how it holds up with mapping'less process") +Signed-off-by: Alexey Dobriyan +Reported-by: Mirsad Goran Todorovac +Tested-by: Mirsad Goran Todorovac +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/proc/proc-empty-vm.c | 12 +++++++----- + tools/testing/selftests/proc/proc-pid-vm.c | 9 +++++---- + 2 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/tools/testing/selftests/proc/proc-empty-vm.c b/tools/testing/selftests/proc/proc-empty-vm.c +index d95b1cb43d9d..7588428b8fcd 100644 +--- a/tools/testing/selftests/proc/proc-empty-vm.c ++++ b/tools/testing/selftests/proc/proc-empty-vm.c +@@ -25,6 +25,7 @@ + #undef NDEBUG + #include + #include ++#include + #include + #include + #include +@@ -41,7 +42,7 @@ + * 1: vsyscall VMA is --xp vsyscall=xonly + * 2: vsyscall VMA is r-xp vsyscall=emulate + */ +-static int g_vsyscall; ++static volatile int g_vsyscall; + static const char *g_proc_pid_maps_vsyscall; + static const char *g_proc_pid_smaps_vsyscall; + +@@ -147,11 +148,12 @@ static void vsyscall(void) + + g_vsyscall = 0; + /* gettimeofday(NULL, NULL); */ ++ uint64_t rax = 0xffffffffff600000; + asm volatile ( +- "call %P0" +- : +- : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) +- : "rax", "rcx", "r11" ++ "call *%[rax]" ++ : [rax] "+a" (rax) ++ : "D" (NULL), "S" (NULL) ++ : "rcx", "r11" + ); + + g_vsyscall = 1; +diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c +index 69551bfa215c..cacbd2a4aec9 100644 +--- a/tools/testing/selftests/proc/proc-pid-vm.c ++++ b/tools/testing/selftests/proc/proc-pid-vm.c +@@ -257,11 +257,12 @@ static void vsyscall(void) + + g_vsyscall = 0; + /* gettimeofday(NULL, NULL); */ ++ uint64_t rax = 0xffffffffff600000; + asm volatile ( +- "call %P0" +- : +- : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) +- : "rax", "rcx", "r11" ++ "call *%[rax]" ++ : [rax] "+a" (rax) ++ : "D" (NULL), "S" (NULL) ++ : "rcx", "r11" + ); + + g_vsyscall = 1; +-- +2.39.1 + diff --git a/queue-6.1/series b/queue-6.1/series index cf6ade26eb7..500325e366b 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -27,3 +27,21 @@ perf-x86-rapl-add-support-for-intel-meteor-lake.patch perf-x86-rapl-add-support-for-intel-emerald-rapids.patch of-fdt-honor-config_cmdline-even-without-chosen-node.patch fbdev-omapfb-avoid-stack-overflow-warning.patch +bluetooth-hci_sync-fix-use-hci_op_le_read_buffer_size_v2.patch +bluetooth-hci_qca-fix-driver-shutdown-on-closed-serdev.patch +wifi-brcmfmac-fix-regression-for-broadcom-pcie-wifi-devices.patch +wifi-mac80211-fix-mlo-ap_vlan-check.patch +wifi-mac80211-reset-multiple-bssid-options-in-stop_ap.patch +wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch +wifi-mac80211-fix-initialization-of-rx-link-and-rx-link_sta.patch +nommu-fix-memory-leak-in-do_mmap-error-path.patch +nommu-fix-do_munmap-error-path.patch +nommu-fix-split_vma-map_count-error.patch +proc-fix-pie-proc-empty-vm-proc-pid-vm-tests.patch +add-exception-protection-processing-for-vd-in-axi_chan_handle_err-function.patch +loongarch-add-hwcap_loongarch_cpucfg-to-elf_hwcap.patch +zonefs-detect-append-writes-at-invalid-locations.patch +nilfs2-fix-general-protection-fault-in-nilfs_btree_insert.patch +mm-shmem-restore-shmem_huge_deny-precedence-over-madv_collapse.patch +hugetlb-unshare-some-pmds-when-splitting-vmas.patch +mm-khugepaged-fix-collapse_pte_mapped_thp-to-allow-anon_vma.patch diff --git a/queue-6.1/wifi-brcmfmac-fix-regression-for-broadcom-pcie-wifi-devices.patch b/queue-6.1/wifi-brcmfmac-fix-regression-for-broadcom-pcie-wifi-devices.patch new file mode 100644 index 00000000000..b5cca885a6a --- /dev/null +++ b/queue-6.1/wifi-brcmfmac-fix-regression-for-broadcom-pcie-wifi-devices.patch @@ -0,0 +1,39 @@ +From ed05cb177ae5cd7f02f1d6e7706ba627d30f1696 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Wed, 11 Jan 2023 12:24:19 +0100 +Subject: wifi: brcmfmac: fix regression for Broadcom PCIe wifi devices + +From: Arend van Spriel + +commit ed05cb177ae5cd7f02f1d6e7706ba627d30f1696 upstream. + +A sanity check was introduced considering maximum flowrings above +256 as insane and effectively aborting the device probe. This +resulted in regression for number of users as the value turns out +to be sane after all. + +Fixes: 2aca4f3734bd ("brcmfmac: return error when getting invalid max_flowrings from dongle") +Reported-by: chainofflowers +Link: https://lore.kernel.org/all/4781984.GXAFRqVoOG@luna/ +Reported-by: Christian Marillat +Link: https://bugzilla.kernel.org/show_bug.cgi?id=216894 +Cc: stable@vger.kernel.org +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230111112419.24185-1-arend.vanspriel@broadcom.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1218,7 +1218,7 @@ static int brcmf_pcie_init_ringbuffers(s + BRCMF_NROF_H2D_COMMON_MSGRINGS; + max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS; + } +- if (max_flowrings > 256) { ++ if (max_flowrings > 512) { + brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings); + return -EIO; + } diff --git a/queue-6.1/wifi-mac80211-fix-initialization-of-rx-link-and-rx-link_sta.patch b/queue-6.1/wifi-mac80211-fix-initialization-of-rx-link-and-rx-link_sta.patch new file mode 100644 index 00000000000..c42d24cec95 --- /dev/null +++ b/queue-6.1/wifi-mac80211-fix-initialization-of-rx-link-and-rx-link_sta.patch @@ -0,0 +1,457 @@ +From e66b7920aa5ac5b1a1997a454004ba9246a3c005 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Fri, 30 Dec 2022 21:07:47 +0100 +Subject: wifi: mac80211: fix initialization of rx->link and rx->link_sta + +From: Felix Fietkau + +commit e66b7920aa5ac5b1a1997a454004ba9246a3c005 upstream. + +There are some codepaths that do not initialize rx->link_sta properly. This +causes a crash in places which assume that rx->link_sta is valid if rx->sta +is valid. +One known instance is triggered by __ieee80211_rx_h_amsdu being called from +fast-rx. It results in a crash like this one: + + BUG: kernel NULL pointer dereference, address: 00000000000000a8 + #PF: supervisor write access in kernel mode + #PF: error_code(0x0002) - not-present page PGD 0 P4D 0 + Oops: 0002 [#1] PREEMPT SMP PTI + CPU: 1 PID: 506 Comm: mt76-usb-rx phy Tainted: G E 6.1.0-debian64x+1.7 #3 + Hardware name: ZOTAC ZBOX-ID92/ZBOX-IQ01/ZBOX-ID92/ZBOX-IQ01, BIOS B220P007 05/21/2014 + RIP: 0010:ieee80211_deliver_skb+0x62/0x1f0 [mac80211] + Code: 00 48 89 04 24 e8 9e a7 c3 df 89 c0 48 03 1c c5 a0 ea 39 a1 4c 01 6b 08 48 ff 03 48 + 83 7d 28 00 74 11 48 8b 45 30 48 63 55 44 <48> 83 84 d0 a8 00 00 00 01 41 8b 86 c0 + 11 00 00 8d 50 fd 83 fa 01 + RSP: 0018:ffff999040803b10 EFLAGS: 00010286 + RAX: 0000000000000000 RBX: ffffb9903f496480 RCX: 0000000000000000 + RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: ffff999040803ce0 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000000 R12: ffff8d21828ac900 + R13: 000000000000004a R14: ffff8d2198ed89c0 R15: ffff8d2198ed8000 + FS: 0000000000000000(0000) GS:ffff8d24afe80000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00000000000000a8 CR3: 0000000429810002 CR4: 00000000001706e0 + Call Trace: + + __ieee80211_rx_h_amsdu+0x1b5/0x240 [mac80211] + ? ieee80211_prepare_and_rx_handle+0xcdd/0x1320 [mac80211] + ? __local_bh_enable_ip+0x3b/0xa0 + ieee80211_prepare_and_rx_handle+0xcdd/0x1320 [mac80211] + ? prepare_transfer+0x109/0x1a0 [xhci_hcd] + ieee80211_rx_list+0xa80/0xda0 [mac80211] + mt76_rx_complete+0x207/0x2e0 [mt76] + mt76_rx_poll_complete+0x357/0x5a0 [mt76] + mt76u_rx_worker+0x4f5/0x600 [mt76_usb] + ? mt76_get_min_avg_rssi+0x140/0x140 [mt76] + __mt76_worker_fn+0x50/0x80 [mt76] + kthread+0xed/0x120 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x22/0x30 + +Since the initialization of rx->link and rx->link_sta is rather convoluted +and duplicated in many places, clean it up by using a helper function to +set it. + +Fixes: ccdde7c74ffd ("wifi: mac80211: properly implement MLO key handling") +Fixes: b320d6c456ff ("wifi: mac80211: use correct rx link_sta instead of default") +Signed-off-by: Felix Fietkau +Link: https://lore.kernel.org/r/20221230200747.19040-1-nbd@nbd.name +[remove unnecessary rx->sta->sta.mlo check] +Cc: stable@vger.kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/rx.c | 222 ++++++++++++++++++++++++------------------------------ + 1 file changed, 99 insertions(+), 123 deletions(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4070,6 +4070,58 @@ static void ieee80211_invoke_rx_handlers + #undef CALL_RXH + } + ++static bool ++ieee80211_rx_is_valid_sta_link_id(struct ieee80211_sta *sta, u8 link_id) ++{ ++ if (!sta->mlo) ++ return false; ++ ++ return !!(sta->valid_links & BIT(link_id)); ++} ++ ++static bool ieee80211_rx_data_set_link(struct ieee80211_rx_data *rx, ++ u8 link_id) ++{ ++ rx->link_id = link_id; ++ rx->link = rcu_dereference(rx->sdata->link[link_id]); ++ ++ if (!rx->sta) ++ return rx->link; ++ ++ if (!ieee80211_rx_is_valid_sta_link_id(&rx->sta->sta, link_id)) ++ return false; ++ ++ rx->link_sta = rcu_dereference(rx->sta->link[link_id]); ++ ++ return rx->link && rx->link_sta; ++} ++ ++static bool ieee80211_rx_data_set_sta(struct ieee80211_rx_data *rx, ++ struct ieee80211_sta *pubsta, ++ int link_id) ++{ ++ struct sta_info *sta; ++ ++ sta = container_of(pubsta, struct sta_info, sta); ++ ++ rx->link_id = link_id; ++ rx->sta = sta; ++ ++ if (sta) { ++ rx->local = sta->sdata->local; ++ if (!rx->sdata) ++ rx->sdata = sta->sdata; ++ rx->link_sta = &sta->deflink; ++ } ++ ++ if (link_id < 0) ++ rx->link = &rx->sdata->deflink; ++ else if (!ieee80211_rx_data_set_link(rx, link_id)) ++ return false; ++ ++ return true; ++} ++ + /* + * This function makes calls into the RX path, therefore + * it has to be invoked under RCU read lock. +@@ -4078,16 +4130,19 @@ void ieee80211_release_reorder_timeout(s + { + struct sk_buff_head frames; + struct ieee80211_rx_data rx = { +- .sta = sta, +- .sdata = sta->sdata, +- .local = sta->local, + /* This is OK -- must be QoS data frame */ + .security_idx = tid, + .seqno_idx = tid, +- .link_id = -1, + }; + struct tid_ampdu_rx *tid_agg_rx; +- u8 link_id; ++ int link_id = -1; ++ ++ /* FIXME: statistics won't be right with this */ ++ if (sta->sta.valid_links) ++ link_id = ffs(sta->sta.valid_links) - 1; ++ ++ if (!ieee80211_rx_data_set_sta(&rx, &sta->sta, link_id)) ++ return; + + tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); + if (!tid_agg_rx) +@@ -4107,10 +4162,6 @@ void ieee80211_release_reorder_timeout(s + }; + drv_event_callback(rx.local, rx.sdata, &event); + } +- /* FIXME: statistics won't be right with this */ +- link_id = sta->sta.valid_links ? ffs(sta->sta.valid_links) - 1 : 0; +- rx.link = rcu_dereference(sta->sdata->link[link_id]); +- rx.link_sta = rcu_dereference(sta->link[link_id]); + + ieee80211_rx_handlers(&rx, &frames); + } +@@ -4126,7 +4177,6 @@ void ieee80211_mark_rx_ba_filtered_frame + /* This is OK -- must be QoS data frame */ + .security_idx = tid, + .seqno_idx = tid, +- .link_id = -1, + }; + int i, diff; + +@@ -4137,10 +4187,8 @@ void ieee80211_mark_rx_ba_filtered_frame + + sta = container_of(pubsta, struct sta_info, sta); + +- rx.sta = sta; +- rx.sdata = sta->sdata; +- rx.link = &rx.sdata->deflink; +- rx.local = sta->local; ++ if (!ieee80211_rx_data_set_sta(&rx, pubsta, -1)) ++ return; + + rcu_read_lock(); + tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); +@@ -4527,15 +4575,6 @@ void ieee80211_check_fast_rx_iface(struc + mutex_unlock(&local->sta_mtx); + } + +-static bool +-ieee80211_rx_is_valid_sta_link_id(struct ieee80211_sta *sta, u8 link_id) +-{ +- if (!sta->mlo) +- return false; +- +- return !!(sta->valid_links & BIT(link_id)); +-} +- + static void ieee80211_rx_8023(struct ieee80211_rx_data *rx, + struct ieee80211_fast_rx *fast_rx, + int orig_len) +@@ -4646,7 +4685,6 @@ static bool ieee80211_invoke_fast_rx(str + struct sk_buff *skb = rx->skb; + struct ieee80211_hdr *hdr = (void *)skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); +- struct sta_info *sta = rx->sta; + int orig_len = skb->len; + int hdrlen = ieee80211_hdrlen(hdr->frame_control); + int snap_offs = hdrlen; +@@ -4658,7 +4696,6 @@ static bool ieee80211_invoke_fast_rx(str + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + } addrs __aligned(2); +- struct link_sta_info *link_sta; + struct ieee80211_sta_rx_stats *stats; + + /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write +@@ -4761,18 +4798,10 @@ static bool ieee80211_invoke_fast_rx(str + drop: + dev_kfree_skb(skb); + +- if (rx->link_id >= 0) { +- link_sta = rcu_dereference(sta->link[rx->link_id]); +- if (!link_sta) +- return true; +- } else { +- link_sta = &sta->deflink; +- } +- + if (fast_rx->uses_rss) +- stats = this_cpu_ptr(link_sta->pcpu_rx_stats); ++ stats = this_cpu_ptr(rx->link_sta->pcpu_rx_stats); + else +- stats = &link_sta->rx_stats; ++ stats = &rx->link_sta->rx_stats; + + stats->dropped++; + return true; +@@ -4790,8 +4819,8 @@ static bool ieee80211_prepare_and_rx_han + struct ieee80211_local *local = rx->local; + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_hdr *hdr = (void *)skb->data; +- struct link_sta_info *link_sta = NULL; +- struct ieee80211_link_data *link; ++ struct link_sta_info *link_sta = rx->link_sta; ++ struct ieee80211_link_data *link = rx->link; + + rx->skb = skb; + +@@ -4813,35 +4842,6 @@ static bool ieee80211_prepare_and_rx_han + if (!ieee80211_accept_frame(rx)) + return false; + +- if (rx->link_id >= 0) { +- link = rcu_dereference(rx->sdata->link[rx->link_id]); +- +- /* we might race link removal */ +- if (!link) +- return true; +- rx->link = link; +- +- if (rx->sta) { +- rx->link_sta = +- rcu_dereference(rx->sta->link[rx->link_id]); +- if (!rx->link_sta) +- return true; +- } +- } else { +- if (rx->sta) +- rx->link_sta = &rx->sta->deflink; +- +- rx->link = &sdata->deflink; +- } +- +- if (unlikely(!is_multicast_ether_addr(hdr->addr1) && +- rx->link_id >= 0 && rx->sta && rx->sta->sta.mlo)) { +- link_sta = rcu_dereference(rx->sta->link[rx->link_id]); +- +- if (WARN_ON_ONCE(!link_sta)) +- return true; +- } +- + if (!consume) { + struct skb_shared_hwtstamps *shwt; + +@@ -4861,7 +4861,7 @@ static bool ieee80211_prepare_and_rx_han + shwt->hwtstamp = skb_hwtstamps(skb)->hwtstamp; + } + +- if (unlikely(link_sta)) { ++ if (unlikely(rx->sta && rx->sta->sta.mlo)) { + /* translate to MLD addresses */ + if (ether_addr_equal(link->conf->addr, hdr->addr1)) + ether_addr_copy(hdr->addr1, rx->sdata->vif.addr); +@@ -4891,6 +4891,7 @@ static void __ieee80211_rx_handle_8023(s + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_fast_rx *fast_rx; + struct ieee80211_rx_data rx; ++ int link_id = -1; + + memset(&rx, 0, sizeof(rx)); + rx.skb = skb; +@@ -4907,12 +4908,8 @@ static void __ieee80211_rx_handle_8023(s + if (!pubsta) + goto drop; + +- rx.sta = container_of(pubsta, struct sta_info, sta); +- rx.sdata = rx.sta->sdata; +- +- if (status->link_valid && +- !ieee80211_rx_is_valid_sta_link_id(pubsta, status->link_id)) +- goto drop; ++ if (status->link_valid) ++ link_id = status->link_id; + + /* + * TODO: Should the frame be dropped if the right link_id is not +@@ -4921,19 +4918,8 @@ static void __ieee80211_rx_handle_8023(s + * link_id is used only for stats purpose and updating the stats on + * the deflink is fine? + */ +- if (status->link_valid) +- rx.link_id = status->link_id; +- +- if (rx.link_id >= 0) { +- struct ieee80211_link_data *link; +- +- link = rcu_dereference(rx.sdata->link[rx.link_id]); +- if (!link) +- goto drop; +- rx.link = link; +- } else { +- rx.link = &rx.sdata->deflink; +- } ++ if (!ieee80211_rx_data_set_sta(&rx, pubsta, link_id)) ++ goto drop; + + fast_rx = rcu_dereference(rx.sta->fast_rx); + if (!fast_rx) +@@ -4951,6 +4937,8 @@ static bool ieee80211_rx_for_interface(s + { + struct link_sta_info *link_sta; + struct ieee80211_hdr *hdr = (void *)skb->data; ++ struct sta_info *sta; ++ int link_id = -1; + + /* + * Look up link station first, in case there's a +@@ -4960,24 +4948,19 @@ static bool ieee80211_rx_for_interface(s + */ + link_sta = link_sta_info_get_bss(rx->sdata, hdr->addr2); + if (link_sta) { +- rx->sta = link_sta->sta; +- rx->link_id = link_sta->link_id; ++ sta = link_sta->sta; ++ link_id = link_sta->link_id; + } else { + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + +- rx->sta = sta_info_get_bss(rx->sdata, hdr->addr2); +- if (rx->sta) { +- if (status->link_valid && +- !ieee80211_rx_is_valid_sta_link_id(&rx->sta->sta, +- status->link_id)) +- return false; +- +- rx->link_id = status->link_valid ? status->link_id : -1; +- } else { +- rx->link_id = -1; +- } ++ sta = sta_info_get_bss(rx->sdata, hdr->addr2); ++ if (status->link_valid) ++ link_id = status->link_id; + } + ++ if (!ieee80211_rx_data_set_sta(rx, &sta->sta, link_id)) ++ return false; ++ + return ieee80211_prepare_and_rx_handle(rx, skb, consume); + } + +@@ -5036,19 +5019,15 @@ static void __ieee80211_rx_handle_packet + + if (ieee80211_is_data(fc)) { + struct sta_info *sta, *prev_sta; +- u8 link_id = status->link_id; ++ int link_id = -1; + +- if (pubsta) { +- rx.sta = container_of(pubsta, struct sta_info, sta); +- rx.sdata = rx.sta->sdata; ++ if (status->link_valid) ++ link_id = status->link_id; + +- if (status->link_valid && +- !ieee80211_rx_is_valid_sta_link_id(pubsta, link_id)) ++ if (pubsta) { ++ if (!ieee80211_rx_data_set_sta(&rx, pubsta, link_id)) + goto out; + +- if (status->link_valid) +- rx.link_id = status->link_id; +- + /* + * In MLO connection, fetch the link_id using addr2 + * when the driver does not pass link_id in status. +@@ -5066,7 +5045,7 @@ static void __ieee80211_rx_handle_packet + if (!link_sta) + goto out; + +- rx.link_id = link_sta->link_id; ++ ieee80211_rx_data_set_link(&rx, link_sta->link_id); + } + + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) +@@ -5082,30 +5061,27 @@ static void __ieee80211_rx_handle_packet + continue; + } + +- if ((status->link_valid && +- !ieee80211_rx_is_valid_sta_link_id(&prev_sta->sta, +- link_id)) || +- (!status->link_valid && prev_sta->sta.mlo)) ++ rx.sdata = prev_sta->sdata; ++ if (!ieee80211_rx_data_set_sta(&rx, &prev_sta->sta, ++ link_id)) ++ goto out; ++ ++ if (!status->link_valid && prev_sta->sta.mlo) + continue; + +- rx.link_id = status->link_valid ? link_id : -1; +- rx.sta = prev_sta; +- rx.sdata = prev_sta->sdata; + ieee80211_prepare_and_rx_handle(&rx, skb, false); + + prev_sta = sta; + } + + if (prev_sta) { +- if ((status->link_valid && +- !ieee80211_rx_is_valid_sta_link_id(&prev_sta->sta, +- link_id)) || +- (!status->link_valid && prev_sta->sta.mlo)) ++ rx.sdata = prev_sta->sdata; ++ if (!ieee80211_rx_data_set_sta(&rx, &prev_sta->sta, ++ link_id)) + goto out; + +- rx.link_id = status->link_valid ? link_id : -1; +- rx.sta = prev_sta; +- rx.sdata = prev_sta->sdata; ++ if (!status->link_valid && prev_sta->sta.mlo) ++ goto out; + + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) + return; diff --git a/queue-6.1/wifi-mac80211-fix-mlo-ap_vlan-check.patch b/queue-6.1/wifi-mac80211-fix-mlo-ap_vlan-check.patch new file mode 100644 index 00000000000..5d5c98e83b6 --- /dev/null +++ b/queue-6.1/wifi-mac80211-fix-mlo-ap_vlan-check.patch @@ -0,0 +1,41 @@ +From f216033d770f7ca0eda491fe01a9f02e7af59576 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 14 Dec 2022 14:03:26 +0100 +Subject: wifi: mac80211: fix MLO + AP_VLAN check + +From: Felix Fietkau + +commit f216033d770f7ca0eda491fe01a9f02e7af59576 upstream. + +Instead of preventing adding AP_VLAN to MLO enabled APs, this check was +preventing adding more than one 4-addr AP_VLAN regardless of the MLO status. +Fix this by adding missing extra checks. + +Fixes: ae960ee90bb1 ("wifi: mac80211: prevent VLANs on MLDs") +Signed-off-by: Felix Fietkau +Link: https://lore.kernel.org/r/20221214130326.37756-1-nbd@nbd.name +Cc: stable@vger.kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/iface.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index d49a5906a943..e20c3fe9a0b1 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -364,7 +364,9 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, + + /* No support for VLAN with MLO yet */ + if (iftype == NL80211_IFTYPE_AP_VLAN && +- nsdata->wdev.use_4addr) ++ sdata->wdev.use_4addr && ++ nsdata->vif.type == NL80211_IFTYPE_AP && ++ nsdata->vif.valid_links) + return -EOPNOTSUPP; + + /* +-- +2.39.1 + diff --git a/queue-6.1/wifi-mac80211-reset-multiple-bssid-options-in-stop_ap.patch b/queue-6.1/wifi-mac80211-reset-multiple-bssid-options-in-stop_ap.patch new file mode 100644 index 00000000000..467bbcb7f0f --- /dev/null +++ b/queue-6.1/wifi-mac80211-reset-multiple-bssid-options-in-stop_ap.patch @@ -0,0 +1,48 @@ +From 0eb38842ada035d71bb06fb9116f26f24ee0f998 Mon Sep 17 00:00:00 2001 +From: Aloka Dixit +Date: Wed, 21 Dec 2022 10:56:16 -0800 +Subject: wifi: mac80211: reset multiple BSSID options in stop_ap() + +From: Aloka Dixit + +commit 0eb38842ada035d71bb06fb9116f26f24ee0f998 upstream. + +Reset multiple BSSID options when all AP related configurations are +reset in ieee80211_stop_ap(). + +Stale values result in HWSIM test failures (e.g. p2p_group_cli_invalid), +if run after 'he_ap_ema'. + +Reported-by: Jouni Malinen +Signed-off-by: Aloka Dixit +Link: https://lore.kernel.org/r/20221221185616.11514-1-quic_alokad@quicinc.com +Cc: stable@vger.kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/cfg.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -147,6 +147,7 @@ static int ieee80211_set_ap_mbssid_optio + link_conf->bssid_index = 0; + link_conf->nontransmitted = false; + link_conf->ema_ap = false; ++ link_conf->bssid_indicator = 0; + + if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev) + return -EINVAL; +@@ -1511,6 +1512,12 @@ static int ieee80211_stop_ap(struct wiph + kfree(link_conf->ftmr_params); + link_conf->ftmr_params = NULL; + ++ sdata->vif.mbssid_tx_vif = NULL; ++ link_conf->bssid_index = 0; ++ link_conf->nontransmitted = false; ++ link_conf->ema_ap = false; ++ link_conf->bssid_indicator = 0; ++ + __sta_info_flush(sdata, true); + ieee80211_free_keys(sdata, true); + diff --git a/queue-6.1/wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch b/queue-6.1/wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch new file mode 100644 index 00000000000..d165f3569af --- /dev/null +++ b/queue-6.1/wifi-mac80211-sdata-can-be-null-during-ampdu-start.patch @@ -0,0 +1,117 @@ +From 69403bad97aa0162e3d7911b27e25abe774093df Mon Sep 17 00:00:00 2001 +From: Alexander Wetzel +Date: Fri, 30 Dec 2022 13:18:50 +0100 +Subject: wifi: mac80211: sdata can be NULL during AMPDU start + +From: Alexander Wetzel + +commit 69403bad97aa0162e3d7911b27e25abe774093df upstream. + +ieee80211_tx_ba_session_handle_start() may get NULL for sdata when a +deauthentication is ongoing. + +Here a trace triggering the race with the hostapd test +multi_ap_fronthaul_on_ap: + +(gdb) list *drv_ampdu_action+0x46 +0x8b16 is in drv_ampdu_action (net/mac80211/driver-ops.c:396). +391 int ret = -EOPNOTSUPP; +392 +393 might_sleep(); +394 +395 sdata = get_bss_sdata(sdata); +396 if (!check_sdata_in_driver(sdata)) +397 return -EIO; +398 +399 trace_drv_ampdu_action(local, sdata, params); +400 + +wlan0: moving STA 02:00:00:00:03:00 to state 3 +wlan0: associated +wlan0: deauthenticating from 02:00:00:00:03:00 by local choice (Reason: 3=DEAUTH_LEAVING) +wlan3.sta1: Open BA session requested for 02:00:00:00:00:00 tid 0 +wlan3.sta1: dropped frame to 02:00:00:00:00:00 (unauthorized port) +wlan0: moving STA 02:00:00:00:03:00 to state 2 +wlan0: moving STA 02:00:00:00:03:00 to state 1 +wlan0: Removed STA 02:00:00:00:03:00 +wlan0: Destroyed STA 02:00:00:00:03:00 +BUG: unable to handle page fault for address: fffffffffffffb48 +PGD 11814067 P4D 11814067 PUD 11816067 PMD 0 +Oops: 0000 [#1] PREEMPT SMP PTI +CPU: 2 PID: 133397 Comm: kworker/u16:1 Tainted: G W 6.1.0-rc8-wt+ #59 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-20220807_005459-localhost 04/01/2014 +Workqueue: phy3 ieee80211_ba_session_work [mac80211] +RIP: 0010:drv_ampdu_action+0x46/0x280 [mac80211] +Code: 53 48 89 f3 be 89 01 00 00 e8 d6 43 bf ef e8 21 46 81 f0 83 bb a0 1b 00 00 04 75 0e 48 8b 9b 28 0d 00 00 48 81 eb 10 0e 00 00 <8b> 93 58 09 00 00 f6 c2 20 0f 84 3b 01 00 00 8b 05 dd 1c 0f 00 85 +RSP: 0018:ffffc900025ebd20 EFLAGS: 00010287 +RAX: 0000000000000000 RBX: fffffffffffff1f0 RCX: ffff888102228240 +RDX: 0000000080000000 RSI: ffffffff918c5de0 RDI: ffff888102228b40 +RBP: ffffc900025ebd40 R08: 0000000000000001 R09: 0000000000000001 +R10: 0000000000000001 R11: 0000000000000000 R12: ffff888118c18ec0 +R13: 0000000000000000 R14: ffffc900025ebd60 R15: ffff888018b7efb8 +FS: 0000000000000000(0000) GS:ffff88817a600000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: fffffffffffffb48 CR3: 0000000105228006 CR4: 0000000000170ee0 +Call Trace: + + ieee80211_tx_ba_session_handle_start+0xd0/0x190 [mac80211] + ieee80211_ba_session_work+0xff/0x2e0 [mac80211] + process_one_work+0x29f/0x620 + worker_thread+0x4d/0x3d0 + ? process_one_work+0x620/0x620 + kthread+0xfb/0x120 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x22/0x30 + + +Signed-off-by: Alexander Wetzel +Link: https://lore.kernel.org/r/20221230121850.218810-2-alexander@wetzel-home.de +Cc: stable@vger.kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/agg-tx.c | 6 +++++- + net/mac80211/driver-ops.c | 3 +++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -491,7 +491,7 @@ void ieee80211_tx_ba_session_handle_star + { + struct tid_ampdu_tx *tid_tx; + struct ieee80211_local *local = sta->local; +- struct ieee80211_sub_if_data *sdata = sta->sdata; ++ struct ieee80211_sub_if_data *sdata; + struct ieee80211_ampdu_params params = { + .sta = &sta->sta, + .action = IEEE80211_AMPDU_TX_START, +@@ -521,6 +521,7 @@ void ieee80211_tx_ba_session_handle_star + */ + synchronize_net(); + ++ sdata = sta->sdata; + params.ssn = sta->tid_seq[tid] >> 4; + ret = drv_ampdu_action(local, sdata, ¶ms); + tid_tx->ssn = params.ssn; +@@ -534,6 +535,9 @@ void ieee80211_tx_ba_session_handle_star + */ + set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state); + } else if (ret) { ++ if (!sdata) ++ return; ++ + ht_dbg(sdata, + "BA request denied - HW unavailable for %pM tid %d\n", + sta->sta.addr, tid); +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -391,6 +391,9 @@ int drv_ampdu_action(struct ieee80211_lo + + might_sleep(); + ++ if (!sdata) ++ return -EIO; ++ + sdata = get_bss_sdata(sdata); + if (!check_sdata_in_driver(sdata)) + return -EIO; diff --git a/queue-6.1/zonefs-detect-append-writes-at-invalid-locations.patch b/queue-6.1/zonefs-detect-append-writes-at-invalid-locations.patch new file mode 100644 index 00000000000..99921e9d672 --- /dev/null +++ b/queue-6.1/zonefs-detect-append-writes-at-invalid-locations.patch @@ -0,0 +1,72 @@ +From a608da3bd730d718f2d3ebec1c26f9865f8f17ce Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Fri, 6 Jan 2023 17:43:06 +0900 +Subject: zonefs: Detect append writes at invalid locations + +From: Damien Le Moal + +commit a608da3bd730d718f2d3ebec1c26f9865f8f17ce upstream. + +Using REQ_OP_ZONE_APPEND operations for synchronous writes to sequential +files succeeds regardless of the zone write pointer position, as long as +the target zone is not full. This means that if an external (buggy) +application writes to the zone of a sequential file underneath the file +system, subsequent file write() operation will succeed but the file size +will not be correct and the file will contain invalid data written by +another application. + +Modify zonefs_file_dio_append() to check the written sector of an append +write (returned in bio->bi_iter.bi_sector) and return -EIO if there is a +mismatch with the file zone wp offset field. This change triggers a call +to zonefs_io_error() and a zone check. Modify zonefs_io_error_cb() to +not expose the unexpected data after the current inode size when the +errors=remount-ro mode is used. Other error modes are correctly handled +already. + +Fixes: 02ef12a663c7 ("zonefs: use REQ_OP_ZONE_APPEND for sync DIO") +Cc: stable@vger.kernel.org +Signed-off-by: Damien Le Moal +Reviewed-by: Johannes Thumshirn +Signed-off-by: Greg Kroah-Hartman +--- + fs/zonefs/super.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/fs/zonefs/super.c ++++ b/fs/zonefs/super.c +@@ -442,6 +442,10 @@ static int zonefs_io_error_cb(struct blk + data_size = zonefs_check_zone_condition(inode, zone, + false, false); + } ++ } else if (sbi->s_mount_opts & ZONEFS_MNTOPT_ERRORS_RO && ++ data_size > isize) { ++ /* Do not expose garbage data */ ++ data_size = isize; + } + + /* +@@ -805,6 +809,24 @@ static ssize_t zonefs_file_dio_append(st + + ret = submit_bio_wait(bio); + ++ /* ++ * If the file zone was written underneath the file system, the zone ++ * write pointer may not be where we expect it to be, but the zone ++ * append write can still succeed. So check manually that we wrote where ++ * we intended to, that is, at zi->i_wpoffset. ++ */ ++ if (!ret) { ++ sector_t wpsector = ++ zi->i_zsector + (zi->i_wpoffset >> SECTOR_SHIFT); ++ ++ if (bio->bi_iter.bi_sector != wpsector) { ++ zonefs_warn(inode->i_sb, ++ "Corrupted write pointer %llu for zone at %llu\n", ++ wpsector, zi->i_zsector); ++ ret = -EIO; ++ } ++ } ++ + zonefs_file_write_dio_end_io(iocb, size, ret, 0); + trace_zonefs_file_dio_append(inode, size, ret); +