From: Greg Kroah-Hartman Date: Mon, 1 Jul 2024 14:32:53 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v4.19.317~75 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=db396b58fefda2cdde2b0c5271274a1eba7da14e;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: ata-ahci-clean-up-sysfs-file-on-error.patch ata-libata-core-fix-double-free-on-error.patch batman-adv-don-t-accept-tt-entries-for-out-of-spec-vids.patch can-mcp251xfd-fix-infinite-loop-when-xmit-fails.patch --- diff --git a/queue-6.1/ata-ahci-clean-up-sysfs-file-on-error.patch b/queue-6.1/ata-ahci-clean-up-sysfs-file-on-error.patch new file mode 100644 index 00000000000..91f8094c20a --- /dev/null +++ b/queue-6.1/ata-ahci-clean-up-sysfs-file-on-error.patch @@ -0,0 +1,87 @@ +From eeb25a09c5e0805d92e4ebd12c4b0ad0df1b0295 Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Sat, 29 Jun 2024 14:42:14 +0200 +Subject: ata: ahci: Clean up sysfs file on error + +From: Niklas Cassel + +commit eeb25a09c5e0805d92e4ebd12c4b0ad0df1b0295 upstream. + +.probe() (ahci_init_one()) calls sysfs_add_file_to_group(), however, +if probe() fails after this call, we currently never call +sysfs_remove_file_from_group(). + +(The sysfs_remove_file_from_group() call in .remove() (ahci_remove_one()) +does not help, as .remove() is not called on .probe() error.) + +Thus, if probe() fails after the sysfs_add_file_to_group() call, the next +time we insmod the module we will get: + +sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:04.0/remapped_nvme' +CPU: 11 PID: 954 Comm: modprobe Not tainted 6.10.0-rc5 #43 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 04/01/2014 +Call Trace: + + dump_stack_lvl+0x5d/0x80 + sysfs_warn_dup.cold+0x17/0x23 + sysfs_add_file_mode_ns+0x11a/0x130 + sysfs_add_file_to_group+0x7e/0xc0 + ahci_init_one+0x31f/0xd40 [ahci] + +Fixes: 894fba7f434a ("ata: ahci: Add sysfs attribute to show remapped NVMe device count") +Cc: stable@vger.kernel.org +Reviewed-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Link: https://lore.kernel.org/r/20240629124210.181537-10-cassel@kernel.org +Signed-off-by: Niklas Cassel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/ahci.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -1891,8 +1891,10 @@ static int ahci_init_one(struct pci_dev + n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); +- if (!host) +- return -ENOMEM; ++ if (!host) { ++ rc = -ENOMEM; ++ goto err_rm_sysfs_file; ++ } + host->private_data = hpriv; + + if (ahci_init_msi(pdev, n_ports, hpriv) < 0) { +@@ -1945,11 +1947,11 @@ static int ahci_init_one(struct pci_dev + /* initialize adapter */ + rc = ahci_configure_dma_masks(pdev, hpriv); + if (rc) +- return rc; ++ goto err_rm_sysfs_file; + + rc = ahci_pci_reset_controller(host); + if (rc) +- return rc; ++ goto err_rm_sysfs_file; + + ahci_pci_init_controller(host); + ahci_pci_print_info(host); +@@ -1958,10 +1960,15 @@ static int ahci_init_one(struct pci_dev + + rc = ahci_host_activate(host, &ahci_sht); + if (rc) +- return rc; ++ goto err_rm_sysfs_file; + + pm_runtime_put_noidle(&pdev->dev); + return 0; ++ ++err_rm_sysfs_file: ++ sysfs_remove_file_from_group(&pdev->dev.kobj, ++ &dev_attr_remapped_nvme.attr, NULL); ++ return rc; + } + + static void ahci_shutdown_one(struct pci_dev *pdev) diff --git a/queue-6.1/ata-libata-core-fix-double-free-on-error.patch b/queue-6.1/ata-libata-core-fix-double-free-on-error.patch new file mode 100644 index 00000000000..acff0142c11 --- /dev/null +++ b/queue-6.1/ata-libata-core-fix-double-free-on-error.patch @@ -0,0 +1,86 @@ +From ab9e0c529eb7cafebdd31fe1644524e80a48b05d Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Sat, 29 Jun 2024 14:42:13 +0200 +Subject: ata: libata-core: Fix double free on error + +From: Niklas Cassel + +commit ab9e0c529eb7cafebdd31fe1644524e80a48b05d upstream. + +If e.g. the ata_port_alloc() call in ata_host_alloc() fails, we will jump +to the err_out label, which will call devres_release_group(). +devres_release_group() will trigger a call to ata_host_release(). +ata_host_release() calls kfree(host), so executing the kfree(host) in +ata_host_alloc() will lead to a double free: + +kernel BUG at mm/slub.c:553! +Oops: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI +CPU: 11 PID: 599 Comm: (udev-worker) Not tainted 6.10.0-rc5 #47 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 04/01/2014 +RIP: 0010:kfree+0x2cf/0x2f0 +Code: 5d 41 5e 41 5f 5d e9 80 d6 ff ff 4d 89 f1 41 b8 01 00 00 00 48 89 d9 48 89 da +RSP: 0018:ffffc90000f377f0 EFLAGS: 00010246 +RAX: ffff888112b1f2c0 RBX: ffff888112b1f2c0 RCX: ffff888112b1f320 +RDX: 000000000000400b RSI: ffffffffc02c9de5 RDI: ffff888112b1f2c0 +RBP: ffffc90000f37830 R08: 0000000000000000 R09: 0000000000000000 +R10: ffffc90000f37610 R11: 617461203a736b6e R12: ffffea00044ac780 +R13: ffff888100046400 R14: ffffffffc02c9de5 R15: 0000000000000006 +FS: 00007f2f1cabe980(0000) GS:ffff88813b380000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f2f1c3acf75 CR3: 0000000111724000 CR4: 0000000000750ef0 +PKRU: 55555554 +Call Trace: + + ? __die_body.cold+0x19/0x27 + ? die+0x2e/0x50 + ? do_trap+0xca/0x110 + ? do_error_trap+0x6a/0x90 + ? kfree+0x2cf/0x2f0 + ? exc_invalid_op+0x50/0x70 + ? kfree+0x2cf/0x2f0 + ? asm_exc_invalid_op+0x1a/0x20 + ? ata_host_alloc+0xf5/0x120 [libata] + ? ata_host_alloc+0xf5/0x120 [libata] + ? kfree+0x2cf/0x2f0 + ata_host_alloc+0xf5/0x120 [libata] + ata_host_alloc_pinfo+0x14/0xa0 [libata] + ahci_init_one+0x6c9/0xd20 [ahci] + +Ensure that we will not call kfree(host) twice, by performing the kfree() +only if the devres_open_group() call failed. + +Fixes: dafd6c496381 ("libata: ensure host is free'd on error exit paths") +Cc: stable@vger.kernel.org +Reviewed-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Link: https://lore.kernel.org/r/20240629124210.181537-9-cassel@kernel.org +Signed-off-by: Niklas Cassel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-core.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -5523,8 +5523,10 @@ struct ata_host *ata_host_alloc(struct d + if (!host) + return NULL; + +- if (!devres_open_group(dev, NULL, GFP_KERNEL)) +- goto err_free; ++ if (!devres_open_group(dev, NULL, GFP_KERNEL)) { ++ kfree(host); ++ return NULL; ++ } + + dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL); + if (!dr) +@@ -5556,8 +5558,6 @@ struct ata_host *ata_host_alloc(struct d + + err_out: + devres_release_group(dev, NULL); +- err_free: +- kfree(host); + return NULL; + } + EXPORT_SYMBOL_GPL(ata_host_alloc); diff --git a/queue-6.1/batman-adv-don-t-accept-tt-entries-for-out-of-spec-vids.patch b/queue-6.1/batman-adv-don-t-accept-tt-entries-for-out-of-spec-vids.patch new file mode 100644 index 00000000000..22e1c1e4b52 --- /dev/null +++ b/queue-6.1/batman-adv-don-t-accept-tt-entries-for-out-of-spec-vids.patch @@ -0,0 +1,92 @@ +From 537a350d14321c8cca5efbf0a33a404fec3a9f9e Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Sat, 4 May 2024 21:57:30 +0200 +Subject: batman-adv: Don't accept TT entries for out-of-spec VIDs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Sven Eckelmann + +commit 537a350d14321c8cca5efbf0a33a404fec3a9f9e upstream. + +The internal handling of VLAN IDs in batman-adv is only specified for +following encodings: + +* VLAN is used + - bit 15 is 1 + - bit 11 - bit 0 is the VLAN ID (0-4095) + - remaining bits are 0 +* No VLAN is used + - bit 15 is 0 + - remaining bits are 0 + +batman-adv was only preparing new translation table entries (based on its +soft interface information) using this encoding format. But the receive +path was never checking if entries in the roam or TT TVLVs were also +following this encoding. + +It was therefore possible to create more than the expected maximum of 4096 ++ 1 entries in the originator VLAN list. Simply by setting the "remaining +bits" to "random" values in corresponding TVLV. + +Cc: stable@vger.kernel.org +Fixes: 7ea7b4a14275 ("batman-adv: make the TT CRC logic VLAN specific") +Reported-by: Linus Lüssing +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/originator.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/net/batman-adv/originator.c ++++ b/net/batman-adv/originator.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -132,6 +133,29 @@ batadv_orig_node_vlan_get(struct batadv_ + } + + /** ++ * batadv_vlan_id_valid() - check if vlan id is in valid batman-adv encoding ++ * @vid: the VLAN identifier ++ * ++ * Return: true when either no vlan is set or if VLAN is in correct range, ++ * false otherwise ++ */ ++static bool batadv_vlan_id_valid(unsigned short vid) ++{ ++ unsigned short non_vlan = vid & ~(BATADV_VLAN_HAS_TAG | VLAN_VID_MASK); ++ ++ if (vid == 0) ++ return true; ++ ++ if (!(vid & BATADV_VLAN_HAS_TAG)) ++ return false; ++ ++ if (non_vlan) ++ return false; ++ ++ return true; ++} ++ ++/** + * batadv_orig_node_vlan_new() - search and possibly create an orig_node_vlan + * object + * @orig_node: the originator serving the VLAN +@@ -149,6 +173,9 @@ batadv_orig_node_vlan_new(struct batadv_ + { + struct batadv_orig_node_vlan *vlan; + ++ if (!batadv_vlan_id_valid(vid)) ++ return NULL; ++ + spin_lock_bh(&orig_node->vlan_list_lock); + + /* first look if an object for this vid already exists */ diff --git a/queue-6.1/can-mcp251xfd-fix-infinite-loop-when-xmit-fails.patch b/queue-6.1/can-mcp251xfd-fix-infinite-loop-when-xmit-fails.patch new file mode 100644 index 00000000000..a8fc505d967 --- /dev/null +++ b/queue-6.1/can-mcp251xfd-fix-infinite-loop-when-xmit-fails.patch @@ -0,0 +1,190 @@ +From d8fb63e46c884c898a38f061c2330f7729e75510 Mon Sep 17 00:00:00 2001 +From: Vitor Soares +Date: Fri, 17 May 2024 14:43:55 +0100 +Subject: can: mcp251xfd: fix infinite loop when xmit fails + +From: Vitor Soares + +commit d8fb63e46c884c898a38f061c2330f7729e75510 upstream. + +When the mcp251xfd_start_xmit() function fails, the driver stops +processing messages, and the interrupt routine does not return, +running indefinitely even after killing the running application. + +Error messages: +[ 441.298819] mcp251xfd spi2.0 can0: ERROR in mcp251xfd_start_xmit: -16 +[ 441.306498] mcp251xfd spi2.0 can0: Transmit Event FIFO buffer not empty. (seq=0x000017c7, tef_tail=0x000017cf, tef_head=0x000017d0, tx_head=0x000017d3). +... and repeat forever. + +The issue can be triggered when multiple devices share the same SPI +interface. And there is concurrent access to the bus. + +The problem occurs because tx_ring->head increments even if +mcp251xfd_start_xmit() fails. Consequently, the driver skips one TX +package while still expecting a response in +mcp251xfd_handle_tefif_one(). + +Resolve the issue by starting a workqueue to write the tx obj +synchronously if err = -EBUSY. In case of another error, decrement +tx_ring->head, remove skb from the echo stack, and drop the message. + +Fixes: 55e5b97f003e ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN") +Cc: stable@vger.kernel.org +Signed-off-by: Vitor Soares +Link: https://lore.kernel.org/all/20240517134355.770777-1-ivitro@gmail.com +[mkl: use more imperative wording in patch description] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 14 +++++- + drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c | 55 +++++++++++++++++++++---- + drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 5 ++ + 3 files changed, 65 insertions(+), 9 deletions(-) + +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +@@ -1618,11 +1618,20 @@ static int mcp251xfd_open(struct net_dev + clear_bit(MCP251XFD_FLAGS_DOWN, priv->flags); + can_rx_offload_enable(&priv->offload); + ++ priv->wq = alloc_ordered_workqueue("%s-mcp251xfd_wq", ++ WQ_FREEZABLE | WQ_MEM_RECLAIM, ++ dev_name(&spi->dev)); ++ if (!priv->wq) { ++ err = -ENOMEM; ++ goto out_can_rx_offload_disable; ++ } ++ INIT_WORK(&priv->tx_work, mcp251xfd_tx_obj_write_sync); ++ + err = request_threaded_irq(spi->irq, NULL, mcp251xfd_irq, + IRQF_SHARED | IRQF_ONESHOT, + dev_name(&spi->dev), priv); + if (err) +- goto out_can_rx_offload_disable; ++ goto out_destroy_workqueue; + + err = mcp251xfd_chip_interrupts_enable(priv); + if (err) +@@ -1634,6 +1643,8 @@ static int mcp251xfd_open(struct net_dev + + out_free_irq: + free_irq(spi->irq, priv); ++ out_destroy_workqueue: ++ destroy_workqueue(priv->wq); + out_can_rx_offload_disable: + can_rx_offload_disable(&priv->offload); + set_bit(MCP251XFD_FLAGS_DOWN, priv->flags); +@@ -1661,6 +1672,7 @@ static int mcp251xfd_stop(struct net_dev + hrtimer_cancel(&priv->tx_irq_timer); + mcp251xfd_chip_interrupts_disable(priv); + free_irq(ndev->irq, priv); ++ destroy_workqueue(priv->wq); + can_rx_offload_disable(&priv->offload); + mcp251xfd_timestamp_stop(priv); + mcp251xfd_chip_stop(priv, CAN_STATE_STOPPED); +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c +@@ -131,6 +131,39 @@ mcp251xfd_tx_obj_from_skb(const struct m + tx_obj->xfer[0].len = len; + } + ++static void mcp251xfd_tx_failure_drop(const struct mcp251xfd_priv *priv, ++ struct mcp251xfd_tx_ring *tx_ring, ++ int err) ++{ ++ struct net_device *ndev = priv->ndev; ++ struct net_device_stats *stats = &ndev->stats; ++ unsigned int frame_len = 0; ++ u8 tx_head; ++ ++ tx_ring->head--; ++ stats->tx_dropped++; ++ tx_head = mcp251xfd_get_tx_head(tx_ring); ++ can_free_echo_skb(ndev, tx_head, &frame_len); ++ netdev_completed_queue(ndev, 1, frame_len); ++ netif_wake_queue(ndev); ++ ++ if (net_ratelimit()) ++ netdev_err(priv->ndev, "ERROR in %s: %d\n", __func__, err); ++} ++ ++void mcp251xfd_tx_obj_write_sync(struct work_struct *work) ++{ ++ struct mcp251xfd_priv *priv = container_of(work, struct mcp251xfd_priv, ++ tx_work); ++ struct mcp251xfd_tx_obj *tx_obj = priv->tx_work_obj; ++ struct mcp251xfd_tx_ring *tx_ring = priv->tx; ++ int err; ++ ++ err = spi_sync(priv->spi, &tx_obj->msg); ++ if (err) ++ mcp251xfd_tx_failure_drop(priv, tx_ring, err); ++} ++ + static int mcp251xfd_tx_obj_write(const struct mcp251xfd_priv *priv, + struct mcp251xfd_tx_obj *tx_obj) + { +@@ -162,6 +195,11 @@ static bool mcp251xfd_tx_busy(const stru + return false; + } + ++static bool mcp251xfd_work_busy(struct work_struct *work) ++{ ++ return work_busy(work); ++} ++ + netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, + struct net_device *ndev) + { +@@ -175,7 +213,8 @@ netdev_tx_t mcp251xfd_start_xmit(struct + if (can_dev_dropped_skb(ndev, skb)) + return NETDEV_TX_OK; + +- if (mcp251xfd_tx_busy(priv, tx_ring)) ++ if (mcp251xfd_tx_busy(priv, tx_ring) || ++ mcp251xfd_work_busy(&priv->tx_work)) + return NETDEV_TX_BUSY; + + tx_obj = mcp251xfd_get_tx_obj_next(tx_ring); +@@ -193,13 +232,13 @@ netdev_tx_t mcp251xfd_start_xmit(struct + netdev_sent_queue(priv->ndev, frame_len); + + err = mcp251xfd_tx_obj_write(priv, tx_obj); +- if (err) +- goto out_err; +- +- return NETDEV_TX_OK; +- +- out_err: +- netdev_err(priv->ndev, "ERROR in %s: %d\n", __func__, err); ++ if (err == -EBUSY) { ++ netif_stop_queue(ndev); ++ priv->tx_work_obj = tx_obj; ++ queue_work(priv->wq, &priv->tx_work); ++ } else if (err) { ++ mcp251xfd_tx_failure_drop(priv, tx_ring, err); ++ } + + return NETDEV_TX_OK; + } +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +@@ -628,6 +628,10 @@ struct mcp251xfd_priv { + struct mcp251xfd_rx_ring *rx[MCP251XFD_FIFO_RX_NUM]; + struct mcp251xfd_tx_ring tx[MCP251XFD_FIFO_TX_NUM]; + ++ struct workqueue_struct *wq; ++ struct work_struct tx_work; ++ struct mcp251xfd_tx_obj *tx_work_obj; ++ + DECLARE_BITMAP(flags, __MCP251XFD_FLAGS_SIZE__); + + u8 rx_ring_num; +@@ -934,6 +938,7 @@ void mcp251xfd_skb_set_timestamp(const s + void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv); + void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv); + ++void mcp251xfd_tx_obj_write_sync(struct work_struct *work); + netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, + struct net_device *ndev); + diff --git a/queue-6.1/series b/queue-6.1/series index ecbddad5b8d..08f5e8654c0 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -110,3 +110,7 @@ drm-amdgpu-avoid-using-null-object-of-framebuffer.patch drm-i915-gt-fix-potential-uaf-by-revoke-of-fence-registers.patch drm-nouveau-dispnv04-fix-null-pointer-dereference-in-nv17_tv_get_hd_modes.patch drm-amdgpu-atomfirmware-fix-parsing-of-vram_info.patch +batman-adv-don-t-accept-tt-entries-for-out-of-spec-vids.patch +can-mcp251xfd-fix-infinite-loop-when-xmit-fails.patch +ata-ahci-clean-up-sysfs-file-on-error.patch +ata-libata-core-fix-double-free-on-error.patch