From 3fb7914e0126a258cee29030433eb9c6546f26fb Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 6 Jan 2024 20:58:55 -0500 Subject: [PATCH] Fixes for 4.19 Signed-off-by: Sasha Levin --- ...x-array-index-out-of-bounds-read-in-.patch | 64 ++ ...x-add-check-for-usbnet_get_endpoints.patch | 38 ++ ...is-applied-code-from-bnxt_cfg_ntp_fi.patch | 47 ++ ...input-checks-to-prevent-config-with-.patch | 53 ++ ...e-after-free-in-i40e_aqc_add_filters.patch | 120 ++++ ...tore-vf-msi-x-state-during-pci-reset.patch | 103 ++++ ...e-check-the-mapcount-of-the-precise-.patch | 54 ++ ...-fcs-generation-for-fragmented-skbuf.patch | 46 ++ ...potential-memleak-in-ql_alloc_buffer.patch | 44 ++ ...qla3xxx-switch-from-pci_-to-dma_-api.patch | 564 ++++++++++++++++++ ...-restore-msg_namelen-in-sock_sendmsg.patch | 55 ++ ...t-fix-possible-memory-leak-in-em_tex.patch | 40 ++ ...ld-a-ref-to-llcp_local-dev-when-hold.patch | 128 ++++ queue-4.19/series | 13 + 14 files changed, 1369 insertions(+) create mode 100644 queue-4.19/arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch create mode 100644 queue-4.19/asix-add-check-for-usbnet_get_endpoints.patch create mode 100644 queue-4.19/bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch create mode 100644 queue-4.19/i40e-fix-filter-input-checks-to-prevent-config-with-.patch create mode 100644 queue-4.19/i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch create mode 100644 queue-4.19/i40e-restore-vf-msi-x-state-during-pci-reset.patch create mode 100644 queue-4.19/mm-memory-failure-check-the-mapcount-of-the-precise-.patch create mode 100644 queue-4.19/net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch create mode 100644 queue-4.19/net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch create mode 100644 queue-4.19/net-qla3xxx-switch-from-pci_-to-dma_-api.patch create mode 100644 queue-4.19/net-save-and-restore-msg_namelen-in-sock_sendmsg.patch create mode 100644 queue-4.19/net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch create mode 100644 queue-4.19/nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch diff --git a/queue-4.19/arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch b/queue-4.19/arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch new file mode 100644 index 00000000000..82803d78e77 --- /dev/null +++ b/queue-4.19/arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch @@ -0,0 +1,64 @@ +From c94e29a97886698bdfeca48e454ae514d1bc1474 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Dec 2023 20:39:02 +0100 +Subject: ARM: sun9i: smp: Fix array-index-out-of-bounds read in + sunxi_mc_smp_init + +From: Stefan Wahren + +[ Upstream commit 72ad3b772b6d393701df58ba1359b0bb346a19ed ] + +Running a multi-arch kernel (multi_v7_defconfig) on a Raspberry Pi 3B+ +with enabled CONFIG_UBSAN triggers the following warning: + + UBSAN: array-index-out-of-bounds in arch/arm/mach-sunxi/mc_smp.c:810:29 + index 2 is out of range for type 'sunxi_mc_smp_data [2]' + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.7.0-rc6-00248-g5254c0cbc92d + Hardware name: BCM2835 + unwind_backtrace from show_stack+0x10/0x14 + show_stack from dump_stack_lvl+0x40/0x4c + dump_stack_lvl from ubsan_epilogue+0x8/0x34 + ubsan_epilogue from __ubsan_handle_out_of_bounds+0x78/0x80 + __ubsan_handle_out_of_bounds from sunxi_mc_smp_init+0xe4/0x4cc + sunxi_mc_smp_init from do_one_initcall+0xa0/0x2fc + do_one_initcall from kernel_init_freeable+0xf4/0x2f4 + kernel_init_freeable from kernel_init+0x18/0x158 + kernel_init from ret_from_fork+0x14/0x28 + +Since the enabled method couldn't match with any entry from +sunxi_mc_smp_data, the value of the index shouldn't be used right after +the loop. So move it after the check of ret in order to have a valid +index. + +Fixes: 1631090e34f5 ("ARM: sun9i: smp: Add is_a83t field") +Signed-off-by: Stefan Wahren +Link: https://lore.kernel.org/r/20231228193903.9078-1-wahrenst@gmx.net +Reviewed-by: Chen-Yu Tsai +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/arm/mach-sunxi/mc_smp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c +index ff173e67eed21..527bb82072d9a 100644 +--- a/arch/arm/mach-sunxi/mc_smp.c ++++ b/arch/arm/mach-sunxi/mc_smp.c +@@ -805,12 +805,12 @@ static int __init sunxi_mc_smp_init(void) + break; + } + +- is_a83t = sunxi_mc_smp_data[i].is_a83t; +- + of_node_put(node); + if (ret) + return -ENODEV; + ++ is_a83t = sunxi_mc_smp_data[i].is_a83t; ++ + if (!sunxi_mc_smp_cpu_table_init()) + return -EINVAL; + +-- +2.43.0 + diff --git a/queue-4.19/asix-add-check-for-usbnet_get_endpoints.patch b/queue-4.19/asix-add-check-for-usbnet_get_endpoints.patch new file mode 100644 index 00000000000..eb549567e46 --- /dev/null +++ b/queue-4.19/asix-add-check-for-usbnet_get_endpoints.patch @@ -0,0 +1,38 @@ +From 0982ea3685d502f36770b38c57ed93a49dc2f26c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Jan 2024 03:35:34 +0000 +Subject: asix: Add check for usbnet_get_endpoints + +From: Chen Ni + +[ Upstream commit eaac6a2d26b65511e164772bec6918fcbc61938e ] + +Add check for usbnet_get_endpoints() and return the error if it fails +in order to transfer the error. + +Fixes: 16626b0cc3d5 ("asix: Add a new driver for the AX88172A") +Signed-off-by: Chen Ni +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/usb/ax88172a.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c +index 909755ef71ac3..5881620e44365 100644 +--- a/drivers/net/usb/ax88172a.c ++++ b/drivers/net/usb/ax88172a.c +@@ -198,7 +198,9 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) + u8 buf[ETH_ALEN]; + struct ax88172a_private *priv; + +- usbnet_get_endpoints(dev, intf); ++ ret = usbnet_get_endpoints(dev, intf); ++ if (ret) ++ return ret; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) +-- +2.43.0 + diff --git a/queue-4.19/bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch b/queue-4.19/bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch new file mode 100644 index 00000000000..08e5e524c78 --- /dev/null +++ b/queue-4.19/bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch @@ -0,0 +1,47 @@ +From d30804683bff9328051c32dddcf73c805bb3e276 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Jan 2024 16:59:24 -0800 +Subject: bnxt_en: Remove mis-applied code from bnxt_cfg_ntp_filters() + +From: Michael Chan + +[ Upstream commit e009b2efb7a8850498796b360043ac25c8d3d28f ] + +The 2 lines to check for the BNXT_HWRM_PF_UNLOAD_SP_EVENT bit was +mis-applied to bnxt_cfg_ntp_filters() and should have been applied to +bnxt_sp_task(). + +Fixes: 19241368443f ("bnxt_en: Send PF driver unload notification to all VFs.") +Reviewed-by: Andy Gospodarek +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index d79281c6d915d..ca817b251ef58 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -7847,6 +7847,8 @@ static void bnxt_sp_task(struct work_struct *work) + bnxt_cfg_ntp_filters(bp); + if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_exec_fwd_req(bp); ++ if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) ++ netdev_info(bp->dev, "Receive PF driver unload event!\n"); + if (test_and_clear_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event)) { + bnxt_hwrm_tunnel_dst_port_alloc( + bp, bp->vxlan_port, +@@ -8407,8 +8409,6 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp) + } + } + } +- if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) +- netdev_info(bp->dev, "Receive PF driver unload event!"); + } + + #else +-- +2.43.0 + diff --git a/queue-4.19/i40e-fix-filter-input-checks-to-prevent-config-with-.patch b/queue-4.19/i40e-fix-filter-input-checks-to-prevent-config-with-.patch new file mode 100644 index 00000000000..be6402a5142 --- /dev/null +++ b/queue-4.19/i40e-fix-filter-input-checks-to-prevent-config-with-.patch @@ -0,0 +1,53 @@ +From e89d3424a03b862d9601b2a227f09160dc8f408d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 11:23:11 +0100 +Subject: i40e: Fix filter input checks to prevent config with invalid values + +From: Sudheer Mogilappagari + +[ Upstream commit 3e48041d9820c17e0a51599d12e66c6e12a8d08d ] + +Prevent VF from configuring filters with unsupported actions or use +REDIRECT action with invalid tc number. Current checks could cause +out of bounds access on PF side. + +Fixes: e284fc280473 ("i40e: Add and delete cloud filter") +Reviewed-by: Andrii Staikov +Signed-off-by: Sudheer Mogilappagari +Signed-off-by: Aleksandr Loktionov +Reviewed-by: Simon Horman +Tested-by: Bharathi Sreenivas +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 1527c67b487b2..32b19c4c581b6 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -3143,16 +3143,16 @@ static int i40e_validate_cloud_filter(struct i40e_vf *vf, + bool found = false; + int bkt; + +- if (!tc_filter->action) { ++ if (tc_filter->action != VIRTCHNL_ACTION_TC_REDIRECT) { + dev_info(&pf->pdev->dev, +- "VF %d: Currently ADq doesn't support Drop Action\n", +- vf->vf_id); ++ "VF %d: ADQ doesn't support this action (%d)\n", ++ vf->vf_id, tc_filter->action); + goto err; + } + + /* action_meta is TC number here to which the filter is applied */ + if (!tc_filter->action_meta || +- tc_filter->action_meta > I40E_MAX_VF_VSI) { ++ tc_filter->action_meta > vf->num_tc) { + dev_info(&pf->pdev->dev, "VF %d: Invalid TC number %u\n", + vf->vf_id, tc_filter->action_meta); + goto err; +-- +2.43.0 + diff --git a/queue-4.19/i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch b/queue-4.19/i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch new file mode 100644 index 00000000000..d64c9d78410 --- /dev/null +++ b/queue-4.19/i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch @@ -0,0 +1,120 @@ +From 975b40330bdfa6b9ededbd86c62d170e2ef9a452 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Dec 2023 15:08:50 +0800 +Subject: i40e: fix use-after-free in i40e_aqc_add_filters() + +From: Ke Xiao + +[ Upstream commit 6a15584e99db8918b60e507539c7446375dcf366 ] + +Commit 3116f59c12bd ("i40e: fix use-after-free in +i40e_sync_filters_subtask()") avoided use-after-free issues, +by increasing refcount during update the VSI filter list to +the HW. However, it missed the unicast situation. + +When deleting an unicast FDB entry, the i40e driver will release +the mac_filter, and i40e_service_task will concurrently request +firmware to add the mac_filter, which will lead to the following +use-after-free issue. + +Fix again for both netdev->uc and netdev->mc. + +BUG: KASAN: use-after-free in i40e_aqc_add_filters+0x55c/0x5b0 [i40e] +Read of size 2 at addr ffff888eb3452d60 by task kworker/8:7/6379 + +CPU: 8 PID: 6379 Comm: kworker/8:7 Kdump: loaded Tainted: G +Workqueue: i40e i40e_service_task [i40e] +Call Trace: + dump_stack+0x71/0xab + print_address_description+0x6b/0x290 + kasan_report+0x14a/0x2b0 + i40e_aqc_add_filters+0x55c/0x5b0 [i40e] + i40e_sync_vsi_filters+0x1676/0x39c0 [i40e] + i40e_service_task+0x1397/0x2bb0 [i40e] + process_one_work+0x56a/0x11f0 + worker_thread+0x8f/0xf40 + kthread+0x2a0/0x390 + ret_from_fork+0x1f/0x40 + +Allocated by task 21948: + kasan_kmalloc+0xa6/0xd0 + kmem_cache_alloc_trace+0xdb/0x1c0 + i40e_add_filter+0x11e/0x520 [i40e] + i40e_addr_sync+0x37/0x60 [i40e] + __hw_addr_sync_dev+0x1f5/0x2f0 + i40e_set_rx_mode+0x61/0x1e0 [i40e] + dev_uc_add_excl+0x137/0x190 + i40e_ndo_fdb_add+0x161/0x260 [i40e] + rtnl_fdb_add+0x567/0x950 + rtnetlink_rcv_msg+0x5db/0x880 + netlink_rcv_skb+0x254/0x380 + netlink_unicast+0x454/0x610 + netlink_sendmsg+0x747/0xb00 + sock_sendmsg+0xe2/0x120 + __sys_sendto+0x1ae/0x290 + __x64_sys_sendto+0xdd/0x1b0 + do_syscall_64+0xa0/0x370 + entry_SYSCALL_64_after_hwframe+0x65/0xca + +Freed by task 21948: + __kasan_slab_free+0x137/0x190 + kfree+0x8b/0x1b0 + __i40e_del_filter+0x116/0x1e0 [i40e] + i40e_del_mac_filter+0x16c/0x300 [i40e] + i40e_addr_unsync+0x134/0x1b0 [i40e] + __hw_addr_sync_dev+0xff/0x2f0 + i40e_set_rx_mode+0x61/0x1e0 [i40e] + dev_uc_del+0x77/0x90 + rtnl_fdb_del+0x6a5/0x860 + rtnetlink_rcv_msg+0x5db/0x880 + netlink_rcv_skb+0x254/0x380 + netlink_unicast+0x454/0x610 + netlink_sendmsg+0x747/0xb00 + sock_sendmsg+0xe2/0x120 + __sys_sendto+0x1ae/0x290 + __x64_sys_sendto+0xdd/0x1b0 + do_syscall_64+0xa0/0x370 + entry_SYSCALL_64_after_hwframe+0x65/0xca + +Fixes: 3116f59c12bd ("i40e: fix use-after-free in i40e_sync_filters_subtask()") +Fixes: 41c445ff0f48 ("i40e: main driver core") +Signed-off-by: Ke Xiao +Signed-off-by: Ding Hui +Cc: Di Zhu +Reviewed-by: Jan Sokolowski +Reviewed-by: Simon Horman +Reviewed-by: Jacob Keller +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 75a553f4e26f6..552f5025d265b 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -99,12 +99,18 @@ static struct workqueue_struct *i40e_wq; + static void netdev_hw_addr_refcnt(struct i40e_mac_filter *f, + struct net_device *netdev, int delta) + { ++ struct netdev_hw_addr_list *ha_list; + struct netdev_hw_addr *ha; + + if (!f || !netdev) + return; + +- netdev_for_each_mc_addr(ha, netdev) { ++ if (is_unicast_ether_addr(f->macaddr) || is_link_local_ether_addr(f->macaddr)) ++ ha_list = &netdev->uc; ++ else ++ ha_list = &netdev->mc; ++ ++ netdev_hw_addr_list_for_each(ha, ha_list) { + if (ether_addr_equal(ha->addr, f->macaddr)) { + ha->refcount += delta; + if (ha->refcount <= 0) +-- +2.43.0 + diff --git a/queue-4.19/i40e-restore-vf-msi-x-state-during-pci-reset.patch b/queue-4.19/i40e-restore-vf-msi-x-state-during-pci-reset.patch new file mode 100644 index 00000000000..7591d44412c --- /dev/null +++ b/queue-4.19/i40e-restore-vf-msi-x-state-during-pci-reset.patch @@ -0,0 +1,103 @@ +From dabe509ff2926cc40856f83e8ead5cc958af4a71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Dec 2023 14:27:35 +0100 +Subject: i40e: Restore VF MSI-X state during PCI reset + +From: Andrii Staikov + +[ Upstream commit 371e576ff3e8580d91d49026e5d5faebf5565558 ] + +During a PCI FLR the MSI-X Enable flag in the VF PCI MSI-X capability +register will be cleared. This can lead to issues when a VF is +assigned to a VM because in these cases the VF driver receives no +indication of the PF PCI error/reset and additionally it is incapable +of restoring the cleared flag in the hypervisor configuration space +without fully reinitializing the driver interrupt functionality. + +Since the VF driver is unable to easily resolve this condition on its own, +restore the VF MSI-X flag during the PF PCI reset handling. + +Fixes: 19b7960b2da1 ("i40e: implement split PCI error reset handler") +Co-developed-by: Karen Ostrowska +Signed-off-by: Karen Ostrowska +Co-developed-by: Mateusz Palczewski +Signed-off-by: Mateusz Palczewski +Reviewed-by: Wojciech Drewek +Reviewed-by: Przemek Kitszel +Signed-off-by: Andrii Staikov +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ + .../ethernet/intel/i40e/i40e_virtchnl_pf.c | 26 +++++++++++++++++++ + .../ethernet/intel/i40e/i40e_virtchnl_pf.h | 3 +++ + 3 files changed, 32 insertions(+) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 552f5025d265b..97cf144a4ff99 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -14476,6 +14476,9 @@ static void i40e_pci_error_reset_done(struct pci_dev *pdev) + struct i40e_pf *pf = pci_get_drvdata(pdev); + + i40e_reset_and_rebuild(pf, false, false); ++#ifdef CONFIG_PCI_IOV ++ i40e_restore_all_vfs_msi_state(pdev); ++#endif /* CONFIG_PCI_IOV */ + } + + /** +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 32b19c4c581b6..412f8002f918b 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -99,6 +99,32 @@ void i40e_vc_notify_reset(struct i40e_pf *pf) + (u8 *)&pfe, sizeof(struct virtchnl_pf_event)); + } + ++#ifdef CONFIG_PCI_IOV ++void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev) ++{ ++ u16 vf_id; ++ u16 pos; ++ ++ /* Continue only if this is a PF */ ++ if (!pdev->is_physfn) ++ return; ++ ++ if (!pci_num_vf(pdev)) ++ return; ++ ++ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); ++ if (pos) { ++ struct pci_dev *vf_dev = NULL; ++ ++ pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id); ++ while ((vf_dev = pci_get_device(pdev->vendor, vf_id, vf_dev))) { ++ if (vf_dev->is_virtfn && vf_dev->physfn == pdev) ++ pci_restore_msi_state(vf_dev); ++ } ++ } ++} ++#endif /* CONFIG_PCI_IOV */ ++ + /** + * i40e_vc_notify_vf_reset + * @vf: pointer to the VF structure +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +index 1e001b2bd761b..c9e0a591a344d 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +@@ -137,5 +137,8 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable); + + void i40e_vc_notify_link_state(struct i40e_pf *pf); + void i40e_vc_notify_reset(struct i40e_pf *pf); ++#ifdef CONFIG_PCI_IOV ++void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev); ++#endif /* CONFIG_PCI_IOV */ + + #endif /* _I40E_VIRTCHNL_PF_H_ */ +-- +2.43.0 + diff --git a/queue-4.19/mm-memory-failure-check-the-mapcount-of-the-precise-.patch b/queue-4.19/mm-memory-failure-check-the-mapcount-of-the-precise-.patch new file mode 100644 index 00000000000..11e8b44bfef --- /dev/null +++ b/queue-4.19/mm-memory-failure-check-the-mapcount-of-the-precise-.patch @@ -0,0 +1,54 @@ +From b6a4cc0b689cdaefddaea0c85e1600c9e6dbbe07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Dec 2023 13:58:36 +0000 +Subject: mm/memory-failure: check the mapcount of the precise page + +From: Matthew Wilcox (Oracle) + +[ Upstream commit c79c5a0a00a9457718056b588f312baadf44e471 ] + +A process may map only some of the pages in a folio, and might be missed +if it maps the poisoned page but not the head page. Or it might be +unnecessarily hit if it maps the head page, but not the poisoned page. + +Link: https://lkml.kernel.org/r/20231218135837.3310403-3-willy@infradead.org +Fixes: 7af446a841a2 ("HWPOISON, hugetlb: enable error handling path for hugepage") +Signed-off-by: Matthew Wilcox (Oracle) +Cc: Dan Williams +Cc: Naoya Horiguchi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + mm/memory-failure.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/mm/memory-failure.c b/mm/memory-failure.c +index 3da3c63dccd1a..c971d5e11f932 100644 +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -989,7 +989,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, + * This check implies we don't kill processes if their pages + * are in the swap cache early. Those are always late kills. + */ +- if (!page_mapped(hpage)) ++ if (!page_mapped(p)) + return true; + + if (PageKsm(p)) { +@@ -1033,10 +1033,10 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, + if (kill) + collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED); + +- unmap_success = try_to_unmap(hpage, ttu); ++ unmap_success = try_to_unmap(p, ttu); + if (!unmap_success) + pr_err("Memory failure: %#lx: failed to unmap page (mapcount=%d)\n", +- pfn, page_mapcount(hpage)); ++ pfn, page_mapcount(p)); + + /* + * try_to_unmap() might put mlocked page in lru cache, so call +-- +2.43.0 + diff --git a/queue-4.19/net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch b/queue-4.19/net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch new file mode 100644 index 00000000000..81f1324094b --- /dev/null +++ b/queue-4.19/net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch @@ -0,0 +1,46 @@ +From ee480045db552a36daca265a2248fc956d0dd58a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Dec 2023 14:56:38 +0100 +Subject: net: bcmgenet: Fix FCS generation for fragmented skbuffs + +From: Adrian Cinal + +[ Upstream commit e584f2ff1e6cc9b1d99e8a6b0f3415940d1b3eb3 ] + +The flag DMA_TX_APPEND_CRC was only written to the first DMA descriptor +in the TX path, where each descriptor corresponds to a single skbuff +fragment (or the skbuff head). This led to packets with no FCS appearing +on the wire if the kernel allocated the packet in fragments, which would +always happen when using PACKET_MMAP/TPACKET (cf. tpacket_fill_skb() in +net/af_packet.c). + +Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") +Signed-off-by: Adrian Cinal +Acked-by: Doug Berger +Acked-by: Florian Fainelli +Link: https://lore.kernel.org/r/20231228135638.1339245-1-adriancinal1@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index d518577313145..8bbc5dcf8cb43 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -1650,8 +1650,10 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) + /* Note: if we ever change from DMA_TX_APPEND_CRC below we + * will need to restore software padding of "runt" packets + */ ++ len_stat |= DMA_TX_APPEND_CRC; ++ + if (!i) { +- len_stat |= DMA_TX_APPEND_CRC | DMA_SOP; ++ len_stat |= DMA_SOP; + if (skb->ip_summed == CHECKSUM_PARTIAL) + len_stat |= DMA_TX_DO_CSUM; + } +-- +2.43.0 + diff --git a/queue-4.19/net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch b/queue-4.19/net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch new file mode 100644 index 00000000000..c8ddbab5c4d --- /dev/null +++ b/queue-4.19/net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch @@ -0,0 +1,44 @@ +From 1ebdd06471bf2cf168f836f254cc8eeac3f6b4ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Dec 2023 15:02:27 +0800 +Subject: net/qla3xxx: fix potential memleak in ql_alloc_buffer_queues + +From: Dinghao Liu + +[ Upstream commit 89f45c30172c80e55c887f32f1af8e184124577b ] + +When dma_alloc_coherent() fails, we should free qdev->lrg_buf +to prevent potential memleak. + +Fixes: 1357bfcf7106 ("qla3xxx: Dynamically size the rx buffer queue based on the MTU.") +Signed-off-by: Dinghao Liu +Link: https://lore.kernel.org/r/20231227070227.10527-1-dinghao.liu@zju.edu.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qla3xxx.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c +index 6350872fd5a52..99949140c2e70 100644 +--- a/drivers/net/ethernet/qlogic/qla3xxx.c ++++ b/drivers/net/ethernet/qlogic/qla3xxx.c +@@ -2591,6 +2591,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) + + if (qdev->lrg_buf_q_alloc_virt_addr == NULL) { + netdev_err(qdev->ndev, "lBufQ failed\n"); ++ kfree(qdev->lrg_buf); + return -ENOMEM; + } + qdev->lrg_buf_q_virt_addr = qdev->lrg_buf_q_alloc_virt_addr; +@@ -2615,6 +2616,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) + qdev->lrg_buf_q_alloc_size, + qdev->lrg_buf_q_alloc_virt_addr, + qdev->lrg_buf_q_alloc_phy_addr); ++ kfree(qdev->lrg_buf); + return -ENOMEM; + } + +-- +2.43.0 + diff --git a/queue-4.19/net-qla3xxx-switch-from-pci_-to-dma_-api.patch b/queue-4.19/net-qla3xxx-switch-from-pci_-to-dma_-api.patch new file mode 100644 index 00000000000..af6386f4eb7 --- /dev/null +++ b/queue-4.19/net-qla3xxx-switch-from-pci_-to-dma_-api.patch @@ -0,0 +1,564 @@ +From 0adcc5b1aa071d044af145fd921a11fde15ad778 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Jan 2021 09:15:42 +0100 +Subject: net/qla3xxx: switch from 'pci_' to 'dma_' API + +From: Christophe JAILLET + +[ Upstream commit 41fb4c1ba7478fe34c7e094e124e4ee4513b9763 ] + +The wrappers in include/linux/pci-dma-compat.h should go away. + +The patch has been generated with the coccinelle script below and has been +hand modified to replace GFP_ with a correct flag. +It has been compile tested. + +When memory is allocated in 'ql_alloc_net_req_rsp_queues()' GFP_KERNEL can +be used because it is only called from 'ql_alloc_mem_resources()' which +already calls 'ql_alloc_buffer_queues()' which uses GFP_KERNEL. (see below) + +When memory is allocated in 'ql_alloc_buffer_queues()' GFP_KERNEL can be +used because this flag is already used just a few line above. + +When memory is allocated in 'ql_alloc_small_buffers()' GFP_KERNEL can +be used because it is only called from 'ql_alloc_mem_resources()' which +already calls 'ql_alloc_buffer_queues()' which uses GFP_KERNEL. (see above) + +When memory is allocated in 'ql_alloc_mem_resources()' GFP_KERNEL can be +used because this function already calls 'ql_alloc_buffer_queues()' which +uses GFP_KERNEL. (see above) + +While at it, use 'dma_set_mask_and_coherent()' instead of 'dma_set_mask()/ +dma_set_coherent_mask()' in order to slightly simplify code. + +@@ +@@ +- PCI_DMA_BIDIRECTIONAL ++ DMA_BIDIRECTIONAL + +@@ +@@ +- PCI_DMA_TODEVICE ++ DMA_TO_DEVICE + +@@ +@@ +- PCI_DMA_FROMDEVICE ++ DMA_FROM_DEVICE + +@@ +@@ +- PCI_DMA_NONE ++ DMA_NONE + +@@ +expression e1, e2, e3; +@@ +- pci_alloc_consistent(e1, e2, e3) ++ dma_alloc_coherent(&e1->dev, e2, e3, GFP_) + +@@ +expression e1, e2, e3; +@@ +- pci_zalloc_consistent(e1, e2, e3) ++ dma_alloc_coherent(&e1->dev, e2, e3, GFP_) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_free_consistent(e1, e2, e3, e4) ++ dma_free_coherent(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_map_single(e1, e2, e3, e4) ++ dma_map_single(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_single(e1, e2, e3, e4) ++ dma_unmap_single(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4, e5; +@@ +- pci_map_page(e1, e2, e3, e4, e5) ++ dma_map_page(&e1->dev, e2, e3, e4, e5) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_page(e1, e2, e3, e4) ++ dma_unmap_page(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_map_sg(e1, e2, e3, e4) ++ dma_map_sg(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_sg(e1, e2, e3, e4) ++ dma_unmap_sg(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_single_for_cpu(e1, e2, e3, e4) ++ dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_single_for_device(e1, e2, e3, e4) ++ dma_sync_single_for_device(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) ++ dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_sg_for_device(e1, e2, e3, e4) ++ dma_sync_sg_for_device(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2; +@@ +- pci_dma_mapping_error(e1, e2) ++ dma_mapping_error(&e1->dev, e2) + +@@ +expression e1, e2; +@@ +- pci_set_dma_mask(e1, e2) ++ dma_set_mask(&e1->dev, e2) + +@@ +expression e1, e2; +@@ +- pci_set_consistent_dma_mask(e1, e2) ++ dma_set_coherent_mask(&e1->dev, e2) + +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/20210117081542.560021-1-christophe.jaillet@wanadoo.fr +Signed-off-by: Jakub Kicinski +Stable-dep-of: 89f45c30172c ("net/qla3xxx: fix potential memleak in ql_alloc_buffer_queues") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qla3xxx.c | 196 ++++++++++++-------------- + 1 file changed, 87 insertions(+), 109 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c +index d545593354c63..6350872fd5a52 100644 +--- a/drivers/net/ethernet/qlogic/qla3xxx.c ++++ b/drivers/net/ethernet/qlogic/qla3xxx.c +@@ -316,12 +316,11 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, + * buffer + */ + skb_reserve(lrg_buf_cb->skb, QL_HEADER_SPACE); +- map = pci_map_single(qdev->pdev, ++ map = dma_map_single(&qdev->pdev->dev, + lrg_buf_cb->skb->data, +- qdev->lrg_buffer_len - +- QL_HEADER_SPACE, +- PCI_DMA_FROMDEVICE); +- err = pci_dma_mapping_error(qdev->pdev, map); ++ qdev->lrg_buffer_len - QL_HEADER_SPACE, ++ DMA_FROM_DEVICE); ++ err = dma_mapping_error(&qdev->pdev->dev, map); + if (err) { + netdev_err(qdev->ndev, + "PCI mapping failed with error: %d\n", +@@ -1803,13 +1802,12 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) + * first buffer + */ + skb_reserve(lrg_buf_cb->skb, QL_HEADER_SPACE); +- map = pci_map_single(qdev->pdev, ++ map = dma_map_single(&qdev->pdev->dev, + lrg_buf_cb->skb->data, +- qdev->lrg_buffer_len - +- QL_HEADER_SPACE, +- PCI_DMA_FROMDEVICE); ++ qdev->lrg_buffer_len - QL_HEADER_SPACE, ++ DMA_FROM_DEVICE); + +- err = pci_dma_mapping_error(qdev->pdev, map); ++ err = dma_mapping_error(&qdev->pdev->dev, map); + if (err) { + netdev_err(qdev->ndev, + "PCI mapping failed with error: %d\n", +@@ -1945,18 +1943,16 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, + goto invalid_seg_count; + } + +- pci_unmap_single(qdev->pdev, ++ dma_unmap_single(&qdev->pdev->dev, + dma_unmap_addr(&tx_cb->map[0], mapaddr), +- dma_unmap_len(&tx_cb->map[0], maplen), +- PCI_DMA_TODEVICE); ++ dma_unmap_len(&tx_cb->map[0], maplen), DMA_TO_DEVICE); + tx_cb->seg_count--; + if (tx_cb->seg_count) { + for (i = 1; i < tx_cb->seg_count; i++) { +- pci_unmap_page(qdev->pdev, +- dma_unmap_addr(&tx_cb->map[i], +- mapaddr), ++ dma_unmap_page(&qdev->pdev->dev, ++ dma_unmap_addr(&tx_cb->map[i], mapaddr), + dma_unmap_len(&tx_cb->map[i], maplen), +- PCI_DMA_TODEVICE); ++ DMA_TO_DEVICE); + } + } + qdev->ndev->stats.tx_packets++; +@@ -2023,10 +2019,9 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, + qdev->ndev->stats.rx_bytes += length; + + skb_put(skb, length); +- pci_unmap_single(qdev->pdev, ++ dma_unmap_single(&qdev->pdev->dev, + dma_unmap_addr(lrg_buf_cb2, mapaddr), +- dma_unmap_len(lrg_buf_cb2, maplen), +- PCI_DMA_FROMDEVICE); ++ dma_unmap_len(lrg_buf_cb2, maplen), DMA_FROM_DEVICE); + prefetch(skb->data); + skb_checksum_none_assert(skb); + skb->protocol = eth_type_trans(skb, qdev->ndev); +@@ -2069,10 +2064,9 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, + skb2 = lrg_buf_cb2->skb; + + skb_put(skb2, length); /* Just the second buffer length here. */ +- pci_unmap_single(qdev->pdev, ++ dma_unmap_single(&qdev->pdev->dev, + dma_unmap_addr(lrg_buf_cb2, mapaddr), +- dma_unmap_len(lrg_buf_cb2, maplen), +- PCI_DMA_FROMDEVICE); ++ dma_unmap_len(lrg_buf_cb2, maplen), DMA_FROM_DEVICE); + prefetch(skb2->data); + + skb_checksum_none_assert(skb2); +@@ -2321,9 +2315,9 @@ static int ql_send_map(struct ql3_adapter *qdev, + /* + * Map the skb buffer first. + */ +- map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); ++ map = dma_map_single(&qdev->pdev->dev, skb->data, len, DMA_TO_DEVICE); + +- err = pci_dma_mapping_error(qdev->pdev, map); ++ err = dma_mapping_error(&qdev->pdev->dev, map); + if (err) { + netdev_err(qdev->ndev, "PCI mapping failed with error: %d\n", + err); +@@ -2359,11 +2353,11 @@ static int ql_send_map(struct ql3_adapter *qdev, + (seg == 7 && seg_cnt > 8) || + (seg == 12 && seg_cnt > 13) || + (seg == 17 && seg_cnt > 18)) { +- map = pci_map_single(qdev->pdev, oal, ++ map = dma_map_single(&qdev->pdev->dev, oal, + sizeof(struct oal), +- PCI_DMA_TODEVICE); ++ DMA_TO_DEVICE); + +- err = pci_dma_mapping_error(qdev->pdev, map); ++ err = dma_mapping_error(&qdev->pdev->dev, map); + if (err) { + netdev_err(qdev->ndev, + "PCI mapping outbound address list with error: %d\n", +@@ -2425,24 +2419,24 @@ static int ql_send_map(struct ql3_adapter *qdev, + (seg == 7 && seg_cnt > 8) || + (seg == 12 && seg_cnt > 13) || + (seg == 17 && seg_cnt > 18)) { +- pci_unmap_single(qdev->pdev, +- dma_unmap_addr(&tx_cb->map[seg], mapaddr), +- dma_unmap_len(&tx_cb->map[seg], maplen), +- PCI_DMA_TODEVICE); ++ dma_unmap_single(&qdev->pdev->dev, ++ dma_unmap_addr(&tx_cb->map[seg], mapaddr), ++ dma_unmap_len(&tx_cb->map[seg], maplen), ++ DMA_TO_DEVICE); + oal++; + seg++; + } + +- pci_unmap_page(qdev->pdev, ++ dma_unmap_page(&qdev->pdev->dev, + dma_unmap_addr(&tx_cb->map[seg], mapaddr), + dma_unmap_len(&tx_cb->map[seg], maplen), +- PCI_DMA_TODEVICE); ++ DMA_TO_DEVICE); + } + +- pci_unmap_single(qdev->pdev, ++ dma_unmap_single(&qdev->pdev->dev, + dma_unmap_addr(&tx_cb->map[0], mapaddr), + dma_unmap_addr(&tx_cb->map[0], maplen), +- PCI_DMA_TODEVICE); ++ DMA_TO_DEVICE); + + return NETDEV_TX_BUSY; + +@@ -2528,9 +2522,8 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) + wmb(); + + qdev->req_q_virt_addr = +- pci_alloc_consistent(qdev->pdev, +- (size_t) qdev->req_q_size, +- &qdev->req_q_phy_addr); ++ dma_alloc_coherent(&qdev->pdev->dev, (size_t)qdev->req_q_size, ++ &qdev->req_q_phy_addr, GFP_KERNEL); + + if ((qdev->req_q_virt_addr == NULL) || + LS_64BITS(qdev->req_q_phy_addr) & (qdev->req_q_size - 1)) { +@@ -2539,16 +2532,14 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) + } + + qdev->rsp_q_virt_addr = +- pci_alloc_consistent(qdev->pdev, +- (size_t) qdev->rsp_q_size, +- &qdev->rsp_q_phy_addr); ++ dma_alloc_coherent(&qdev->pdev->dev, (size_t)qdev->rsp_q_size, ++ &qdev->rsp_q_phy_addr, GFP_KERNEL); + + if ((qdev->rsp_q_virt_addr == NULL) || + LS_64BITS(qdev->rsp_q_phy_addr) & (qdev->rsp_q_size - 1)) { + netdev_err(qdev->ndev, "rspQ allocation failed\n"); +- pci_free_consistent(qdev->pdev, (size_t) qdev->req_q_size, +- qdev->req_q_virt_addr, +- qdev->req_q_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, (size_t)qdev->req_q_size, ++ qdev->req_q_virt_addr, qdev->req_q_phy_addr); + return -ENOMEM; + } + +@@ -2564,15 +2555,13 @@ static void ql_free_net_req_rsp_queues(struct ql3_adapter *qdev) + return; + } + +- pci_free_consistent(qdev->pdev, +- qdev->req_q_size, +- qdev->req_q_virt_addr, qdev->req_q_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, qdev->req_q_size, ++ qdev->req_q_virt_addr, qdev->req_q_phy_addr); + + qdev->req_q_virt_addr = NULL; + +- pci_free_consistent(qdev->pdev, +- qdev->rsp_q_size, +- qdev->rsp_q_virt_addr, qdev->rsp_q_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, qdev->rsp_q_size, ++ qdev->rsp_q_virt_addr, qdev->rsp_q_phy_addr); + + qdev->rsp_q_virt_addr = NULL; + +@@ -2596,9 +2585,9 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) + return -ENOMEM; + + qdev->lrg_buf_q_alloc_virt_addr = +- pci_alloc_consistent(qdev->pdev, +- qdev->lrg_buf_q_alloc_size, +- &qdev->lrg_buf_q_alloc_phy_addr); ++ dma_alloc_coherent(&qdev->pdev->dev, ++ qdev->lrg_buf_q_alloc_size, ++ &qdev->lrg_buf_q_alloc_phy_addr, GFP_KERNEL); + + if (qdev->lrg_buf_q_alloc_virt_addr == NULL) { + netdev_err(qdev->ndev, "lBufQ failed\n"); +@@ -2616,15 +2605,16 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) + qdev->small_buf_q_alloc_size = qdev->small_buf_q_size * 2; + + qdev->small_buf_q_alloc_virt_addr = +- pci_alloc_consistent(qdev->pdev, +- qdev->small_buf_q_alloc_size, +- &qdev->small_buf_q_alloc_phy_addr); ++ dma_alloc_coherent(&qdev->pdev->dev, ++ qdev->small_buf_q_alloc_size, ++ &qdev->small_buf_q_alloc_phy_addr, GFP_KERNEL); + + if (qdev->small_buf_q_alloc_virt_addr == NULL) { + netdev_err(qdev->ndev, "Small Buffer Queue allocation failed\n"); +- pci_free_consistent(qdev->pdev, qdev->lrg_buf_q_alloc_size, +- qdev->lrg_buf_q_alloc_virt_addr, +- qdev->lrg_buf_q_alloc_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, ++ qdev->lrg_buf_q_alloc_size, ++ qdev->lrg_buf_q_alloc_virt_addr, ++ qdev->lrg_buf_q_alloc_phy_addr); + return -ENOMEM; + } + +@@ -2641,17 +2631,15 @@ static void ql_free_buffer_queues(struct ql3_adapter *qdev) + return; + } + kfree(qdev->lrg_buf); +- pci_free_consistent(qdev->pdev, +- qdev->lrg_buf_q_alloc_size, +- qdev->lrg_buf_q_alloc_virt_addr, +- qdev->lrg_buf_q_alloc_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, qdev->lrg_buf_q_alloc_size, ++ qdev->lrg_buf_q_alloc_virt_addr, ++ qdev->lrg_buf_q_alloc_phy_addr); + + qdev->lrg_buf_q_virt_addr = NULL; + +- pci_free_consistent(qdev->pdev, +- qdev->small_buf_q_alloc_size, +- qdev->small_buf_q_alloc_virt_addr, +- qdev->small_buf_q_alloc_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, qdev->small_buf_q_alloc_size, ++ qdev->small_buf_q_alloc_virt_addr, ++ qdev->small_buf_q_alloc_phy_addr); + + qdev->small_buf_q_virt_addr = NULL; + +@@ -2669,9 +2657,9 @@ static int ql_alloc_small_buffers(struct ql3_adapter *qdev) + QL_SMALL_BUFFER_SIZE); + + qdev->small_buf_virt_addr = +- pci_alloc_consistent(qdev->pdev, +- qdev->small_buf_total_size, +- &qdev->small_buf_phy_addr); ++ dma_alloc_coherent(&qdev->pdev->dev, ++ qdev->small_buf_total_size, ++ &qdev->small_buf_phy_addr, GFP_KERNEL); + + if (qdev->small_buf_virt_addr == NULL) { + netdev_err(qdev->ndev, "Failed to get small buffer memory\n"); +@@ -2704,10 +2692,10 @@ static void ql_free_small_buffers(struct ql3_adapter *qdev) + return; + } + if (qdev->small_buf_virt_addr != NULL) { +- pci_free_consistent(qdev->pdev, +- qdev->small_buf_total_size, +- qdev->small_buf_virt_addr, +- qdev->small_buf_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, ++ qdev->small_buf_total_size, ++ qdev->small_buf_virt_addr, ++ qdev->small_buf_phy_addr); + + qdev->small_buf_virt_addr = NULL; + } +@@ -2722,10 +2710,10 @@ static void ql_free_large_buffers(struct ql3_adapter *qdev) + lrg_buf_cb = &qdev->lrg_buf[i]; + if (lrg_buf_cb->skb) { + dev_kfree_skb(lrg_buf_cb->skb); +- pci_unmap_single(qdev->pdev, ++ dma_unmap_single(&qdev->pdev->dev, + dma_unmap_addr(lrg_buf_cb, mapaddr), + dma_unmap_len(lrg_buf_cb, maplen), +- PCI_DMA_FROMDEVICE); ++ DMA_FROM_DEVICE); + memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb)); + } else { + break; +@@ -2777,13 +2765,11 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) + * buffer + */ + skb_reserve(skb, QL_HEADER_SPACE); +- map = pci_map_single(qdev->pdev, +- skb->data, +- qdev->lrg_buffer_len - +- QL_HEADER_SPACE, +- PCI_DMA_FROMDEVICE); ++ map = dma_map_single(&qdev->pdev->dev, skb->data, ++ qdev->lrg_buffer_len - QL_HEADER_SPACE, ++ DMA_FROM_DEVICE); + +- err = pci_dma_mapping_error(qdev->pdev, map); ++ err = dma_mapping_error(&qdev->pdev->dev, map); + if (err) { + netdev_err(qdev->ndev, + "PCI mapping failed with error: %d\n", +@@ -2868,8 +2854,8 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev) + * Network Completion Queue Producer Index Register + */ + qdev->shadow_reg_virt_addr = +- pci_alloc_consistent(qdev->pdev, +- PAGE_SIZE, &qdev->shadow_reg_phy_addr); ++ dma_alloc_coherent(&qdev->pdev->dev, PAGE_SIZE, ++ &qdev->shadow_reg_phy_addr, GFP_KERNEL); + + if (qdev->shadow_reg_virt_addr != NULL) { + qdev->preq_consumer_index = qdev->shadow_reg_virt_addr; +@@ -2924,10 +2910,9 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev) + err_buffer_queues: + ql_free_net_req_rsp_queues(qdev); + err_req_rsp: +- pci_free_consistent(qdev->pdev, +- PAGE_SIZE, +- qdev->shadow_reg_virt_addr, +- qdev->shadow_reg_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, PAGE_SIZE, ++ qdev->shadow_reg_virt_addr, ++ qdev->shadow_reg_phy_addr); + + return -ENOMEM; + } +@@ -2940,10 +2925,9 @@ static void ql_free_mem_resources(struct ql3_adapter *qdev) + ql_free_buffer_queues(qdev); + ql_free_net_req_rsp_queues(qdev); + if (qdev->shadow_reg_virt_addr != NULL) { +- pci_free_consistent(qdev->pdev, +- PAGE_SIZE, +- qdev->shadow_reg_virt_addr, +- qdev->shadow_reg_phy_addr); ++ dma_free_coherent(&qdev->pdev->dev, PAGE_SIZE, ++ qdev->shadow_reg_virt_addr, ++ qdev->shadow_reg_phy_addr); + qdev->shadow_reg_virt_addr = NULL; + } + } +@@ -3644,18 +3628,15 @@ static void ql_reset_work(struct work_struct *work) + if (tx_cb->skb) { + netdev_printk(KERN_DEBUG, ndev, + "Freeing lost SKB\n"); +- pci_unmap_single(qdev->pdev, +- dma_unmap_addr(&tx_cb->map[0], +- mapaddr), +- dma_unmap_len(&tx_cb->map[0], maplen), +- PCI_DMA_TODEVICE); ++ dma_unmap_single(&qdev->pdev->dev, ++ dma_unmap_addr(&tx_cb->map[0], mapaddr), ++ dma_unmap_len(&tx_cb->map[0], maplen), ++ DMA_TO_DEVICE); + for (j = 1; j < tx_cb->seg_count; j++) { +- pci_unmap_page(qdev->pdev, +- dma_unmap_addr(&tx_cb->map[j], +- mapaddr), +- dma_unmap_len(&tx_cb->map[j], +- maplen), +- PCI_DMA_TODEVICE); ++ dma_unmap_page(&qdev->pdev->dev, ++ dma_unmap_addr(&tx_cb->map[j], mapaddr), ++ dma_unmap_len(&tx_cb->map[j], maplen), ++ DMA_TO_DEVICE); + } + dev_kfree_skb(tx_cb->skb); + tx_cb->skb = NULL; +@@ -3787,13 +3768,10 @@ static int ql3xxx_probe(struct pci_dev *pdev, + + pci_set_master(pdev); + +- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { ++ if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) + pci_using_dac = 1; +- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); +- } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { ++ else if (!(err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))) + pci_using_dac = 0; +- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); +- } + + if (err) { + pr_err("%s no usable DMA configuration\n", pci_name(pdev)); +-- +2.43.0 + diff --git a/queue-4.19/net-save-and-restore-msg_namelen-in-sock_sendmsg.patch b/queue-4.19/net-save-and-restore-msg_namelen-in-sock_sendmsg.patch new file mode 100644 index 00000000000..ad98d15df59 --- /dev/null +++ b/queue-4.19/net-save-and-restore-msg_namelen-in-sock_sendmsg.patch @@ -0,0 +1,55 @@ +From 0b4d7406fd0291c5165574115e9923198123b65e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Dec 2023 09:12:30 -0400 +Subject: net: Save and restore msg_namelen in sock_sendmsg + +From: Marc Dionne + +[ Upstream commit 01b2885d9415152bcb12ff1f7788f500a74ea0ed ] + +Commit 86a7e0b69bd5 ("net: prevent rewrite of msg_name in +sock_sendmsg()") made sock_sendmsg save the incoming msg_name pointer +and restore it before returning, to insulate the caller against +msg_name being changed by the called code. If the address length +was also changed however, we may return with an inconsistent structure +where the length doesn't match the address, and attempts to reuse it may +lead to lost packets. + +For example, a kernel that doesn't have commit 1c5950fc6fe9 ("udp6: fix +potential access to stale information") will replace a v4 mapped address +with its ipv4 equivalent, and shorten namelen accordingly from 28 to 16. +If the caller attempts to reuse the resulting msg structure, it will have +the original ipv6 (v4 mapped) address but an incorrect v4 length. + +Fixes: 86a7e0b69bd5 ("net: prevent rewrite of msg_name in sock_sendmsg()") +Signed-off-by: Marc Dionne +Reviewed-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/socket.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/socket.c b/net/socket.c +index 328f584345fb3..49ac98cfda423 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -675,6 +675,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg) + { + struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name; + struct sockaddr_storage address; ++ int save_len = msg->msg_namelen; + int ret; + + if (msg->msg_name) { +@@ -684,6 +685,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg) + + ret = __sock_sendmsg(sock, msg); + msg->msg_name = save_addr; ++ msg->msg_namelen = save_len; + + return ret; + } +-- +2.43.0 + diff --git a/queue-4.19/net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch b/queue-4.19/net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch new file mode 100644 index 00000000000..62aa79a1c80 --- /dev/null +++ b/queue-4.19/net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch @@ -0,0 +1,40 @@ +From c579d769c380e4de5ab22916c3461560a14831ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Dec 2023 10:25:31 +0800 +Subject: net: sched: em_text: fix possible memory leak in em_text_destroy() + +From: Hangyu Hua + +[ Upstream commit 8fcb0382af6f1ef50936f1be05b8149eb2f88496 ] + +m->data needs to be freed when em_text_destroy is called. + +Fixes: d675c989ed2d ("[PKT_SCHED]: Packet classification based on textsearch (ematch)") +Acked-by: Jamal Hadi Salim +Signed-off-by: Hangyu Hua +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/sched/em_text.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/sched/em_text.c b/net/sched/em_text.c +index 73e2ed576ceb3..cbf44783024f3 100644 +--- a/net/sched/em_text.c ++++ b/net/sched/em_text.c +@@ -101,8 +101,10 @@ static int em_text_change(struct net *net, void *data, int len, + + static void em_text_destroy(struct tcf_ematch *m) + { +- if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) ++ if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) { + textsearch_destroy(EM_TEXT_PRIV(m)->config); ++ kfree(EM_TEXT_PRIV(m)); ++ } + } + + static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) +-- +2.43.0 + diff --git a/queue-4.19/nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch b/queue-4.19/nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch new file mode 100644 index 00000000000..f6cf2e2e3c1 --- /dev/null +++ b/queue-4.19/nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch @@ -0,0 +1,128 @@ +From 1dcd20d754cb05dc84e060ea9e6953fe36d0b788 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Dec 2023 23:19:43 +0530 +Subject: nfc: llcp_core: Hold a ref to llcp_local->dev when holding a ref to + llcp_local + +From: Siddh Raman Pant + +[ Upstream commit c95f919567d6f1914f13350af61a1b044ac85014 ] + +llcp_sock_sendmsg() calls nfc_llcp_send_ui_frame() which in turn calls +nfc_alloc_send_skb(), which accesses the nfc_dev from the llcp_sock for +getting the headroom and tailroom needed for skb allocation. + +Parallelly the nfc_dev can be freed, as the refcount is decreased via +nfc_free_device(), leading to a UAF reported by Syzkaller, which can +be summarized as follows: + +(1) llcp_sock_sendmsg() -> nfc_llcp_send_ui_frame() + -> nfc_alloc_send_skb() -> Dereference *nfc_dev +(2) virtual_ncidev_close() -> nci_free_device() -> nfc_free_device() + -> put_device() -> nfc_release() -> Free *nfc_dev + +When a reference to llcp_local is acquired, we do not acquire the same +for the nfc_dev. This leads to freeing even when the llcp_local is in +use, and this is the case with the UAF described above too. + +Thus, when we acquire a reference to llcp_local, we should acquire a +reference to nfc_dev, and release the references appropriately later. + +References for llcp_local is initialized in nfc_llcp_register_device() +(which is called by nfc_register_device()). Thus, we should acquire a +reference to nfc_dev there. + +nfc_unregister_device() calls nfc_llcp_unregister_device() which in +turn calls nfc_llcp_local_put(). Thus, the reference to nfc_dev is +appropriately released later. + +Reported-and-tested-by: syzbot+bbe84a4010eeea00982d@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bbe84a4010eeea00982d +Fixes: c7aa12252f51 ("NFC: Take a reference on the LLCP local pointer when creating a socket") +Reviewed-by: Suman Ghosh +Signed-off-by: Siddh Raman Pant +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/nfc/llcp_core.c | 39 ++++++++++++++++++++++++++++++++++++--- + 1 file changed, 36 insertions(+), 3 deletions(-) + +diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c +index c30b28465e644..a217830f0f34c 100644 +--- a/net/nfc/llcp_core.c ++++ b/net/nfc/llcp_core.c +@@ -157,6 +157,13 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device, + + struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) + { ++ /* Since using nfc_llcp_local may result in usage of nfc_dev, whenever ++ * we hold a reference to local, we also need to hold a reference to ++ * the device to avoid UAF. ++ */ ++ if (!nfc_get_device(local->dev->idx)) ++ return NULL; ++ + kref_get(&local->ref); + + return local; +@@ -190,10 +197,18 @@ static void local_release(struct kref *ref) + + int nfc_llcp_local_put(struct nfc_llcp_local *local) + { ++ struct nfc_dev *dev; ++ int ret; ++ + if (local == NULL) + return 0; + +- return kref_put(&local->ref, local_release); ++ dev = local->dev; ++ ++ ret = kref_put(&local->ref, local_release); ++ nfc_put_device(dev); ++ ++ return ret; + } + + static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, +@@ -951,8 +966,17 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, + } + + new_sock = nfc_llcp_sock(new_sk); +- new_sock->dev = local->dev; ++ + new_sock->local = nfc_llcp_local_get(local); ++ if (!new_sock->local) { ++ reason = LLCP_DM_REJ; ++ sock_put(&new_sock->sk); ++ release_sock(&sock->sk); ++ sock_put(&sock->sk); ++ goto fail; ++ } ++ ++ new_sock->dev = local->dev; + new_sock->rw = sock->rw; + new_sock->miux = sock->miux; + new_sock->nfc_protocol = sock->nfc_protocol; +@@ -1584,7 +1608,16 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) + if (local == NULL) + return -ENOMEM; + +- local->dev = ndev; ++ /* As we are going to initialize local's refcount, we need to get the ++ * nfc_dev to avoid UAF, otherwise there is no point in continuing. ++ * See nfc_llcp_local_get(). ++ */ ++ local->dev = nfc_get_device(ndev->idx); ++ if (!local->dev) { ++ kfree(local); ++ return -ENODEV; ++ } ++ + INIT_LIST_HEAD(&local->list); + kref_init(&local->ref); + mutex_init(&local->sdp_lock); +-- +2.43.0 + diff --git a/queue-4.19/series b/queue-4.19/series index 0cf7dd2489b..a5f24241aea 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -39,3 +39,16 @@ usb-fotg210-hcd-delete-an-incorrect-bounds-test.patch smb-client-fix-oob-in-smbcalcsize.patch dm-integrity-don-t-modify-bio-s-immutable-bio_vec-in-integrity_metadata.patch block-don-t-invalidate-pagecache-for-invalid-falloc-modes.patch +nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch +i40e-fix-filter-input-checks-to-prevent-config-with-.patch +net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch +arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch +net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch +net-save-and-restore-msg_namelen-in-sock_sendmsg.patch +i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch +i40e-restore-vf-msi-x-state-during-pci-reset.patch +net-qla3xxx-switch-from-pci_-to-dma_-api.patch +net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch +asix-add-check-for-usbnet_get_endpoints.patch +bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch +mm-memory-failure-check-the-mapcount-of-the-precise-.patch -- 2.47.3