From: Sasha Levin Date: Sat, 15 Mar 2025 01:12:06 +0000 (-0400) Subject: Fixes for 6.1 X-Git-Tag: v6.6.84~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d37a6ab6abe897f9aa74af92b0a78d21e5fa543a;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/bluetooth-hci_event-fix-enabling-passive-scanning.patch b/queue-6.1/bluetooth-hci_event-fix-enabling-passive-scanning.patch new file mode 100644 index 0000000000..f944f5dd3a --- /dev/null +++ b/queue-6.1/bluetooth-hci_event-fix-enabling-passive-scanning.patch @@ -0,0 +1,102 @@ +From 4bbd041467d2d1e83e08a1674f851c01f3f6927d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Feb 2025 13:12:54 -0500 +Subject: Bluetooth: hci_event: Fix enabling passive scanning + +From: Luiz Augusto von Dentz + +[ Upstream commit 0bdd88971519cfa8a76d1a4dde182e74cfbd5d5c ] + +Passive scanning shall only be enabled when disconnecting LE links, +otherwise it may start result in triggering scanning when e.g. an ISO +link disconnects: + +> HCI Event: LE Meta Event (0x3e) plen 29 + LE Connected Isochronous Stream Established (0x19) + Status: Success (0x00) + Connection Handle: 257 + CIG Synchronization Delay: 0 us (0x000000) + CIS Synchronization Delay: 0 us (0x000000) + Central to Peripheral Latency: 10000 us (0x002710) + Peripheral to Central Latency: 10000 us (0x002710) + Central to Peripheral PHY: LE 2M (0x02) + Peripheral to Central PHY: LE 2M (0x02) + Number of Subevents: 1 + Central to Peripheral Burst Number: 1 + Peripheral to Central Burst Number: 1 + Central to Peripheral Flush Timeout: 2 + Peripheral to Central Flush Timeout: 2 + Central to Peripheral MTU: 320 + Peripheral to Central MTU: 160 + ISO Interval: 10.00 msec (0x0008) +... +> HCI Event: Disconnect Complete (0x05) plen 4 + Status: Success (0x00) + Handle: 257 + Reason: Remote User Terminated Connection (0x13) +< HCI Command: LE Set Extended Scan Enable (0x08|0x0042) plen 6 + Extended scan: Enabled (0x01) + Filter duplicates: Enabled (0x01) + Duration: 0 msec (0x0000) + Period: 0.00 sec (0x0000) + +Fixes: 9fcb18ef3acb ("Bluetooth: Introduce LE auto connect options") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_event.c | 37 ++++++++++++++++++++++--------------- + 1 file changed, 22 insertions(+), 15 deletions(-) + +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index b6fe5e15981f8..6cfd61628cd78 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -3477,23 +3477,30 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data, + hci_update_scan(hdev); + } + +- params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); +- if (params) { +- switch (params->auto_connect) { +- case HCI_AUTO_CONN_LINK_LOSS: +- if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) ++ /* Re-enable passive scanning if disconnected device is marked ++ * as auto-connectable. ++ */ ++ if (conn->type == LE_LINK) { ++ params = hci_conn_params_lookup(hdev, &conn->dst, ++ conn->dst_type); ++ if (params) { ++ switch (params->auto_connect) { ++ case HCI_AUTO_CONN_LINK_LOSS: ++ if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) ++ break; ++ fallthrough; ++ ++ case HCI_AUTO_CONN_DIRECT: ++ case HCI_AUTO_CONN_ALWAYS: ++ hci_pend_le_list_del_init(params); ++ hci_pend_le_list_add(params, ++ &hdev->pend_le_conns); ++ hci_update_passive_scan(hdev); + break; +- fallthrough; + +- case HCI_AUTO_CONN_DIRECT: +- case HCI_AUTO_CONN_ALWAYS: +- hci_pend_le_list_del_init(params); +- hci_pend_le_list_add(params, &hdev->pend_le_conns); +- hci_update_passive_scan(hdev); +- break; +- +- default: +- break; ++ default: ++ break; ++ } + } + } + +-- +2.39.5 + diff --git a/queue-6.1/bonding-fix-incorrect-mac-address-setting-to-receive.patch b/queue-6.1/bonding-fix-incorrect-mac-address-setting-to-receive.patch new file mode 100644 index 0000000000..4234343adf --- /dev/null +++ b/queue-6.1/bonding-fix-incorrect-mac-address-setting-to-receive.patch @@ -0,0 +1,131 @@ +From e49f5a555be52156ae6420b1d43e6f3ce096e6b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 02:39:22 +0000 +Subject: bonding: fix incorrect MAC address setting to receive NS messages + +From: Hangbin Liu + +[ Upstream commit 0c5e145a350de3b38cd5ae77a401b12c46fb7c1d ] + +When validation on the backup slave is enabled, we need to validate the +Neighbor Solicitation (NS) messages received on the backup slave. To +receive these messages, the correct destination MAC address must be added +to the slave. However, the target in bonding is a unicast address, which +we cannot use directly. Instead, we should first convert it to a +Solicited-Node Multicast Address and then derive the corresponding MAC +address. + +Fix the incorrect MAC address setting on both slave_set_ns_maddr() and +slave_set_ns_maddrs(). Since the two function names are similar. Add +some description for the functions. Also only use one mac_addr variable +in slave_set_ns_maddr() to save some code and logic. + +Fixes: 8eb36164d1a6 ("bonding: add ns target multicast address to slave device") +Acked-by: Jay Vosburgh +Reviewed-by: Nikolay Aleksandrov +Signed-off-by: Hangbin Liu +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250306023923.38777-2-liuhangbin@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_options.c | 55 +++++++++++++++++++++++++----- + 1 file changed, 47 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c +index c8536dc7d860d..21ca95cdef42e 100644 +--- a/drivers/net/bonding/bond_options.c ++++ b/drivers/net/bonding/bond_options.c +@@ -1238,10 +1238,28 @@ static bool slave_can_set_ns_maddr(const struct bonding *bond, struct slave *sla + slave->dev->flags & IFF_MULTICAST; + } + ++/** ++ * slave_set_ns_maddrs - add/del all NS mac addresses for slave ++ * @bond: bond device ++ * @slave: slave device ++ * @add: add or remove all the NS mac addresses ++ * ++ * This function tries to add or delete all the NS mac addresses on the slave ++ * ++ * Note, the IPv6 NS target address is the unicast address in Neighbor ++ * Solicitation (NS) message. The dest address of NS message should be ++ * solicited-node multicast address of the target. The dest mac of NS message ++ * is converted from the solicited-node multicast address. ++ * ++ * This function is called when ++ * * arp_validate changes ++ * * enslaving, releasing new slaves ++ */ + static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool add) + { + struct in6_addr *targets = bond->params.ns_targets; + char slot_maddr[MAX_ADDR_LEN]; ++ struct in6_addr mcaddr; + int i; + + if (!slave_can_set_ns_maddr(bond, slave)) +@@ -1251,7 +1269,8 @@ static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool + if (ipv6_addr_any(&targets[i])) + break; + +- if (!ndisc_mc_map(&targets[i], slot_maddr, slave->dev, 0)) { ++ addrconf_addr_solict_mult(&targets[i], &mcaddr); ++ if (!ndisc_mc_map(&mcaddr, slot_maddr, slave->dev, 0)) { + if (add) + dev_mc_add(slave->dev, slot_maddr); + else +@@ -1274,23 +1293,43 @@ void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave) + slave_set_ns_maddrs(bond, slave, false); + } + ++/** ++ * slave_set_ns_maddr - set new NS mac address for slave ++ * @bond: bond device ++ * @slave: slave device ++ * @target: the new IPv6 target ++ * @slot: the old IPv6 target in the slot ++ * ++ * This function tries to replace the old mac address to new one on the slave. ++ * ++ * Note, the target/slot IPv6 address is the unicast address in Neighbor ++ * Solicitation (NS) message. The dest address of NS message should be ++ * solicited-node multicast address of the target. The dest mac of NS message ++ * is converted from the solicited-node multicast address. ++ * ++ * This function is called when ++ * * An IPv6 NS target is added or removed. ++ */ + static void slave_set_ns_maddr(struct bonding *bond, struct slave *slave, + struct in6_addr *target, struct in6_addr *slot) + { +- char target_maddr[MAX_ADDR_LEN], slot_maddr[MAX_ADDR_LEN]; ++ char mac_addr[MAX_ADDR_LEN]; ++ struct in6_addr mcast_addr; + + if (!bond->params.arp_validate || !slave_can_set_ns_maddr(bond, slave)) + return; + +- /* remove the previous maddr from slave */ ++ /* remove the previous mac addr from slave */ ++ addrconf_addr_solict_mult(slot, &mcast_addr); + if (!ipv6_addr_any(slot) && +- !ndisc_mc_map(slot, slot_maddr, slave->dev, 0)) +- dev_mc_del(slave->dev, slot_maddr); ++ !ndisc_mc_map(&mcast_addr, mac_addr, slave->dev, 0)) ++ dev_mc_del(slave->dev, mac_addr); + +- /* add new maddr on slave if target is set */ ++ /* add new mac addr on slave if target is set */ ++ addrconf_addr_solict_mult(target, &mcast_addr); + if (!ipv6_addr_any(target) && +- !ndisc_mc_map(target, target_maddr, slave->dev, 0)) +- dev_mc_add(slave->dev, target_maddr); ++ !ndisc_mc_map(&mcast_addr, mac_addr, slave->dev, 0)) ++ dev_mc_add(slave->dev, mac_addr); + } + + static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot, +-- +2.39.5 + diff --git a/queue-6.1/drivers-hv-vmbus-don-t-release-fb_mmio-resource-in-v.patch b/queue-6.1/drivers-hv-vmbus-don-t-release-fb_mmio-resource-in-v.patch new file mode 100644 index 0000000000..d038355594 --- /dev/null +++ b/queue-6.1/drivers-hv-vmbus-don-t-release-fb_mmio-resource-in-v.patch @@ -0,0 +1,85 @@ +From 7ac4e3bd2118a4c8a3575e7e0cac17a09bea9695 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Mar 2025 20:52:08 -0700 +Subject: Drivers: hv: vmbus: Don't release fb_mmio resource in + vmbus_free_mmio() + +From: Michael Kelley + +[ Upstream commit 73fe9073c0cc28056cb9de0c8a516dac070f1d1f ] + +The VMBus driver manages the MMIO space it owns via the hyperv_mmio +resource tree. Because the synthetic video framebuffer portion of the +MMIO space is initially setup by the Hyper-V host for each guest, the +VMBus driver does an early reserve of that portion of MMIO space in the +hyperv_mmio resource tree. It saves a pointer to that resource in +fb_mmio. When a VMBus driver requests MMIO space and passes "true" +for the "fb_overlap_ok" argument, the reserved framebuffer space is +used if possible. In that case it's not necessary to do another request +against the "shadow" hyperv_mmio resource tree because that resource +was already requested in the early reserve steps. + +However, the vmbus_free_mmio() function currently does no special +handling for the fb_mmio resource. When a framebuffer device is +removed, or the driver is unbound, the current code for +vmbus_free_mmio() releases the reserved resource, leaving fb_mmio +pointing to memory that has been freed. If the same or another +driver is subsequently bound to the device, vmbus_allocate_mmio() +checks against fb_mmio, and potentially gets garbage. Furthermore +a second unbind operation produces this "nonexistent resource" error +because of the unbalanced behavior between vmbus_allocate_mmio() and +vmbus_free_mmio(): + +[ 55.499643] resource: Trying to free nonexistent + resource <0x00000000f0000000-0x00000000f07fffff> + +Fix this by adding logic to vmbus_free_mmio() to recognize when +MMIO space in the fb_mmio reserved area would be released, and don't +release it. This filtering ensures the fb_mmio resource always exists, +and makes vmbus_free_mmio() more parallel with vmbus_allocate_mmio(). + +Fixes: be000f93e5d7 ("drivers:hv: Track allocations of children of hv_vmbus in private resource tree") +Signed-off-by: Michael Kelley +Tested-by: Saurabh Sengar +Reviewed-by: Saurabh Sengar +Link: https://lore.kernel.org/r/20250310035208.275764-1-mhklinux@outlook.com +Signed-off-by: Wei Liu +Message-ID: <20250310035208.275764-1-mhklinux@outlook.com> +Signed-off-by: Sasha Levin +--- + drivers/hv/vmbus_drv.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index a2191bc5c1535..dfbfdbf9cbd72 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -2409,12 +2409,25 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size) + struct resource *iter; + + mutex_lock(&hyperv_mmio_lock); ++ ++ /* ++ * If all bytes of the MMIO range to be released are within the ++ * special case fb_mmio shadow region, skip releasing the shadow ++ * region since no corresponding __request_region() was done ++ * in vmbus_allocate_mmio(). ++ */ ++ if (fb_mmio && start >= fb_mmio->start && ++ (start + size - 1 <= fb_mmio->end)) ++ goto skip_shadow_release; ++ + for (iter = hyperv_mmio; iter; iter = iter->sibling) { + if ((iter->start >= start + size) || (iter->end <= start)) + continue; + + __release_region(iter, start, size); + } ++ ++skip_shadow_release: + release_mem_region(start, size); + mutex_unlock(&hyperv_mmio_lock); + +-- +2.39.5 + diff --git a/queue-6.1/drm-hyperv-fix-address-space-leak-when-hyper-v-drm-d.patch b/queue-6.1/drm-hyperv-fix-address-space-leak-when-hyper-v-drm-d.patch new file mode 100644 index 0000000000..e220f8242e --- /dev/null +++ b/queue-6.1/drm-hyperv-fix-address-space-leak-when-hyper-v-drm-d.patch @@ -0,0 +1,53 @@ +From 5ad741668113fcb9d75998e528a95d1734c80291 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Feb 2025 11:34:41 -0800 +Subject: drm/hyperv: Fix address space leak when Hyper-V DRM device is removed + +From: Michael Kelley + +[ Upstream commit aed709355fd05ef747e1af24a1d5d78cd7feb81e ] + +When a Hyper-V DRM device is probed, the driver allocates MMIO space for +the vram, and maps it cacheable. If the device removed, or in the error +path for device probing, the MMIO space is released but no unmap is done. +Consequently the kernel address space for the mapping is leaked. + +Fix this by adding iounmap() calls in the device removal path, and in the +error path during device probing. + +Fixes: f1f63cbb705d ("drm/hyperv: Fix an error handling path in hyperv_vmbus_probe()") +Fixes: a0ab5abced55 ("drm/hyperv : Removing the restruction of VRAM allocation with PCI bar size") +Signed-off-by: Michael Kelley +Reviewed-by: Saurabh Sengar +Tested-by: Saurabh Sengar +Link: https://lore.kernel.org/r/20250210193441.2414-1-mhklinux@outlook.com +Signed-off-by: Wei Liu +Message-ID: <20250210193441.2414-1-mhklinux@outlook.com> +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +index 68050409dd26c..499c7c8916df2 100644 +--- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c ++++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +@@ -157,6 +157,7 @@ static int hyperv_vmbus_probe(struct hv_device *hdev, + return 0; + + err_free_mmio: ++ iounmap(hv->vram); + vmbus_free_mmio(hv->mem->start, hv->fb_size); + err_vmbus_close: + vmbus_close(hdev->channel); +@@ -175,6 +176,7 @@ static int hyperv_vmbus_remove(struct hv_device *hdev) + vmbus_close(hdev->channel); + hv_set_drvdata(hdev, NULL); + ++ iounmap(hv->vram); + vmbus_free_mmio(hv->mem->start, hv->fb_size); + + return 0; +-- +2.39.5 + diff --git a/queue-6.1/eth-bnxt-do-not-update-checksum-in-bnxt_xdp_build_sk.patch b/queue-6.1/eth-bnxt-do-not-update-checksum-in-bnxt_xdp_build_sk.patch new file mode 100644 index 0000000000..cc2a214126 --- /dev/null +++ b/queue-6.1/eth-bnxt-do-not-update-checksum-in-bnxt_xdp_build_sk.patch @@ -0,0 +1,137 @@ +From 5e8e00ba63451920b4a9923b017a63609be354a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Mar 2025 13:42:15 +0000 +Subject: eth: bnxt: do not update checksum in bnxt_xdp_build_skb() + +From: Taehee Yoo + +[ Upstream commit c03e7d05aa0e2f7e9a9ce5ad8a12471a53f941dc ] + +The bnxt_rx_pkt() updates ip_summed value at the end if checksum offload +is enabled. +When the XDP-MB program is attached and it returns XDP_PASS, the +bnxt_xdp_build_skb() is called to update skb_shared_info. +The main purpose of bnxt_xdp_build_skb() is to update skb_shared_info, +but it updates ip_summed value too if checksum offload is enabled. +This is actually duplicate work. + +When the bnxt_rx_pkt() updates ip_summed value, it checks if ip_summed +is CHECKSUM_NONE or not. +It means that ip_summed should be CHECKSUM_NONE at this moment. +But ip_summed may already be updated to CHECKSUM_UNNECESSARY in the +XDP-MB-PASS path. +So the by skb_checksum_none_assert() WARNS about it. + +This is duplicate work and updating ip_summed in the +bnxt_xdp_build_skb() is not needed. + +Splat looks like: +WARNING: CPU: 3 PID: 5782 at ./include/linux/skbuff.h:5155 bnxt_rx_pkt+0x479b/0x7610 [bnxt_en] +Modules linked in: bnxt_re bnxt_en rdma_ucm rdma_cm iw_cm ib_cm ib_uverbs veth xt_nat xt_tcpudp xt_conntrack nft_chain_nat xt_MASQUERADE nf_] +CPU: 3 UID: 0 PID: 5782 Comm: socat Tainted: G W 6.14.0-rc4+ #27 +Tainted: [W]=WARN +Hardware name: ASUS System Product Name/PRIME Z690-P D4, BIOS 0603 11/01/2021 +RIP: 0010:bnxt_rx_pkt+0x479b/0x7610 [bnxt_en] +Code: 54 24 0c 4c 89 f1 4c 89 ff c1 ea 1f ff d3 0f 1f 00 49 89 c6 48 85 c0 0f 84 4c e5 ff ff 48 89 c7 e8 ca 3d a0 c8 e9 8f f4 ff ff <0f> 0b f +RSP: 0018:ffff88881ba09928 EFLAGS: 00010202 +RAX: 0000000000000000 RBX: 00000000c7590303 RCX: 0000000000000000 +RDX: 1ffff1104e7d1610 RSI: 0000000000000001 RDI: ffff8881c91300b8 +RBP: ffff88881ba09b28 R08: ffff888273e8b0d0 R09: ffff888273e8b070 +R10: ffff888273e8b010 R11: ffff888278b0f000 R12: ffff888273e8b080 +R13: ffff8881c9130e00 R14: ffff8881505d3800 R15: ffff888273e8b000 +FS: 00007f5a2e7be080(0000) GS:ffff88881ba00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007fff2e708ff8 CR3: 000000013e3b0000 CR4: 00000000007506f0 +PKRU: 55555554 +Call Trace: + + ? __warn+0xcd/0x2f0 + ? bnxt_rx_pkt+0x479b/0x7610 + ? report_bug+0x326/0x3c0 + ? handle_bug+0x53/0xa0 + ? exc_invalid_op+0x14/0x50 + ? asm_exc_invalid_op+0x16/0x20 + ? bnxt_rx_pkt+0x479b/0x7610 + ? bnxt_rx_pkt+0x3e41/0x7610 + ? __pfx_bnxt_rx_pkt+0x10/0x10 + ? napi_complete_done+0x2cf/0x7d0 + __bnxt_poll_work+0x4e8/0x1220 + ? __pfx___bnxt_poll_work+0x10/0x10 + ? __pfx_mark_lock.part.0+0x10/0x10 + bnxt_poll_p5+0x36a/0xfa0 + ? __pfx_bnxt_poll_p5+0x10/0x10 + __napi_poll.constprop.0+0xa0/0x440 + net_rx_action+0x899/0xd00 +... + +Following ping.py patch adds xdp-mb-pass case. so ping.py is going +to be able to reproduce this issue. + +Fixes: 1dc4c557bfed ("bnxt: adding bnxt_xdp_build_skb to build skb from multibuffer xdp_buff") +Signed-off-by: Taehee Yoo +Reviewed-by: Somnath Kotur +Link: https://patch.msgid.link/20250309134219.91670-5-ap420073@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 ++- + drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 11 ++--------- + drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 3 +-- + 3 files changed, 5 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 7d9677d0f7304..393a983f6d695 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -1994,7 +1994,8 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, + if (!skb) + goto oom_next_rx; + } else { +- skb = bnxt_xdp_build_skb(bp, skb, agg_bufs, rxr->page_pool, &xdp, rxcmp1); ++ skb = bnxt_xdp_build_skb(bp, skb, agg_bufs, ++ rxr->page_pool, &xdp); + if (!skb) { + /* we should be able to free the old skb here */ + bnxt_xdp_buff_frags_free(rxr, &xdp); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +index aa56db138d6b5..d9a7b85343a49 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +@@ -462,20 +462,13 @@ int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp) + + struct sk_buff * + bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags, +- struct page_pool *pool, struct xdp_buff *xdp, +- struct rx_cmp_ext *rxcmp1) ++ struct page_pool *pool, struct xdp_buff *xdp) + { + struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp); + + if (!skb) + return NULL; +- skb_checksum_none_assert(skb); +- if (RX_CMP_L4_CS_OK(rxcmp1)) { +- if (bp->dev->features & NETIF_F_RXCSUM) { +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- skb->csum_level = RX_CMP_ENCAP(rxcmp1); +- } +- } ++ + xdp_update_skb_shared_info(skb, num_frags, + sinfo->xdp_frags_size, + BNXT_RX_PAGE_SIZE * sinfo->nr_frags, +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h +index ea430d6961df3..ae8159c5f56c4 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h +@@ -33,6 +33,5 @@ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr, + struct xdp_buff *xdp); + struct sk_buff *bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, + u8 num_frags, struct page_pool *pool, +- struct xdp_buff *xdp, +- struct rx_cmp_ext *rxcmp1); ++ struct xdp_buff *xdp); + #endif +-- +2.39.5 + diff --git a/queue-6.1/fbdev-hyperv_fb-iounmap-the-correct-memory-when-remo.patch b/queue-6.1/fbdev-hyperv_fb-iounmap-the-correct-memory-when-remo.patch new file mode 100644 index 0000000000..ef781d7066 --- /dev/null +++ b/queue-6.1/fbdev-hyperv_fb-iounmap-the-correct-memory-when-remo.patch @@ -0,0 +1,53 @@ +From c07a6a3f7474e0e3828d3c0ca71b4e7cd7267ddc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Feb 2025 15:52:52 -0800 +Subject: fbdev: hyperv_fb: iounmap() the correct memory when removing a device + +From: Michael Kelley + +[ Upstream commit 7241c886a71797cc51efc6fadec7076fcf6435c2 ] + +When a Hyper-V framebuffer device is removed, or the driver is unbound +from a device, any allocated and/or mapped memory must be released. In +particular, MMIO address space that was mapped to the framebuffer must +be unmapped. Current code unmaps the wrong address, resulting in an +error like: + +[ 4093.980597] iounmap: bad address 00000000c936c05c + +followed by a stack dump. + +Commit d21987d709e8 ("video: hyperv: hyperv_fb: Support deferred IO for +Hyper-V frame buffer driver") changed the kind of address stored in +info->screen_base, and the iounmap() call in hvfb_putmem() was not +updated accordingly. + +Fix this by updating hvfb_putmem() to unmap the correct address. + +Fixes: d21987d709e8 ("video: hyperv: hyperv_fb: Support deferred IO for Hyper-V frame buffer driver") +Signed-off-by: Michael Kelley +Reviewed-by: Saurabh Sengar +Link: https://lore.kernel.org/r/20250209235252.2987-1-mhklinux@outlook.com +Signed-off-by: Wei Liu +Message-ID: <20250209235252.2987-1-mhklinux@outlook.com> +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/hyperv_fb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c +index d3d643cf7506c..41c496ff55cc4 100644 +--- a/drivers/video/fbdev/hyperv_fb.c ++++ b/drivers/video/fbdev/hyperv_fb.c +@@ -1106,7 +1106,7 @@ static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info) + + if (par->need_docopy) { + vfree(par->dio_vp); +- iounmap(info->screen_base); ++ iounmap(par->mmio_vp); + vmbus_free_mmio(par->mem->start, screen_fb_size); + } else { + hvfb_release_phymem(hdev, info->fix.smem_start, +-- +2.39.5 + diff --git a/queue-6.1/gre-fix-ipv6-link-local-address-generation.patch b/queue-6.1/gre-fix-ipv6-link-local-address-generation.patch new file mode 100644 index 0000000000..e721d65861 --- /dev/null +++ b/queue-6.1/gre-fix-ipv6-link-local-address-generation.patch @@ -0,0 +1,110 @@ +From ebf29721197e6939f9625b93999084062bba51b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Mar 2025 20:28:53 +0100 +Subject: gre: Fix IPv6 link-local address generation. + +From: Guillaume Nault + +[ Upstream commit 183185a18ff96751db52a46ccf93fff3a1f42815 ] + +Use addrconf_addr_gen() to generate IPv6 link-local addresses on GRE +devices in most cases and fall back to using add_v4_addrs() only in +case the GRE configuration is incompatible with addrconf_addr_gen(). + +GRE used to use addrconf_addr_gen() until commit e5dd729460ca +("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL +address") restricted this use to gretap and ip6gretap devices, and +created add_v4_addrs() (borrowed from SIT) for non-Ethernet GRE ones. + +The original problem came when commit 9af28511be10 ("addrconf: refuse +isatap eui64 for INADDR_ANY") made __ipv6_isatap_ifid() fail when its +addr parameter was 0. The commit says that this would create an invalid +address, however, I couldn't find any RFC saying that the generated +interface identifier would be wrong. Anyway, since gre over IPv4 +devices pass their local tunnel address to __ipv6_isatap_ifid(), that +commit broke their IPv6 link-local address generation when the local +address was unspecified. + +Then commit e5dd729460ca ("ip/ip6_gre: use the same logic as SIT +interfaces when computing v6LL address") tried to fix that case by +defining add_v4_addrs() and calling it to generate the IPv6 link-local +address instead of using addrconf_addr_gen() (apart for gretap and +ip6gretap devices, which would still use the regular +addrconf_addr_gen(), since they have a MAC address). + +That broke several use cases because add_v4_addrs() isn't properly +integrated into the rest of IPv6 Neighbor Discovery code. Several of +these shortcomings have been fixed over time, but add_v4_addrs() +remains broken on several aspects. In particular, it doesn't send any +Router Sollicitations, so the SLAAC process doesn't start until the +interface receives a Router Advertisement. Also, add_v4_addrs() mostly +ignores the address generation mode of the interface +(/proc/sys/net/ipv6/conf/*/addr_gen_mode), thus breaking the +IN6_ADDR_GEN_MODE_RANDOM and IN6_ADDR_GEN_MODE_STABLE_PRIVACY cases. + +Fix the situation by using add_v4_addrs() only in the specific scenario +where the normal method would fail. That is, for interfaces that have +all of the following characteristics: + + * run over IPv4, + * transport IP packets directly, not Ethernet (that is, not gretap + interfaces), + * tunnel endpoint is INADDR_ANY (that is, 0), + * device address generation mode is EUI64. + +In all other cases, revert back to the regular addrconf_addr_gen(). + +Also, remove the special case for ip6gre interfaces in add_v4_addrs(), +since ip6gre devices now always use addrconf_addr_gen() instead. + +Fixes: e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address") +Signed-off-by: Guillaume Nault +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/559c32ce5c9976b269e6337ac9abb6a96abe5096.1741375285.git.gnault@redhat.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv6/addrconf.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index f52527c86e71c..69fb4d7c9c98e 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3162,16 +3162,13 @@ static void add_v4_addrs(struct inet6_dev *idev) + struct in6_addr addr; + struct net_device *dev; + struct net *net = dev_net(idev->dev); +- int scope, plen, offset = 0; ++ int scope, plen; + u32 pflags = 0; + + ASSERT_RTNL(); + + memset(&addr, 0, sizeof(struct in6_addr)); +- /* in case of IP6GRE the dev_addr is an IPv6 and therefore we use only the last 4 bytes */ +- if (idev->dev->addr_len == sizeof(struct in6_addr)) +- offset = sizeof(struct in6_addr) - 4; +- memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4); ++ memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4); + + if (!(idev->dev->flags & IFF_POINTOPOINT) && idev->dev->type == ARPHRD_SIT) { + scope = IPV6_ADDR_COMPATv4; +@@ -3481,7 +3478,13 @@ static void addrconf_gre_config(struct net_device *dev) + return; + } + +- if (dev->type == ARPHRD_ETHER) { ++ /* Generate the IPv6 link-local address using addrconf_addr_gen(), ++ * unless we have an IPv4 GRE device not bound to an IP address and ++ * which is in EUI64 mode (as __ipv6_isatap_ifid() would fail in this ++ * case). Such devices fall back to add_v4_addrs() instead. ++ */ ++ if (!(dev->type == ARPHRD_IPGRE && *(__be32 *)dev->dev_addr == 0 && ++ idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)) { + addrconf_addr_gen(idev, true); + return; + } +-- +2.39.5 + diff --git a/queue-6.1/ice-fix-memory-leak-in-arfs-after-reset.patch b/queue-6.1/ice-fix-memory-leak-in-arfs-after-reset.patch new file mode 100644 index 0000000000..61cdd522a1 --- /dev/null +++ b/queue-6.1/ice-fix-memory-leak-in-arfs-after-reset.patch @@ -0,0 +1,68 @@ +From 830f404feaee8be2daad49bc8514eff03d7c28ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Jan 2025 09:15:39 +0100 +Subject: ice: fix memory leak in aRFS after reset + +From: Grzegorz Nitka + +[ Upstream commit 23d97f18901ef5e4e264e3b1777fe65c760186b5 ] + +Fix aRFS (accelerated Receive Flow Steering) structures memory leak by +adding a checker to verify if aRFS memory is already allocated while +configuring VSI. aRFS objects are allocated in two cases: +- as part of VSI initialization (at probe), and +- as part of reset handling + +However, VSI reconfiguration executed during reset involves memory +allocation one more time, without prior releasing already allocated +resources. This led to the memory leak with the following signature: + +[root@os-delivery ~]# cat /sys/kernel/debug/kmemleak +unreferenced object 0xff3c1ca7252e6000 (size 8192): + comm "kworker/0:0", pid 8, jiffies 4296833052 + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace (crc 0): + [] __kmalloc_cache_noprof+0x275/0x340 + [] ice_init_arfs+0x3a/0xe0 [ice] + [] ice_vsi_cfg_def+0x607/0x850 [ice] + [] ice_vsi_setup+0x5b/0x130 [ice] + [] ice_init+0x1c1/0x460 [ice] + [] ice_probe+0x2af/0x520 [ice] + [] local_pci_probe+0x43/0xa0 + [] work_for_cpu_fn+0x13/0x20 + [] process_one_work+0x179/0x390 + [] worker_thread+0x239/0x340 + [] kthread+0xcc/0x100 + [] ret_from_fork+0x2d/0x50 + [] ret_from_fork_asm+0x1a/0x30 + ... + +Fixes: 28bf26724fdb ("ice: Implement aRFS") +Reviewed-by: Michal Swiatkowski +Signed-off-by: Grzegorz Nitka +Reviewed-by: Simon Horman +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_arfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c +index fba178e076009..79074f041e39b 100644 +--- a/drivers/net/ethernet/intel/ice/ice_arfs.c ++++ b/drivers/net/ethernet/intel/ice/ice_arfs.c +@@ -510,7 +510,7 @@ void ice_init_arfs(struct ice_vsi *vsi) + struct hlist_head *arfs_fltr_list; + unsigned int i; + +- if (!vsi || vsi->type != ICE_VSI_PF) ++ if (!vsi || vsi->type != ICE_VSI_PF || ice_is_arfs_active(vsi)) + return; + + arfs_fltr_list = kcalloc(ICE_MAX_ARFS_LIST, sizeof(*arfs_fltr_list), +-- +2.39.5 + diff --git a/queue-6.1/ipvs-prevent-integer-overflow-in-do_ip_vs_get_ctl.patch b/queue-6.1/ipvs-prevent-integer-overflow-in-do_ip_vs_get_ctl.patch new file mode 100644 index 0000000000..588e647fff --- /dev/null +++ b/queue-6.1/ipvs-prevent-integer-overflow-in-do_ip_vs_get_ctl.patch @@ -0,0 +1,68 @@ +From 61cb1ada1ee4018a596ef657afea0b24cd22c96a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 10:45:53 +0300 +Subject: ipvs: prevent integer overflow in do_ip_vs_get_ctl() + +From: Dan Carpenter + +[ Upstream commit 80b78c39eb86e6b55f56363b709eb817527da5aa ] + +The get->num_services variable is an unsigned int which is controlled by +the user. The struct_size() function ensures that the size calculation +does not overflow an unsigned long, however, we are saving the result to +an int so the calculation can overflow. + +Both "len" and "get->num_services" come from the user. This check is +just a sanity check to help the user and ensure they are using the API +correctly. An integer overflow here is not a big deal. This has no +security impact. + +Save the result from struct_size() type size_t to fix this integer +overflow bug. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Dan Carpenter +Acked-by: Julian Anastasov +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_ctl.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index 18e37b32a5d61..6cc50f05c46c1 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -2854,12 +2854,12 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) + case IP_VS_SO_GET_SERVICES: + { + struct ip_vs_get_services *get; +- int size; ++ size_t size; + + get = (struct ip_vs_get_services *)arg; + size = struct_size(get, entrytable, get->num_services); + if (*len != size) { +- pr_err("length: %u != %u\n", *len, size); ++ pr_err("length: %u != %zu\n", *len, size); + ret = -EINVAL; + goto out; + } +@@ -2895,12 +2895,12 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) + case IP_VS_SO_GET_DESTS: + { + struct ip_vs_get_dests *get; +- int size; ++ size_t size; + + get = (struct ip_vs_get_dests *)arg; + size = struct_size(get, entrytable, get->num_dests); + if (*len != size) { +- pr_err("length: %u != %u\n", *len, size); ++ pr_err("length: %u != %zu\n", *len, size); + ret = -EINVAL; + goto out; + } +-- +2.39.5 + diff --git a/queue-6.1/net-dsa-mv88e6xxx-verify-after-atu-load-ops.patch b/queue-6.1/net-dsa-mv88e6xxx-verify-after-atu-load-ops.patch new file mode 100644 index 0000000000..d684d1079d --- /dev/null +++ b/queue-6.1/net-dsa-mv88e6xxx-verify-after-atu-load-ops.patch @@ -0,0 +1,137 @@ +From f669097527883530a45ec025c13425dc44fc6ebe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 12:23:05 -0500 +Subject: net: dsa: mv88e6xxx: Verify after ATU Load ops + +From: Joseph Huang + +[ Upstream commit dc5340c3133a3ebe54853fd299116149e528cfaa ] + +ATU Load operations could fail silently if there's not enough space +on the device to hold the new entry. When this happens, the symptom +depends on the unknown flood settings. If unknown multicast flood is +disabled, the multicast packets are dropped when the ATU table is +full. If unknown multicast flood is enabled, the multicast packets +will be flooded to all ports. Either way, IGMP snooping is broken +when the ATU Load operation fails silently. + +Do a Read-After-Write verification after each fdb/mdb add operation +to make sure that the operation was really successful, and return +-ENOSPC otherwise. + +Fixes: defb05b9b9b4 ("net: dsa: mv88e6xxx: Add support for fdb_add, fdb_del, and fdb_getnext") +Signed-off-by: Joseph Huang +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250306172306.3859214-1-Joseph.Huang@garmin.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/mv88e6xxx/chip.c | 59 ++++++++++++++++++++++++++------ + 1 file changed, 48 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index d94b46316a117..af0565c3a364c 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -2107,13 +2107,11 @@ mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, + return err; + } + +-static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, +- const unsigned char *addr, u16 vid, +- u8 state) ++static int mv88e6xxx_port_db_get(struct mv88e6xxx_chip *chip, ++ const unsigned char *addr, u16 vid, ++ u16 *fid, struct mv88e6xxx_atu_entry *entry) + { +- struct mv88e6xxx_atu_entry entry; + struct mv88e6xxx_vtu_entry vlan; +- u16 fid; + int err; + + /* Ports have two private address databases: one for when the port is +@@ -2124,7 +2122,7 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, + * VLAN ID into the port's database used for VLAN-unaware bridging. + */ + if (vid == 0) { +- fid = MV88E6XXX_FID_BRIDGED; ++ *fid = MV88E6XXX_FID_BRIDGED; + } else { + err = mv88e6xxx_vtu_get(chip, vid, &vlan); + if (err) +@@ -2134,14 +2132,39 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, + if (!vlan.valid) + return -EOPNOTSUPP; + +- fid = vlan.fid; ++ *fid = vlan.fid; + } + +- entry.state = 0; +- ether_addr_copy(entry.mac, addr); +- eth_addr_dec(entry.mac); ++ entry->state = 0; ++ ether_addr_copy(entry->mac, addr); ++ eth_addr_dec(entry->mac); ++ ++ return mv88e6xxx_g1_atu_getnext(chip, *fid, entry); ++} ++ ++static bool mv88e6xxx_port_db_find(struct mv88e6xxx_chip *chip, ++ const unsigned char *addr, u16 vid) ++{ ++ struct mv88e6xxx_atu_entry entry; ++ u16 fid; ++ int err; + +- err = mv88e6xxx_g1_atu_getnext(chip, fid, &entry); ++ err = mv88e6xxx_port_db_get(chip, addr, vid, &fid, &entry); ++ if (err) ++ return false; ++ ++ return entry.state && ether_addr_equal(entry.mac, addr); ++} ++ ++static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, ++ const unsigned char *addr, u16 vid, ++ u8 state) ++{ ++ struct mv88e6xxx_atu_entry entry; ++ u16 fid; ++ int err; ++ ++ err = mv88e6xxx_port_db_get(chip, addr, vid, &fid, &entry); + if (err) + return err; + +@@ -2739,6 +2762,13 @@ static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, + mv88e6xxx_reg_lock(chip); + err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, + MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC); ++ if (err) ++ goto out; ++ ++ if (!mv88e6xxx_port_db_find(chip, addr, vid)) ++ err = -ENOSPC; ++ ++out: + mv88e6xxx_reg_unlock(chip); + + return err; +@@ -6502,6 +6532,13 @@ static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port, + mv88e6xxx_reg_lock(chip); + err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, + MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC); ++ if (err) ++ goto out; ++ ++ if (!mv88e6xxx_port_db_find(chip, mdb->addr, mdb->vid)) ++ err = -ENOSPC; ++ ++out: + mv88e6xxx_reg_unlock(chip); + + return err; +-- +2.39.5 + diff --git a/queue-6.1/net-mctp-i2c-copy-headers-if-cloned.patch b/queue-6.1/net-mctp-i2c-copy-headers-if-cloned.patch new file mode 100644 index 0000000000..670297358a --- /dev/null +++ b/queue-6.1/net-mctp-i2c-copy-headers-if-cloned.patch @@ -0,0 +1,47 @@ +From 003ecdf5f8fb65e3b023adb05610b422471f7f46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 10:33:20 +0800 +Subject: net: mctp i2c: Copy headers if cloned + +From: Matt Johnston + +[ Upstream commit df8ce77ba8b7c012a3edd1ca7368b46831341466 ] + +Use skb_cow_head() prior to modifying the TX SKB. This is necessary +when the SKB has been cloned, to avoid modifying other shared clones. + +Signed-off-by: Matt Johnston +Fixes: f5b8abf9fc3d ("mctp i2c: MCTP I2C binding driver") +Link: https://patch.msgid.link/20250306-matt-mctp-i2c-cow-v1-1-293827212681@codeconstruct.com.au +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/mctp/mctp-i2c.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/mctp/mctp-i2c.c b/drivers/net/mctp/mctp-i2c.c +index 7635a8b3c35cd..17619d011689f 100644 +--- a/drivers/net/mctp/mctp-i2c.c ++++ b/drivers/net/mctp/mctp-i2c.c +@@ -543,6 +543,7 @@ static int mctp_i2c_header_create(struct sk_buff *skb, struct net_device *dev, + struct mctp_i2c_hdr *hdr; + struct mctp_hdr *mhdr; + u8 lldst, llsrc; ++ int rc; + + if (len > MCTP_I2C_MAXMTU) + return -EMSGSIZE; +@@ -553,6 +554,10 @@ static int mctp_i2c_header_create(struct sk_buff *skb, struct net_device *dev, + lldst = *((u8 *)daddr); + llsrc = *((u8 *)saddr); + ++ rc = skb_cow_head(skb, sizeof(struct mctp_i2c_hdr)); ++ if (rc) ++ return rc; ++ + skb_push(skb, sizeof(struct mctp_i2c_hdr)); + skb_reset_mac_header(skb); + hdr = (void *)skb_mac_header(skb); +-- +2.39.5 + diff --git a/queue-6.1/net-mlx5-bridge-fix-the-crash-caused-by-lag-state-ch.patch b/queue-6.1/net-mlx5-bridge-fix-the-crash-caused-by-lag-state-ch.patch new file mode 100644 index 0000000000..9631cdc474 --- /dev/null +++ b/queue-6.1/net-mlx5-bridge-fix-the-crash-caused-by-lag-state-ch.patch @@ -0,0 +1,129 @@ +From 66fb6e8c1942a948a3694af636817cf059aaf946 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 00:01:43 +0200 +Subject: net/mlx5: Bridge, fix the crash caused by LAG state check + +From: Jianbo Liu + +[ Upstream commit 4b8eeed4fb105770ce6dc84a2c6ef953c7b71cbb ] + +When removing LAG device from bridge, NETDEV_CHANGEUPPER event is +triggered. Driver finds the lower devices (PFs) to flush all the +offloaded entries. And mlx5_lag_is_shared_fdb is checked, it returns +false if one of PF is unloaded. In such case, +mlx5_esw_bridge_lag_rep_get() and its caller return NULL, instead of +the alive PF, and the flush is skipped. + +Besides, the bridge fdb entry's lastuse is updated in mlx5 bridge +event handler. But this SWITCHDEV_FDB_ADD_TO_BRIDGE event can be +ignored in this case because the upper interface for bond is deleted, +and the entry will never be aged because lastuse is never updated. + +To make things worse, as the entry is alive, mlx5 bridge workqueue +keeps sending that event, which is then handled by kernel bridge +notifier. It causes the following crash when accessing the passed bond +netdev which is already destroyed. + +To fix this issue, remove such checks. LAG state is already checked in +commit 15f8f168952f ("net/mlx5: Bridge, verify LAG state when adding +bond to bridge"), driver still need to skip offload if LAG becomes +invalid state after initialization. + + Oops: stack segment: 0000 [#1] SMP + CPU: 3 UID: 0 PID: 23695 Comm: kworker/u40:3 Tainted: G OE 6.11.0_mlnx #1 + Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 + Workqueue: mlx5_bridge_wq mlx5_esw_bridge_update_work [mlx5_core] + RIP: 0010:br_switchdev_event+0x2c/0x110 [bridge] + Code: 44 00 00 48 8b 02 48 f7 00 00 02 00 00 74 69 41 54 55 53 48 83 ec 08 48 8b a8 08 01 00 00 48 85 ed 74 4a 48 83 fe 02 48 89 d3 <4c> 8b 65 00 74 23 76 49 48 83 fe 05 74 7e 48 83 fe 06 75 2f 0f b7 + RSP: 0018:ffffc900092cfda0 EFLAGS: 00010297 + RAX: ffff888123bfe000 RBX: ffffc900092cfe08 RCX: 00000000ffffffff + RDX: ffffc900092cfe08 RSI: 0000000000000001 RDI: ffffffffa0c585f0 + RBP: 6669746f6e690a30 R08: 0000000000000000 R09: ffff888123ae92c8 + R10: 0000000000000000 R11: fefefefefefefeff R12: ffff888123ae9c60 + R13: 0000000000000001 R14: ffffc900092cfe08 R15: 0000000000000000 + FS: 0000000000000000(0000) GS:ffff88852c980000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007f15914c8734 CR3: 0000000002830005 CR4: 0000000000770ef0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 55555554 + Call Trace: + + ? __die_body+0x1a/0x60 + ? die+0x38/0x60 + ? do_trap+0x10b/0x120 + ? do_error_trap+0x64/0xa0 + ? exc_stack_segment+0x33/0x50 + ? asm_exc_stack_segment+0x22/0x30 + ? br_switchdev_event+0x2c/0x110 [bridge] + ? sched_balance_newidle.isra.149+0x248/0x390 + notifier_call_chain+0x4b/0xa0 + atomic_notifier_call_chain+0x16/0x20 + mlx5_esw_bridge_update+0xec/0x170 [mlx5_core] + mlx5_esw_bridge_update_work+0x19/0x40 [mlx5_core] + process_scheduled_works+0x81/0x390 + worker_thread+0x106/0x250 + ? bh_worker+0x110/0x110 + kthread+0xb7/0xe0 + ? kthread_park+0x80/0x80 + ret_from_fork+0x2d/0x50 + ? kthread_park+0x80/0x80 + ret_from_fork_asm+0x11/0x20 + + +Fixes: ff9b7521468b ("net/mlx5: Bridge, support LAG") +Signed-off-by: Jianbo Liu +Reviewed-by: Vlad Buslov +Signed-off-by: Tariq Toukan +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/1741644104-97767-6-git-send-email-tariqt@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en/rep/bridge.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c +index ce85b48d327da..6748c92941b1e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c +@@ -48,15 +48,10 @@ mlx5_esw_bridge_lag_rep_get(struct net_device *dev, struct mlx5_eswitch *esw) + struct list_head *iter; + + netdev_for_each_lower_dev(dev, lower, iter) { +- struct mlx5_core_dev *mdev; +- struct mlx5e_priv *priv; +- + if (!mlx5e_eswitch_rep(lower)) + continue; + +- priv = netdev_priv(lower); +- mdev = priv->mdev; +- if (mlx5_lag_is_shared_fdb(mdev) && mlx5_esw_bridge_dev_same_esw(lower, esw)) ++ if (mlx5_esw_bridge_dev_same_esw(lower, esw)) + return lower; + } + +@@ -121,7 +116,7 @@ static bool mlx5_esw_bridge_is_local(struct net_device *dev, struct net_device * + priv = netdev_priv(rep); + mdev = priv->mdev; + if (netif_is_lag_master(dev)) +- return mlx5_lag_is_shared_fdb(mdev) && mlx5_lag_is_master(mdev); ++ return mlx5_lag_is_master(mdev); + return true; + } + +@@ -436,6 +431,9 @@ static int mlx5_esw_bridge_switchdev_event(struct notifier_block *nb, + if (!rep) + return NOTIFY_DONE; + ++ if (netif_is_lag_master(dev) && !mlx5_lag_is_shared_fdb(esw->dev)) ++ return NOTIFY_DONE; ++ + switch (event) { + case SWITCHDEV_FDB_ADD_TO_BRIDGE: + fdb_info = container_of(info, +-- +2.39.5 + diff --git a/queue-6.1/net-mlx5-handle-errors-in-mlx5_chains_create_table.patch b/queue-6.1/net-mlx5-handle-errors-in-mlx5_chains_create_table.patch new file mode 100644 index 0000000000..ea98bf5915 --- /dev/null +++ b/queue-6.1/net-mlx5-handle-errors-in-mlx5_chains_create_table.patch @@ -0,0 +1,46 @@ +From 87815bb530014f9214023910dea2856290d22661 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Mar 2025 10:18:20 +0800 +Subject: net/mlx5: handle errors in mlx5_chains_create_table() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Wentao Liang + +[ Upstream commit eab0396353be1c778eba1c0b5180176f04dd21ce ] + +In mlx5_chains_create_table(), the return value of mlx5_get_fdb_sub_ns() +and mlx5_get_flow_namespace() must be checked to prevent NULL pointer +dereferences. If either function fails, the function should log error +message with mlx5_core_warn() and return error pointer. + +Fixes: 39ac237ce009 ("net/mlx5: E-Switch, Refactor chains and priorities") +Signed-off-by: Wentao Liang +Reviewed-by: Tariq Toukan +Link: https://patch.msgid.link/20250307021820.2646-1-vulab@iscas.ac.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +index df58cba37930a..64c1071bece8d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +@@ -196,6 +196,11 @@ mlx5_chains_create_table(struct mlx5_fs_chains *chains, + ns = mlx5_get_flow_namespace(chains->dev, chains->ns); + } + ++ if (!ns) { ++ mlx5_core_warn(chains->dev, "Failed to get flow namespace\n"); ++ return ERR_PTR(-EOPNOTSUPP); ++ } ++ + ft_attr.autogroup.num_reserved_entries = 2; + ft_attr.autogroup.max_num_groups = chains->group_num; + ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr); +-- +2.39.5 + diff --git a/queue-6.1/net-mlx5e-prevent-bridge-link-show-failure-for-non-e.patch b/queue-6.1/net-mlx5e-prevent-bridge-link-show-failure-for-non-e.patch new file mode 100644 index 0000000000..83adb98cf0 --- /dev/null +++ b/queue-6.1/net-mlx5e-prevent-bridge-link-show-failure-for-non-e.patch @@ -0,0 +1,53 @@ +From f5ba2ed737f0a7544535697c5f6a3de18ac9a412 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 00:01:44 +0200 +Subject: net/mlx5e: Prevent bridge link show failure for non-eswitch-allowed + devices + +From: Carolina Jubran + +[ Upstream commit e92df790d07a8eea873efcb84776e7b71f81c7d5 ] + +mlx5_eswitch_get_vepa returns -EPERM if the device lacks +eswitch_manager capability, blocking mlx5e_bridge_getlink from +retrieving VEPA mode. Since mlx5e_bridge_getlink implements +ndo_bridge_getlink, returning -EPERM causes bridge link show to fail +instead of skipping devices without this capability. + +To avoid this, return -EOPNOTSUPP from mlx5e_bridge_getlink when +mlx5_eswitch_get_vepa fails, ensuring the command continues processing +other devices while ignoring those without the necessary capability. + +Fixes: 4b89251de024 ("net/mlx5: Support ndo bridge_setlink and getlink") +Signed-off-by: Carolina Jubran +Reviewed-by: Jianbo Liu +Signed-off-by: Tariq Toukan +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/1741644104-97767-7-git-send-email-tariqt@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 8ee6a81b42b47..f520949b2024c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -4791,11 +4791,9 @@ static int mlx5e_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, + struct mlx5e_priv *priv = netdev_priv(dev); + struct mlx5_core_dev *mdev = priv->mdev; + u8 mode, setting; +- int err; + +- err = mlx5_eswitch_get_vepa(mdev->priv.eswitch, &setting); +- if (err) +- return err; ++ if (mlx5_eswitch_get_vepa(mdev->priv.eswitch, &setting)) ++ return -EOPNOTSUPP; + mode = setting ? BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB; + return ndo_dflt_bridge_getlink(skb, pid, seq, dev, + mode, +-- +2.39.5 + diff --git a/queue-6.1/net-openvswitch-remove-misbehaving-actions-length-ch.patch b/queue-6.1/net-openvswitch-remove-misbehaving-actions-length-ch.patch new file mode 100644 index 0000000000..48a6ee81b7 --- /dev/null +++ b/queue-6.1/net-openvswitch-remove-misbehaving-actions-length-ch.patch @@ -0,0 +1,154 @@ +From 467be6394afc4127b2a3b9beb6d1163488428dda Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Mar 2025 01:45:59 +0100 +Subject: net: openvswitch: remove misbehaving actions length check + +From: Ilya Maximets + +[ Upstream commit a1e64addf3ff9257b45b78bc7d743781c3f41340 ] + +The actions length check is unreliable and produces different results +depending on the initial length of the provided netlink attribute and +the composition of the actual actions inside of it. For example, a +user can add 4088 empty clone() actions without triggering -EMSGSIZE, +on attempt to add 4089 such actions the operation will fail with the +-EMSGSIZE verdict. However, if another 16 KB of other actions will +be *appended* to the previous 4089 clone() actions, the check passes +and the flow is successfully installed into the openvswitch datapath. + +The reason for a such a weird behavior is the way memory is allocated. +When ovs_flow_cmd_new() is invoked, it calls ovs_nla_copy_actions(), +that in turn calls nla_alloc_flow_actions() with either the actual +length of the user-provided actions or the MAX_ACTIONS_BUFSIZE. The +function adds the size of the sw_flow_actions structure and then the +actually allocated memory is rounded up to the closest power of two. + +So, if the user-provided actions are larger than MAX_ACTIONS_BUFSIZE, +then MAX_ACTIONS_BUFSIZE + sizeof(*sfa) rounded up is 32K + 24 -> 64K. +Later, while copying individual actions, we look at ksize(), which is +64K, so this way the MAX_ACTIONS_BUFSIZE check is not actually +triggered and the user can easily allocate almost 64 KB of actions. + +However, when the initial size is less than MAX_ACTIONS_BUFSIZE, but +the actions contain ones that require size increase while copying +(such as clone() or sample()), then the limit check will be performed +during the reserve_sfa_size() and the user will not be allowed to +create actions that yield more than 32 KB internally. + +This is one part of the problem. The other part is that it's not +actually possible for the userspace application to know beforehand +if the particular set of actions will be rejected or not. + +Certain actions require more space in the internal representation, +e.g. an empty clone() takes 4 bytes in the action list passed in by +the user, but it takes 12 bytes in the internal representation due +to an extra nested attribute, and some actions require less space in +the internal representations, e.g. set(tunnel(..)) normally takes +64+ bytes in the action list provided by the user, but only needs to +store a single pointer in the internal implementation, since all the +data is stored in the tunnel_info structure instead. + +And the action size limit is applied to the internal representation, +not to the action list passed by the user. So, it's not possible for +the userpsace application to predict if the certain combination of +actions will be rejected or not, because it is not possible for it to +calculate how much space these actions will take in the internal +representation without knowing kernel internals. + +All that is causing random failures in ovs-vswitchd in userspace and +inability to handle certain traffic patterns as a result. For example, +it is reported that adding a bit more than a 1100 VMs in an OpenStack +setup breaks the network due to OVS not being able to handle ARP +traffic anymore in some cases (it tries to install a proper datapath +flow, but the kernel rejects it with -EMSGSIZE, even though the action +list isn't actually that large.) + +Kernel behavior must be consistent and predictable in order for the +userspace application to use it in a reasonable way. ovs-vswitchd has +a mechanism to re-direct parts of the traffic and partially handle it +in userspace if the required action list is oversized, but that doesn't +work properly if we can't actually tell if the action list is oversized +or not. + +Solution for this is to check the size of the user-provided actions +instead of the internal representation. This commit just removes the +check from the internal part because there is already an implicit size +check imposed by the netlink protocol. The attribute can't be larger +than 64 KB. Realistically, we could reduce the limit to 32 KB, but +we'll be risking to break some existing setups that rely on the fact +that it's possible to create nearly 64 KB action lists today. + +Vast majority of flows in real setups are below 100-ish bytes. So +removal of the limit will not change real memory consumption on the +system. The absolutely worst case scenario is if someone adds a flow +with 64 KB of empty clone() actions. That will yield a 192 KB in the +internal representation consuming 256 KB block of memory. However, +that list of actions is not meaningful and also a no-op. Real world +very large action lists (that can occur for a rare cases of BUM +traffic handling) are unlikely to contain a large number of clones and +will likely have a lot of tunnel attributes making the internal +representation comparable in size to the original action list. +So, it should be fine to just remove the limit. + +Commit in the 'Fixes' tag is the first one that introduced the +difference between internal representation and the user-provided action +lists, but there were many more afterwards that lead to the situation +we have today. + +Fixes: 7d5437c709de ("openvswitch: Add tunneling interface.") +Signed-off-by: Ilya Maximets +Reviewed-by: Aaron Conole +Link: https://patch.msgid.link/20250308004609.2881861-1-i.maximets@ovn.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/openvswitch/flow_netlink.c | 15 +-------------- + 1 file changed, 1 insertion(+), 14 deletions(-) + +diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c +index e3c85ceb1f0a5..5ebbec656895e 100644 +--- a/net/openvswitch/flow_netlink.c ++++ b/net/openvswitch/flow_netlink.c +@@ -2302,14 +2302,10 @@ int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb) + OVS_FLOW_ATTR_MASK, true, skb); + } + +-#define MAX_ACTIONS_BUFSIZE (32 * 1024) +- + static struct sw_flow_actions *nla_alloc_flow_actions(int size) + { + struct sw_flow_actions *sfa; + +- WARN_ON_ONCE(size > MAX_ACTIONS_BUFSIZE); +- + sfa = kmalloc(kmalloc_size_roundup(sizeof(*sfa) + size), GFP_KERNEL); + if (!sfa) + return ERR_PTR(-ENOMEM); +@@ -2465,15 +2461,6 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, + + new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2); + +- if (new_acts_size > MAX_ACTIONS_BUFSIZE) { +- if ((next_offset + req_size) > MAX_ACTIONS_BUFSIZE) { +- OVS_NLERR(log, "Flow action size exceeds max %u", +- MAX_ACTIONS_BUFSIZE); +- return ERR_PTR(-EMSGSIZE); +- } +- new_acts_size = MAX_ACTIONS_BUFSIZE; +- } +- + acts = nla_alloc_flow_actions(new_acts_size); + if (IS_ERR(acts)) + return (void *)acts; +@@ -3492,7 +3479,7 @@ int ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, + int err; + u32 mpls_label_count = 0; + +- *sfa = nla_alloc_flow_actions(min(nla_len(attr), MAX_ACTIONS_BUFSIZE)); ++ *sfa = nla_alloc_flow_actions(nla_len(attr)); + if (IS_ERR(*sfa)) + return PTR_ERR(*sfa); + +-- +2.39.5 + diff --git a/queue-6.1/net-switchdev-convert-blocking-notification-chain-to.patch b/queue-6.1/net-switchdev-convert-blocking-notification-chain-to.patch new file mode 100644 index 0000000000..22a7f615de --- /dev/null +++ b/queue-6.1/net-switchdev-convert-blocking-notification-chain-to.patch @@ -0,0 +1,150 @@ +From 9db25c7a13523e294137a5adecc9151519b3ea07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 14:15:09 +0200 +Subject: net: switchdev: Convert blocking notification chain to a raw one + +From: Amit Cohen + +[ Upstream commit 62531a1effa87bdab12d5104015af72e60d926ff ] + +A blocking notification chain uses a read-write semaphore to protect the +integrity of the chain. The semaphore is acquired for writing when +adding / removing notifiers to / from the chain and acquired for reading +when traversing the chain and informing notifiers about an event. + +In case of the blocking switchdev notification chain, recursive +notifications are possible which leads to the semaphore being acquired +twice for reading and to lockdep warnings being generated [1]. + +Specifically, this can happen when the bridge driver processes a +SWITCHDEV_BRPORT_UNOFFLOADED event which causes it to emit notifications +about deferred events when calling switchdev_deferred_process(). + +Fix this by converting the notification chain to a raw notification +chain in a similar fashion to the netdev notification chain. Protect +the chain using the RTNL mutex by acquiring it when modifying the chain. +Events are always informed under the RTNL mutex, but add an assertion in +call_switchdev_blocking_notifiers() to make sure this is not violated in +the future. + +Maintain the "blocking" prefix as events are always emitted from process +context and listeners are allowed to block. + +[1]: +WARNING: possible recursive locking detected +6.14.0-rc4-custom-g079270089484 #1 Not tainted +-------------------------------------------- +ip/52731 is trying to acquire lock: +ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0 + +but task is already holding lock: +ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0 + +other info that might help us debug this: +Possible unsafe locking scenario: +CPU0 +---- +lock((switchdev_blocking_notif_chain).rwsem); +lock((switchdev_blocking_notif_chain).rwsem); + +*** DEADLOCK *** +May be due to missing lock nesting notation +3 locks held by ip/52731: + #0: ffffffff84f795b0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x727/0x1dc0 + #1: ffffffff8731f628 (&net->rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x790/0x1dc0 + #2: ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0 + +stack backtrace: +... +? __pfx_down_read+0x10/0x10 +? __pfx_mark_lock+0x10/0x10 +? __pfx_switchdev_port_attr_set_deferred+0x10/0x10 +blocking_notifier_call_chain+0x58/0xa0 +switchdev_port_attr_notify.constprop.0+0xb3/0x1b0 +? __pfx_switchdev_port_attr_notify.constprop.0+0x10/0x10 +? mark_held_locks+0x94/0xe0 +? switchdev_deferred_process+0x11a/0x340 +switchdev_port_attr_set_deferred+0x27/0xd0 +switchdev_deferred_process+0x164/0x340 +br_switchdev_port_unoffload+0xc8/0x100 [bridge] +br_switchdev_blocking_event+0x29f/0x580 [bridge] +notifier_call_chain+0xa2/0x440 +blocking_notifier_call_chain+0x6e/0xa0 +switchdev_bridge_port_unoffload+0xde/0x1a0 +... + +Fixes: f7a70d650b0b6 ("net: bridge: switchdev: Ensure deferred event delivery on unoffload") +Signed-off-by: Amit Cohen +Reviewed-by: Ido Schimmel +Reviewed-by: Simon Horman +Reviewed-by: Vladimir Oltean +Tested-by: Vladimir Oltean +Link: https://patch.msgid.link/20250305121509.631207-1-amcohen@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/switchdev/switchdev.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c +index 2e14d4c37e2dc..9aec24490e8fd 100644 +--- a/net/switchdev/switchdev.c ++++ b/net/switchdev/switchdev.c +@@ -381,7 +381,7 @@ bool switchdev_port_obj_act_is_deferred(struct net_device *dev, + EXPORT_SYMBOL_GPL(switchdev_port_obj_act_is_deferred); + + static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain); +-static BLOCKING_NOTIFIER_HEAD(switchdev_blocking_notif_chain); ++static RAW_NOTIFIER_HEAD(switchdev_blocking_notif_chain); + + /** + * register_switchdev_notifier - Register notifier +@@ -427,17 +427,27 @@ EXPORT_SYMBOL_GPL(call_switchdev_notifiers); + + int register_switchdev_blocking_notifier(struct notifier_block *nb) + { +- struct blocking_notifier_head *chain = &switchdev_blocking_notif_chain; ++ struct raw_notifier_head *chain = &switchdev_blocking_notif_chain; ++ int err; ++ ++ rtnl_lock(); ++ err = raw_notifier_chain_register(chain, nb); ++ rtnl_unlock(); + +- return blocking_notifier_chain_register(chain, nb); ++ return err; + } + EXPORT_SYMBOL_GPL(register_switchdev_blocking_notifier); + + int unregister_switchdev_blocking_notifier(struct notifier_block *nb) + { +- struct blocking_notifier_head *chain = &switchdev_blocking_notif_chain; ++ struct raw_notifier_head *chain = &switchdev_blocking_notif_chain; ++ int err; + +- return blocking_notifier_chain_unregister(chain, nb); ++ rtnl_lock(); ++ err = raw_notifier_chain_unregister(chain, nb); ++ rtnl_unlock(); ++ ++ return err; + } + EXPORT_SYMBOL_GPL(unregister_switchdev_blocking_notifier); + +@@ -445,10 +455,11 @@ int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev, + struct switchdev_notifier_info *info, + struct netlink_ext_ack *extack) + { ++ ASSERT_RTNL(); + info->dev = dev; + info->extack = extack; +- return blocking_notifier_call_chain(&switchdev_blocking_notif_chain, +- val, info); ++ return raw_notifier_call_chain(&switchdev_blocking_notif_chain, ++ val, info); + } + EXPORT_SYMBOL_GPL(call_switchdev_blocking_notifiers); + +-- +2.39.5 + diff --git a/queue-6.1/net_sched-prevent-creation-of-classes-with-tc_h_root.patch b/queue-6.1/net_sched-prevent-creation-of-classes-with-tc_h_root.patch new file mode 100644 index 0000000000..4d34da399e --- /dev/null +++ b/queue-6.1/net_sched-prevent-creation-of-classes-with-tc_h_root.patch @@ -0,0 +1,50 @@ +From b01a0e73b86d509f729b9ea5787f02f1660676ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 15:23:54 -0800 +Subject: net_sched: Prevent creation of classes with TC_H_ROOT + +From: Cong Wang + +[ Upstream commit 0c3057a5a04d07120b3d0ec9c79568fceb9c921e ] + +The function qdisc_tree_reduce_backlog() uses TC_H_ROOT as a termination +condition when traversing up the qdisc tree to update parent backlog +counters. However, if a class is created with classid TC_H_ROOT, the +traversal terminates prematurely at this class instead of reaching the +actual root qdisc, causing parent statistics to be incorrectly maintained. +In case of DRR, this could lead to a crash as reported by Mingi Cho. + +Prevent the creation of any Qdisc class with classid TC_H_ROOT +(0xFFFFFFFF) across all qdisc types, as suggested by Jamal. + +Reported-by: Mingi Cho +Signed-off-by: Cong Wang +Reviewed-by: Simon Horman +Fixes: 066a3b5b2346 ("[NET_SCHED] sch_api: fix qdisc_tree_decrease_qlen() loop") +Link: https://patch.msgid.link/20250306232355.93864-2-xiyou.wangcong@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_api.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index cb379849c51a4..c395e7a98232d 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -2200,6 +2200,12 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, + return -EOPNOTSUPP; + } + ++ /* Prevent creation of traffic classes with classid TC_H_ROOT */ ++ if (clid == TC_H_ROOT) { ++ NL_SET_ERR_MSG(extack, "Cannot create traffic class with classid TC_H_ROOT"); ++ return -EINVAL; ++ } ++ + new_cl = cl; + err = -EOPNOTSUPP; + if (cops->change) +-- +2.39.5 + diff --git a/queue-6.1/netfilter-nf_conncount-fully-initialize-struct-nf_co.patch b/queue-6.1/netfilter-nf_conncount-fully-initialize-struct-nf_co.patch new file mode 100644 index 0000000000..62080e78fc --- /dev/null +++ b/queue-6.1/netfilter-nf_conncount-fully-initialize-struct-nf_co.patch @@ -0,0 +1,129 @@ +From a7dc9395605657ba8eaa7370f4a74ae0ca0ef5b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Mar 2025 17:07:38 +0900 +Subject: netfilter: nf_conncount: Fully initialize struct nf_conncount_tuple + in insert_tree() + +From: Kohei Enju + +[ Upstream commit d653bfeb07ebb3499c403404c21ac58a16531607 ] + +Since commit b36e4523d4d5 ("netfilter: nf_conncount: fix garbage +collection confirm race"), `cpu` and `jiffies32` were introduced to +the struct nf_conncount_tuple. + +The commit made nf_conncount_add() initialize `conn->cpu` and +`conn->jiffies32` when allocating the struct. +In contrast, count_tree() was not changed to initialize them. + +By commit 34848d5c896e ("netfilter: nf_conncount: Split insert and +traversal"), count_tree() was split and the relevant allocation +code now resides in insert_tree(). +Initialize `conn->cpu` and `conn->jiffies32` in insert_tree(). + +BUG: KMSAN: uninit-value in find_or_evict net/netfilter/nf_conncount.c:117 [inline] +BUG: KMSAN: uninit-value in __nf_conncount_add+0xd9c/0x2850 net/netfilter/nf_conncount.c:143 + find_or_evict net/netfilter/nf_conncount.c:117 [inline] + __nf_conncount_add+0xd9c/0x2850 net/netfilter/nf_conncount.c:143 + count_tree net/netfilter/nf_conncount.c:438 [inline] + nf_conncount_count+0x82f/0x1e80 net/netfilter/nf_conncount.c:521 + connlimit_mt+0x7f6/0xbd0 net/netfilter/xt_connlimit.c:72 + __nft_match_eval net/netfilter/nft_compat.c:403 [inline] + nft_match_eval+0x1a5/0x300 net/netfilter/nft_compat.c:433 + expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline] + nft_do_chain+0x426/0x2290 net/netfilter/nf_tables_core.c:288 + nft_do_chain_ipv4+0x1a5/0x230 net/netfilter/nft_chain_filter.c:23 + nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] + nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626 + nf_hook_slow_list+0x24d/0x860 net/netfilter/core.c:663 + NF_HOOK_LIST include/linux/netfilter.h:350 [inline] + ip_sublist_rcv+0x17b7/0x17f0 net/ipv4/ip_input.c:633 + ip_list_rcv+0x9ef/0xa40 net/ipv4/ip_input.c:669 + __netif_receive_skb_list_ptype net/core/dev.c:5936 [inline] + __netif_receive_skb_list_core+0x15c5/0x1670 net/core/dev.c:5983 + __netif_receive_skb_list net/core/dev.c:6035 [inline] + netif_receive_skb_list_internal+0x1085/0x1700 net/core/dev.c:6126 + netif_receive_skb_list+0x5a/0x460 net/core/dev.c:6178 + xdp_recv_frames net/bpf/test_run.c:280 [inline] + xdp_test_run_batch net/bpf/test_run.c:361 [inline] + bpf_test_run_xdp_live+0x2e86/0x3480 net/bpf/test_run.c:390 + bpf_prog_test_run_xdp+0xf1d/0x1ae0 net/bpf/test_run.c:1316 + bpf_prog_test_run+0x5e5/0xa30 kernel/bpf/syscall.c:4407 + __sys_bpf+0x6aa/0xd90 kernel/bpf/syscall.c:5813 + __do_sys_bpf kernel/bpf/syscall.c:5902 [inline] + __se_sys_bpf kernel/bpf/syscall.c:5900 [inline] + __ia32_sys_bpf+0xa0/0xe0 kernel/bpf/syscall.c:5900 + ia32_sys_call+0x394d/0x4180 arch/x86/include/generated/asm/syscalls_32.h:358 + do_syscall_32_irqs_on arch/x86/entry/common.c:165 [inline] + __do_fast_syscall_32+0xb0/0x110 arch/x86/entry/common.c:387 + do_fast_syscall_32+0x38/0x80 arch/x86/entry/common.c:412 + do_SYSENTER_32+0x1f/0x30 arch/x86/entry/common.c:450 + entry_SYSENTER_compat_after_hwframe+0x84/0x8e + +Uninit was created at: + slab_post_alloc_hook mm/slub.c:4121 [inline] + slab_alloc_node mm/slub.c:4164 [inline] + kmem_cache_alloc_noprof+0x915/0xe10 mm/slub.c:4171 + insert_tree net/netfilter/nf_conncount.c:372 [inline] + count_tree net/netfilter/nf_conncount.c:450 [inline] + nf_conncount_count+0x1415/0x1e80 net/netfilter/nf_conncount.c:521 + connlimit_mt+0x7f6/0xbd0 net/netfilter/xt_connlimit.c:72 + __nft_match_eval net/netfilter/nft_compat.c:403 [inline] + nft_match_eval+0x1a5/0x300 net/netfilter/nft_compat.c:433 + expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline] + nft_do_chain+0x426/0x2290 net/netfilter/nf_tables_core.c:288 + nft_do_chain_ipv4+0x1a5/0x230 net/netfilter/nft_chain_filter.c:23 + nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] + nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626 + nf_hook_slow_list+0x24d/0x860 net/netfilter/core.c:663 + NF_HOOK_LIST include/linux/netfilter.h:350 [inline] + ip_sublist_rcv+0x17b7/0x17f0 net/ipv4/ip_input.c:633 + ip_list_rcv+0x9ef/0xa40 net/ipv4/ip_input.c:669 + __netif_receive_skb_list_ptype net/core/dev.c:5936 [inline] + __netif_receive_skb_list_core+0x15c5/0x1670 net/core/dev.c:5983 + __netif_receive_skb_list net/core/dev.c:6035 [inline] + netif_receive_skb_list_internal+0x1085/0x1700 net/core/dev.c:6126 + netif_receive_skb_list+0x5a/0x460 net/core/dev.c:6178 + xdp_recv_frames net/bpf/test_run.c:280 [inline] + xdp_test_run_batch net/bpf/test_run.c:361 [inline] + bpf_test_run_xdp_live+0x2e86/0x3480 net/bpf/test_run.c:390 + bpf_prog_test_run_xdp+0xf1d/0x1ae0 net/bpf/test_run.c:1316 + bpf_prog_test_run+0x5e5/0xa30 kernel/bpf/syscall.c:4407 + __sys_bpf+0x6aa/0xd90 kernel/bpf/syscall.c:5813 + __do_sys_bpf kernel/bpf/syscall.c:5902 [inline] + __se_sys_bpf kernel/bpf/syscall.c:5900 [inline] + __ia32_sys_bpf+0xa0/0xe0 kernel/bpf/syscall.c:5900 + ia32_sys_call+0x394d/0x4180 arch/x86/include/generated/asm/syscalls_32.h:358 + do_syscall_32_irqs_on arch/x86/entry/common.c:165 [inline] + __do_fast_syscall_32+0xb0/0x110 arch/x86/entry/common.c:387 + do_fast_syscall_32+0x38/0x80 arch/x86/entry/common.c:412 + do_SYSENTER_32+0x1f/0x30 arch/x86/entry/common.c:450 + entry_SYSENTER_compat_after_hwframe+0x84/0x8e + +Reported-by: syzbot+83fed965338b573115f7@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=83fed965338b573115f7 +Fixes: b36e4523d4d5 ("netfilter: nf_conncount: fix garbage collection confirm race") +Signed-off-by: Kohei Enju +Reviewed-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 71869ad466467..6156c0751056c 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -377,6 +377,8 @@ insert_tree(struct net *net, + + conn->tuple = *tuple; + conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; + memcpy(rbconn->key, key, sizeof(u32) * data->keylen); + + nf_conncount_list_init(&rbconn->list); +-- +2.39.5 + diff --git a/queue-6.1/netfilter-nf_conncount-garbage-collection-is-not-ski.patch b/queue-6.1/netfilter-nf_conncount-garbage-collection-is-not-ski.patch new file mode 100644 index 0000000000..914875a069 --- /dev/null +++ b/queue-6.1/netfilter-nf_conncount-garbage-collection-is-not-ski.patch @@ -0,0 +1,55 @@ +From 05c2603b6b9c32b1fd90f54b77c2ffb0b3150011 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 13:32:34 +0000 +Subject: netfilter: nf_conncount: garbage collection is not skipped when + jiffies wrap around + +From: Nicklas Bo Jensen + +[ Upstream commit df08c94baafb001de6cf44bb7098bb557f36c335 ] + +nf_conncount is supposed to skip garbage collection if it has already +run garbage collection in the same jiffy. Unfortunately, this is broken +when jiffies wrap around which this patch fixes. + +The problem is that last_gc in the nf_conncount_list struct is an u32, +but jiffies is an unsigned long which is 8 bytes on my systems. When +those two are compared it only works until last_gc wraps around. + +See bug report: https://bugzilla.netfilter.org/show_bug.cgi?id=1778 +for more details. + +Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") +Signed-off-by: Nicklas Bo Jensen +Reviewed-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 5885810da412f..71869ad466467 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -132,7 +132,7 @@ static int __nf_conncount_add(struct net *net, + struct nf_conn *found_ct; + unsigned int collect = 0; + +- if (time_is_after_eq_jiffies((unsigned long)list->last_gc)) ++ if ((u32)jiffies == list->last_gc) + goto add_new_node; + + /* check the saved connections */ +@@ -234,7 +234,7 @@ bool nf_conncount_gc_list(struct net *net, + bool ret = false; + + /* don't bother if we just did GC */ +- if (time_is_after_eq_jiffies((unsigned long)READ_ONCE(list->last_gc))) ++ if ((u32)jiffies == READ_ONCE(list->last_gc)) + return false; + + /* don't bother if other cpu is already doing GC */ +-- +2.39.5 + diff --git a/queue-6.1/netfilter-nft_ct-use-__refcount_inc-for-per-cpu-nft_.patch b/queue-6.1/netfilter-nft_ct-use-__refcount_inc-for-per-cpu-nft_.patch new file mode 100644 index 0000000000..3a61cc50c4 --- /dev/null +++ b/queue-6.1/netfilter-nft_ct-use-__refcount_inc-for-per-cpu-nft_.patch @@ -0,0 +1,63 @@ +From e745314ccd9456d7e430a3a08bf52240fa15f7e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 17:02:42 +0100 +Subject: netfilter: nft_ct: Use __refcount_inc() for per-CPU + nft_ct_pcpu_template. + +From: Sebastian Andrzej Siewior + +[ Upstream commit 5cfe5612ca9590db69b9be29dc83041dbf001108 ] + +nft_ct_pcpu_template is a per-CPU variable and relies on disabled BH for its +locking. The refcounter is read and if its value is set to one then the +refcounter is incremented and variable is used - otherwise it is already +in use and left untouched. + +Without per-CPU locking in local_bh_disable() on PREEMPT_RT the +read-then-increment operation is not atomic and therefore racy. + +This can be avoided by using unconditionally __refcount_inc() which will +increment counter and return the old value as an atomic operation. +In case the returned counter is not one, the variable is in use and we +need to decrement counter. Otherwise we can use it. + +Use __refcount_inc() instead of read and a conditional increment. + +Fixes: edee4f1e9245 ("netfilter: nft_ct: add zone id set support") +Signed-off-by: Sebastian Andrzej Siewior +Reviewed-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_ct.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c +index 6157f8b4a3cea..3641043ca8cc5 100644 +--- a/net/netfilter/nft_ct.c ++++ b/net/netfilter/nft_ct.c +@@ -240,6 +240,7 @@ static void nft_ct_set_zone_eval(const struct nft_expr *expr, + enum ip_conntrack_info ctinfo; + u16 value = nft_reg_load16(®s->data[priv->sreg]); + struct nf_conn *ct; ++ int oldcnt; + + ct = nf_ct_get(skb, &ctinfo); + if (ct) /* already tracked */ +@@ -260,10 +261,11 @@ static void nft_ct_set_zone_eval(const struct nft_expr *expr, + + ct = this_cpu_read(nft_ct_pcpu_template); + +- if (likely(refcount_read(&ct->ct_general.use) == 1)) { +- refcount_inc(&ct->ct_general.use); ++ __refcount_inc(&ct->ct_general.use, &oldcnt); ++ if (likely(oldcnt == 1)) { + nf_ct_zone_add(ct, &zone); + } else { ++ refcount_dec(&ct->ct_general.use); + /* previous skb got queued to userspace, allocate temporary + * one until percpu template can be reused. + */ +-- +2.39.5 + diff --git a/queue-6.1/netfilter-nft_exthdr-fix-offset-with-ipv4_find_optio.patch b/queue-6.1/netfilter-nft_exthdr-fix-offset-with-ipv4_find_optio.patch new file mode 100644 index 0000000000..3e7181da27 --- /dev/null +++ b/queue-6.1/netfilter-nft_exthdr-fix-offset-with-ipv4_find_optio.patch @@ -0,0 +1,78 @@ +From 41ef1c1381a3bf9c4a906fd60821c986d1348dbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Mar 2025 00:14:36 +0300 +Subject: netfilter: nft_exthdr: fix offset with ipv4_find_option() + +From: Alexey Kashavkin + +[ Upstream commit 6edd78af9506bb182518da7f6feebd75655d9a0e ] + +There is an incorrect calculation in the offset variable which causes +the nft_skb_copy_to_reg() function to always return -EFAULT. Adding the +start variable is redundant. In the __ip_options_compile() function the +correct offset is specified when finding the function. There is no need +to add the size of the iphdr structure to the offset. + +Fixes: dbb5281a1f84 ("netfilter: nf_tables: add support for matching IPv4 options") +Signed-off-by: Alexey Kashavkin +Reviewed-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_exthdr.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c +index de588f7b69c45..60d18bd60d821 100644 +--- a/net/netfilter/nft_exthdr.c ++++ b/net/netfilter/nft_exthdr.c +@@ -86,7 +86,6 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb, + unsigned char optbuf[sizeof(struct ip_options) + 40]; + struct ip_options *opt = (struct ip_options *)optbuf; + struct iphdr *iph, _iph; +- unsigned int start; + bool found = false; + __be32 info; + int optlen; +@@ -94,7 +93,6 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb, + iph = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); + if (!iph) + return -EBADMSG; +- start = sizeof(struct iphdr); + + optlen = iph->ihl * 4 - (int)sizeof(struct iphdr); + if (optlen <= 0) +@@ -104,7 +102,7 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb, + /* Copy the options since __ip_options_compile() modifies + * the options. + */ +- if (skb_copy_bits(skb, start, opt->__data, optlen)) ++ if (skb_copy_bits(skb, sizeof(struct iphdr), opt->__data, optlen)) + return -EBADMSG; + opt->optlen = optlen; + +@@ -119,18 +117,18 @@ static int ipv4_find_option(struct net *net, struct sk_buff *skb, + found = target == IPOPT_SSRR ? opt->is_strictroute : + !opt->is_strictroute; + if (found) +- *offset = opt->srr + start; ++ *offset = opt->srr; + break; + case IPOPT_RR: + if (!opt->rr) + break; +- *offset = opt->rr + start; ++ *offset = opt->rr; + found = true; + break; + case IPOPT_RA: + if (!opt->router_alert) + break; +- *offset = opt->router_alert + start; ++ *offset = opt->router_alert; + found = true; + break; + default: +-- +2.39.5 + diff --git a/queue-6.1/netpoll-hold-rcu-read-lock-in-__netpoll_send_skb.patch b/queue-6.1/netpoll-hold-rcu-read-lock-in-__netpoll_send_skb.patch new file mode 100644 index 0000000000..b5debdb595 --- /dev/null +++ b/queue-6.1/netpoll-hold-rcu-read-lock-in-__netpoll_send_skb.patch @@ -0,0 +1,76 @@ +From 671094906693f292aa604ae23c7df40802f73c6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 05:16:18 -0800 +Subject: netpoll: hold rcu read lock in __netpoll_send_skb() + +From: Breno Leitao + +[ Upstream commit 505ead7ab77f289f12d8a68ac83da068e4d4408b ] + +The function __netpoll_send_skb() is being invoked without holding the +RCU read lock. This oversight triggers a warning message when +CONFIG_PROVE_RCU_LIST is enabled: + + net/core/netpoll.c:330 suspicious rcu_dereference_check() usage! + + netpoll_send_skb + netpoll_send_udp + write_ext_msg + console_flush_all + console_unlock + vprintk_emit + +To prevent npinfo from disappearing unexpectedly, ensure that +__netpoll_send_skb() is protected with the RCU read lock. + +Fixes: 2899656b494dcd1 ("netpoll: take rcu_read_lock_bh() in netpoll_send_skb_on_dev()") +Signed-off-by: Breno Leitao +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250306-netpoll_rcu_v2-v2-1-bc4f5c51742a@debian.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/netpoll.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index 681eeb2b73992..657abbb7d0d7e 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -326,6 +326,7 @@ static int netpoll_owner_active(struct net_device *dev) + static netdev_tx_t __netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) + { + netdev_tx_t status = NETDEV_TX_BUSY; ++ netdev_tx_t ret = NET_XMIT_DROP; + struct net_device *dev; + unsigned long tries; + /* It is up to the caller to keep npinfo alive. */ +@@ -334,11 +335,12 @@ static netdev_tx_t __netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) + lockdep_assert_irqs_disabled(); + + dev = np->dev; ++ rcu_read_lock(); + npinfo = rcu_dereference_bh(dev->npinfo); + + if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) { + dev_kfree_skb_irq(skb); +- return NET_XMIT_DROP; ++ goto out; + } + + /* don't get messages out of order, and no recursion */ +@@ -377,7 +379,10 @@ static netdev_tx_t __netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) + skb_queue_tail(&npinfo->txq, skb); + schedule_delayed_work(&npinfo->tx_work,0); + } +- return NETDEV_TX_OK; ++ ret = NETDEV_TX_OK; ++out: ++ rcu_read_unlock(); ++ return ret; + } + + netdev_tx_t netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) +-- +2.39.5 + diff --git a/queue-6.1/pinctrl-bcm281xx-fix-incorrect-regmap-max_registers-.patch b/queue-6.1/pinctrl-bcm281xx-fix-incorrect-regmap-max_registers-.patch new file mode 100644 index 0000000000..080a5d145c --- /dev/null +++ b/queue-6.1/pinctrl-bcm281xx-fix-incorrect-regmap-max_registers-.patch @@ -0,0 +1,40 @@ +From fa52a7417caf5fe1dfb0450ec9f88959e25c72d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 21:02:41 +0100 +Subject: pinctrl: bcm281xx: Fix incorrect regmap max_registers value + +From: Artur Weber + +[ Upstream commit 68283c1cb573143c0b7515e93206f3503616bc10 ] + +The max_registers value does not take into consideration the stride; +currently, it's set to the number of the last pin, but this does not +accurately represent the final register. + +Fix this by multiplying the current value by 4. + +Fixes: 54b1aa5a5b16 ("ARM: pinctrl: Add Broadcom Capri pinctrl driver") +Signed-off-by: Artur Weber +Link: https://lore.kernel.org/20250207-bcm21664-pinctrl-v1-2-e7cfac9b2d3b@gmail.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/bcm/pinctrl-bcm281xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c +index fd52a83387ef7..bba5496335eeb 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c +@@ -971,7 +971,7 @@ static const struct regmap_config bcm281xx_pinctrl_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, +- .max_register = BCM281XX_PIN_VC_CAM3_SDA, ++ .max_register = BCM281XX_PIN_VC_CAM3_SDA * 4, + }; + + static int bcm281xx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +-- +2.39.5 + diff --git a/queue-6.1/revert-bluetooth-hci_core-fix-sleeping-function-call.patch b/queue-6.1/revert-bluetooth-hci_core-fix-sleeping-function-call.patch new file mode 100644 index 0000000000..6e801346bd --- /dev/null +++ b/queue-6.1/revert-bluetooth-hci_core-fix-sleeping-function-call.patch @@ -0,0 +1,389 @@ +From 97479a2709ef42eaaa7c067ccd591b1014461b42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Mar 2025 10:06:10 -0500 +Subject: Revert "Bluetooth: hci_core: Fix sleeping function called from + invalid context" + +From: Luiz Augusto von Dentz + +[ Upstream commit ab6ab707a4d060a51c45fc13e3b2228d5f7c0b87 ] + +This reverts commit 4d94f05558271654670d18c26c912da0c1c15549 which has +problems (see [1]) and is no longer needed since 581dd2dc168f +("Bluetooth: hci_event: Fix using rcu_read_(un)lock while iterating") +has reworked the code where the original bug has been found. + +[1] Link: https://lore.kernel.org/linux-bluetooth/877c55ci1r.wl-tiwai@suse.de/T/#t +Fixes: 4d94f0555827 ("Bluetooth: hci_core: Fix sleeping function called from invalid context") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci_core.h | 108 +++++++++++-------------------- + net/bluetooth/hci_core.c | 10 ++- + net/bluetooth/iso.c | 6 -- + net/bluetooth/l2cap_core.c | 12 ++-- + net/bluetooth/rfcomm/core.c | 6 -- + net/bluetooth/sco.c | 12 ++-- + 6 files changed, 57 insertions(+), 97 deletions(-) + +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index b37e95554271b..d26b57e87f7f4 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -815,6 +815,7 @@ struct hci_conn_params { + extern struct list_head hci_dev_list; + extern struct list_head hci_cb_list; + extern rwlock_t hci_dev_list_lock; ++extern struct mutex hci_cb_list_lock; + + #define hci_dev_set_flag(hdev, nr) set_bit((nr), (hdev)->dev_flags) + #define hci_dev_clear_flag(hdev, nr) clear_bit((nr), (hdev)->dev_flags) +@@ -1768,47 +1769,24 @@ struct hci_cb { + + char *name; + +- bool (*match) (struct hci_conn *conn); + void (*connect_cfm) (struct hci_conn *conn, __u8 status); + void (*disconn_cfm) (struct hci_conn *conn, __u8 status); + void (*security_cfm) (struct hci_conn *conn, __u8 status, +- __u8 encrypt); ++ __u8 encrypt); + void (*key_change_cfm) (struct hci_conn *conn, __u8 status); + void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); + }; + +-static inline void hci_cb_lookup(struct hci_conn *conn, struct list_head *list) +-{ +- struct hci_cb *cb, *cpy; +- +- rcu_read_lock(); +- list_for_each_entry_rcu(cb, &hci_cb_list, list) { +- if (cb->match && cb->match(conn)) { +- cpy = kmalloc(sizeof(*cpy), GFP_ATOMIC); +- if (!cpy) +- break; +- +- *cpy = *cb; +- INIT_LIST_HEAD(&cpy->list); +- list_add_rcu(&cpy->list, list); +- } +- } +- rcu_read_unlock(); +-} +- + static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status) + { +- struct list_head list; +- struct hci_cb *cb, *tmp; +- +- INIT_LIST_HEAD(&list); +- hci_cb_lookup(conn, &list); ++ struct hci_cb *cb; + +- list_for_each_entry_safe(cb, tmp, &list, list) { ++ mutex_lock(&hci_cb_list_lock); ++ list_for_each_entry(cb, &hci_cb_list, list) { + if (cb->connect_cfm) + cb->connect_cfm(conn, status); +- kfree(cb); + } ++ mutex_unlock(&hci_cb_list_lock); + + if (conn->connect_cfm_cb) + conn->connect_cfm_cb(conn, status); +@@ -1816,43 +1794,22 @@ static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status) + + static inline void hci_disconn_cfm(struct hci_conn *conn, __u8 reason) + { +- struct list_head list; +- struct hci_cb *cb, *tmp; +- +- INIT_LIST_HEAD(&list); +- hci_cb_lookup(conn, &list); ++ struct hci_cb *cb; + +- list_for_each_entry_safe(cb, tmp, &list, list) { ++ mutex_lock(&hci_cb_list_lock); ++ list_for_each_entry(cb, &hci_cb_list, list) { + if (cb->disconn_cfm) + cb->disconn_cfm(conn, reason); +- kfree(cb); + } ++ mutex_unlock(&hci_cb_list_lock); + + if (conn->disconn_cfm_cb) + conn->disconn_cfm_cb(conn, reason); + } + +-static inline void hci_security_cfm(struct hci_conn *conn, __u8 status, +- __u8 encrypt) +-{ +- struct list_head list; +- struct hci_cb *cb, *tmp; +- +- INIT_LIST_HEAD(&list); +- hci_cb_lookup(conn, &list); +- +- list_for_each_entry_safe(cb, tmp, &list, list) { +- if (cb->security_cfm) +- cb->security_cfm(conn, status, encrypt); +- kfree(cb); +- } +- +- if (conn->security_cfm_cb) +- conn->security_cfm_cb(conn, status); +-} +- + static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) + { ++ struct hci_cb *cb; + __u8 encrypt; + + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) +@@ -1860,11 +1817,20 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) + + encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00; + +- hci_security_cfm(conn, status, encrypt); ++ mutex_lock(&hci_cb_list_lock); ++ list_for_each_entry(cb, &hci_cb_list, list) { ++ if (cb->security_cfm) ++ cb->security_cfm(conn, status, encrypt); ++ } ++ mutex_unlock(&hci_cb_list_lock); ++ ++ if (conn->security_cfm_cb) ++ conn->security_cfm_cb(conn, status); + } + + static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status) + { ++ struct hci_cb *cb; + __u8 encrypt; + + if (conn->state == BT_CONFIG) { +@@ -1891,38 +1857,40 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status) + conn->sec_level = conn->pending_sec_level; + } + +- hci_security_cfm(conn, status, encrypt); ++ mutex_lock(&hci_cb_list_lock); ++ list_for_each_entry(cb, &hci_cb_list, list) { ++ if (cb->security_cfm) ++ cb->security_cfm(conn, status, encrypt); ++ } ++ mutex_unlock(&hci_cb_list_lock); ++ ++ if (conn->security_cfm_cb) ++ conn->security_cfm_cb(conn, status); + } + + static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) + { +- struct list_head list; +- struct hci_cb *cb, *tmp; +- +- INIT_LIST_HEAD(&list); +- hci_cb_lookup(conn, &list); ++ struct hci_cb *cb; + +- list_for_each_entry_safe(cb, tmp, &list, list) { ++ mutex_lock(&hci_cb_list_lock); ++ list_for_each_entry(cb, &hci_cb_list, list) { + if (cb->key_change_cfm) + cb->key_change_cfm(conn, status); +- kfree(cb); + } ++ mutex_unlock(&hci_cb_list_lock); + } + + static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, + __u8 role) + { +- struct list_head list; +- struct hci_cb *cb, *tmp; +- +- INIT_LIST_HEAD(&list); +- hci_cb_lookup(conn, &list); ++ struct hci_cb *cb; + +- list_for_each_entry_safe(cb, tmp, &list, list) { ++ mutex_lock(&hci_cb_list_lock); ++ list_for_each_entry(cb, &hci_cb_list, list) { + if (cb->role_switch_cfm) + cb->role_switch_cfm(conn, status, role); +- kfree(cb); + } ++ mutex_unlock(&hci_cb_list_lock); + } + + static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type) +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 496dac042b9cf..3cd7c212375fc 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -58,6 +58,7 @@ DEFINE_RWLOCK(hci_dev_list_lock); + + /* HCI callback list */ + LIST_HEAD(hci_cb_list); ++DEFINE_MUTEX(hci_cb_list_lock); + + /* HCI ID Numbering */ + static DEFINE_IDA(hci_index_ida); +@@ -2977,7 +2978,9 @@ int hci_register_cb(struct hci_cb *cb) + { + BT_DBG("%p name %s", cb, cb->name); + +- list_add_tail_rcu(&cb->list, &hci_cb_list); ++ mutex_lock(&hci_cb_list_lock); ++ list_add_tail(&cb->list, &hci_cb_list); ++ mutex_unlock(&hci_cb_list_lock); + + return 0; + } +@@ -2987,8 +2990,9 @@ int hci_unregister_cb(struct hci_cb *cb) + { + BT_DBG("%p name %s", cb, cb->name); + +- list_del_rcu(&cb->list); +- synchronize_rcu(); ++ mutex_lock(&hci_cb_list_lock); ++ list_del(&cb->list); ++ mutex_unlock(&hci_cb_list_lock); + + return 0; + } +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index f62df9097f5ee..437cbeaa96193 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -1579,11 +1579,6 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) + return lm; + } + +-static bool iso_match(struct hci_conn *hcon) +-{ +- return hcon->type == ISO_LINK || hcon->type == LE_LINK; +-} +- + static void iso_connect_cfm(struct hci_conn *hcon, __u8 status) + { + if (hcon->type != ISO_LINK) { +@@ -1753,7 +1748,6 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) + + static struct hci_cb iso_cb = { + .name = "ISO", +- .match = iso_match, + .connect_cfm = iso_connect_cfm, + .disconn_cfm = iso_disconn_cfm, + }; +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 36d6122f2e12d..21a79ef7092d7 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -8278,11 +8278,6 @@ static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c, + return NULL; + } + +-static bool l2cap_match(struct hci_conn *hcon) +-{ +- return hcon->type == ACL_LINK || hcon->type == LE_LINK; +-} +- + static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) + { + struct hci_dev *hdev = hcon->hdev; +@@ -8290,6 +8285,9 @@ static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) + struct l2cap_chan *pchan; + u8 dst_type; + ++ if (hcon->type != ACL_LINK && hcon->type != LE_LINK) ++ return; ++ + BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + + if (status) { +@@ -8354,6 +8352,9 @@ int l2cap_disconn_ind(struct hci_conn *hcon) + + static void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) + { ++ if (hcon->type != ACL_LINK && hcon->type != LE_LINK) ++ return; ++ + BT_DBG("hcon %p reason %d", hcon, reason); + + l2cap_conn_del(hcon, bt_to_errno(reason)); +@@ -8641,7 +8642,6 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) + + static struct hci_cb l2cap_cb = { + .name = "L2CAP", +- .match = l2cap_match, + .connect_cfm = l2cap_connect_cfm, + .disconn_cfm = l2cap_disconn_cfm, + .security_cfm = l2cap_security_cfm, +diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c +index 1686fa60e2782..4f54c7df3a94f 100644 +--- a/net/bluetooth/rfcomm/core.c ++++ b/net/bluetooth/rfcomm/core.c +@@ -2130,11 +2130,6 @@ static int rfcomm_run(void *unused) + return 0; + } + +-static bool rfcomm_match(struct hci_conn *hcon) +-{ +- return hcon->type == ACL_LINK; +-} +- + static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) + { + struct rfcomm_session *s; +@@ -2181,7 +2176,6 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) + + static struct hci_cb rfcomm_cb = { + .name = "RFCOMM", +- .match = rfcomm_match, + .security_cfm = rfcomm_security_cfm + }; + +diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c +index 127479bf475b9..fe8728041ad08 100644 +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -1367,13 +1367,11 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) + return lm; + } + +-static bool sco_match(struct hci_conn *hcon) +-{ +- return hcon->type == SCO_LINK || hcon->type == ESCO_LINK; +-} +- + static void sco_connect_cfm(struct hci_conn *hcon, __u8 status) + { ++ if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) ++ return; ++ + BT_DBG("hcon %p bdaddr %pMR status %u", hcon, &hcon->dst, status); + + if (!status) { +@@ -1388,6 +1386,9 @@ static void sco_connect_cfm(struct hci_conn *hcon, __u8 status) + + static void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) + { ++ if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) ++ return; ++ + BT_DBG("hcon %p reason %d", hcon, reason); + + sco_conn_del(hcon, bt_to_errno(reason)); +@@ -1413,7 +1414,6 @@ void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) + + static struct hci_cb sco_cb = { + .name = "SCO", +- .match = sco_match, + .connect_cfm = sco_connect_cfm, + .disconn_cfm = sco_disconn_cfm, + }; +-- +2.39.5 + diff --git a/queue-6.1/sched-address-a-potential-null-pointer-dereference-i.patch b/queue-6.1/sched-address-a-potential-null-pointer-dereference-i.patch new file mode 100644 index 0000000000..ec6f91a3ad --- /dev/null +++ b/queue-6.1/sched-address-a-potential-null-pointer-dereference-i.patch @@ -0,0 +1,46 @@ +From af094899574f2a22e52def0531608168b1845ca1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 23:44:10 +0800 +Subject: sched: address a potential NULL pointer dereference in the GRED + scheduler. + +From: Jun Yang + +[ Upstream commit 115ef44a98220fddfab37a39a19370497cd718b9 ] + +If kzalloc in gred_init returns a NULL pointer, the code follows the +error handling path, invoking gred_destroy. This, in turn, calls +gred_offload, where memset could receive a NULL pointer as input, +potentially leading to a kernel crash. + +When table->opt is NULL in gred_init(), gred_change_table_def() +is not called yet, so it is not necessary to call ->ndo_setup_tc() +in gred_offload(). + +Signed-off-by: Jun Yang +Reviewed-by: Cong Wang +Fixes: f25c0515c521 ("net: sched: gred: dynamically allocate tc_gred_qopt_offload") +Link: https://patch.msgid.link/20250305154410.3505642-1-juny24602@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_gred.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c +index 872d127c9db42..fa7a1b69c0f35 100644 +--- a/net/sched/sch_gred.c ++++ b/net/sched/sch_gred.c +@@ -913,7 +913,8 @@ static void gred_destroy(struct Qdisc *sch) + for (i = 0; i < table->DPs; i++) + gred_destroy_vq(table->tab[i]); + +- gred_offload(sch, TC_GRED_DESTROY); ++ if (table->opt) ++ gred_offload(sch, TC_GRED_DESTROY); + kfree(table->opt); + } + +-- +2.39.5 + diff --git a/queue-6.1/series b/queue-6.1/series index b4ad35732f..ad63f31820 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -2,3 +2,29 @@ clockevents-drivers-i8253-fix-stop-sequence-for-timer-0.patch sched-isolation-prevent-boot-crash-when-the-boot-cpu-is-nohz_full.patch hrtimer-use-and-report-correct-timerslack-values-for-realtime-tasks.patch fs-ntfs3-fix-shift-out-of-bounds-in-ntfs_fill_super.patch +fbdev-hyperv_fb-iounmap-the-correct-memory-when-remo.patch +pinctrl-bcm281xx-fix-incorrect-regmap-max_registers-.patch +netfilter-nft_ct-use-__refcount_inc-for-per-cpu-nft_.patch +ice-fix-memory-leak-in-arfs-after-reset.patch +netfilter-nf_conncount-garbage-collection-is-not-ski.patch +sched-address-a-potential-null-pointer-dereference-i.patch +wifi-cfg80211-cancel-wiphy_work-before-freeing-wiphy.patch +bluetooth-hci_event-fix-enabling-passive-scanning.patch +revert-bluetooth-hci_core-fix-sleeping-function-call.patch +net-dsa-mv88e6xxx-verify-after-atu-load-ops.patch +net-mctp-i2c-copy-headers-if-cloned.patch +netpoll-hold-rcu-read-lock-in-__netpoll_send_skb.patch +drm-hyperv-fix-address-space-leak-when-hyper-v-drm-d.patch +drivers-hv-vmbus-don-t-release-fb_mmio-resource-in-v.patch +net-mlx5-handle-errors-in-mlx5_chains_create_table.patch +eth-bnxt-do-not-update-checksum-in-bnxt_xdp_build_sk.patch +net-switchdev-convert-blocking-notification-chain-to.patch +bonding-fix-incorrect-mac-address-setting-to-receive.patch +netfilter-nf_conncount-fully-initialize-struct-nf_co.patch +ipvs-prevent-integer-overflow-in-do_ip_vs_get_ctl.patch +net_sched-prevent-creation-of-classes-with-tc_h_root.patch +netfilter-nft_exthdr-fix-offset-with-ipv4_find_optio.patch +gre-fix-ipv6-link-local-address-generation.patch +net-openvswitch-remove-misbehaving-actions-length-ch.patch +net-mlx5-bridge-fix-the-crash-caused-by-lag-state-ch.patch +net-mlx5e-prevent-bridge-link-show-failure-for-non-e.patch diff --git a/queue-6.1/wifi-cfg80211-cancel-wiphy_work-before-freeing-wiphy.patch b/queue-6.1/wifi-cfg80211-cancel-wiphy_work-before-freeing-wiphy.patch new file mode 100644 index 0000000000..02009ce0ce --- /dev/null +++ b/queue-6.1/wifi-cfg80211-cancel-wiphy_work-before-freeing-wiphy.patch @@ -0,0 +1,50 @@ +From a2cac50c65fc52bbee3f07367aed2655116971b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 12:37:59 +0200 +Subject: wifi: cfg80211: cancel wiphy_work before freeing wiphy + +From: Miri Korenblit + +[ Upstream commit 72d520476a2fab6f3489e8388ab524985d6c4b90 ] + +A wiphy_work can be queued from the moment the wiphy is allocated and +initialized (i.e. wiphy_new_nm). When a wiphy_work is queued, the +rdev::wiphy_work is getting queued. + +If wiphy_free is called before the rdev::wiphy_work had a chance to run, +the wiphy memory will be freed, and then when it eventally gets to run +it'll use invalid memory. + +Fix this by canceling the work before freeing the wiphy. + +Fixes: a3ee4dc84c4e ("wifi: cfg80211: add a work abstraction with special semantics") +Signed-off-by: Miri Korenblit +Reviewed-by: Johannes Berg +Link: https://patch.msgid.link/20250306123626.efd1d19f6e07.I48229f96f4067ef73f5b87302335e2fd750136c9@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/core.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/net/wireless/core.c b/net/wireless/core.c +index 2bed30621fa6e..74904f88edfab 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -1146,6 +1146,13 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev) + { + struct cfg80211_internal_bss *scan, *tmp; + struct cfg80211_beacon_registration *reg, *treg; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); ++ WARN_ON(!list_empty(&rdev->wiphy_work_list)); ++ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); ++ cancel_work_sync(&rdev->wiphy_work); ++ + rfkill_destroy(rdev->wiphy.rfkill); + list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) { + list_del(®->list); +-- +2.39.5 +