From: Greg Kroah-Hartman Date: Mon, 20 Jul 2026 15:43:51 +0000 (+0200) Subject: 7.1-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c986cac47f785a1b2077f1c15eb8b362a8ee4bb2;p=thirdparty%2Fkernel%2Fstable-queue.git 7.1-stable patches added patches: fs-resctrl-fix-use-after-free-during-unmount.patch input-ims-pcu-add-response-length-checks.patch input-ims-pcu-fix-dma-mapping-violation-in-line-setup.patch input-ims-pcu-fix-firmware-leak-in-async-update.patch input-ims-pcu-fix-logic-error-in-packet-reset.patch input-ims-pcu-fix-out-of-bounds-read-in-ims_pcu_irq-debug-logging.patch input-ims-pcu-fix-potential-infinite-loop-in-cdc-union-descriptor-parsing.patch input-ims-pcu-fix-race-condition-in-reset_device-sysfs-callback.patch input-ims-pcu-fix-type-confusion-in-cdc-union-descriptor-parsing.patch input-ims-pcu-fix-use-after-free-and-double-free-in-disconnect.patch input-ims-pcu-only-expose-sysfs-attributes-on-control-interface.patch input-ims-pcu-release-data-interface-on-disconnect.patch input-ims-pcu-validate-control-endpoint-type.patch mmc-vub300-fix-use-after-free-on-probe-failure.patch net-mlx5e-macsec-fix-use-after-free-of-metadata_dst-on-rx-sc-delete.patch tracing-user_events-fix-use-after-free-in-user_event_mm_dup.patch wifi-libertas_tf-fix-use-after-free-in-lbtf_free_adapter.patch --- diff --git a/queue-7.1/fs-resctrl-fix-use-after-free-during-unmount.patch b/queue-7.1/fs-resctrl-fix-use-after-free-during-unmount.patch new file mode 100644 index 0000000000..20ead49639 --- /dev/null +++ b/queue-7.1/fs-resctrl-fix-use-after-free-during-unmount.patch @@ -0,0 +1,130 @@ +From 52fce648607e0d6a76eeb443d78708c49df1c554 Mon Sep 17 00:00:00 2001 +From: Tony Luck +Date: Mon, 6 Jul 2026 15:46:22 -0700 +Subject: fs/resctrl: Fix use-after-free during unmount + +From: Tony Luck + +commit 52fce648607e0d6a76eeb443d78708c49df1c554 upstream. + +During unmount or failure teardown all mon_data structures that contain +monitoring event file private data are freed after which kernfs nodes are +removed. However, the RDT_DELETED flag is never set for the statically +allocated default resource group. + +A concurrent reader of an event file associated with the default resource +group may, after dropping kernfs active protection, block on rdtgroup_mutex +while unmount proceeds to free the file private data and destroy the kernfs +node without waiting for the reader. + +When the mutex is released, the reader wakes up, observes that RDT_DELETED +is not set for the default group, and dereferences the already-freed +file private data. + +The scenario can be depicted as follows: + CPU0 CPU1 + /* + * Default resource group's + * monitoring data accessible via + * kernfs file with kernfs_node::priv + * pointing to a struct mon_data. + * User opens the file for reading. + */ + rdtgroup_mondata_show() /* arch encounters fatal error */ + rdtgroup_kn_lock_live() resctrl_exit() + atomic_inc(&rdtgroup_default.waitcount) cpus_read_lock() + kernfs_break_active_protection(kn) mutex_lock(&rdtgroup_mutex) + cpus_read_lock() resctrl_fs_teardown() + mutex_lock(&rdtgroup_mutex) rmdir_all_sub() + mon_put_kn_priv() + /* Delete all mon_data structures */ + rdtgroup_destroy_root() + kernfs_destroy_root() + rdtgroup_default.kn = NULL + mutex_unlock(&rdtgroup_mutex) + /* + * rdtgroup_default.flags is empty so + * rdtgroup_kn_lock_live() returns + * &rdtgroup_default + */ + md = of->kn->priv; + + /* md points to freed mon_data */ + +Set RDT_DELETED for the default group unconditionally since the flag does +not lead to the freeing of this statically allocated group. + +Do not allow a new resctrl mount if there are any waiters on default group +of previous mount. A new mount will re-initialize the default group that +would appear to waiters from previous mount as though the default group is +accessible causing them to access the mon_data structures from the previous +mount that have been removed. + +Fixes: 2a6566038544 ("x86/resctrl: Expand the width of domid by replacing mon_data_bits") +Closes: https://sashiko.dev/#/patchset/20260508182143.14592-1-tony.luck%40intel.com?part=2 [1] +Reported-by: Sashiko +Signed-off-by: Tony Luck +Signed-off-by: Reinette Chatre +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Chen Yu +Cc: +Link: https://patch.msgid.link/49a2ca3ca688f27e1a646cf90e1dc69287021127.1783377598.git.reinette.chatre@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + fs/resctrl/rdtgroup.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/fs/resctrl/rdtgroup.c ++++ b/fs/resctrl/rdtgroup.c +@@ -585,14 +585,20 @@ unlock: + * + * On resource group creation via a mkdir, an extra kernfs_node reference is + * taken to ensure that the rdtgroup structure remains accessible for the +- * rdtgroup_kn_unlock() calls where it is removed. ++ * rdtgroup_kn_unlock() calls where it is removed. The default group is ++ * statically allocated: it does not have an extra reference but will have ++ * RDT_DELETED set on unmount to support safe access to its associated files ++ * via rdtgroup_kn_lock_live/rdtgroup_kn_unlock(). + * +- * Drop the extra reference here, then free the rdtgroup structure. ++ * For all but the default group: drop the extra reference, then free the ++ * rdtgroup structure. + * + * Return: void + */ + static void rdtgroup_remove(struct rdtgroup *rdtgrp) + { ++ if (rdtgrp == &rdtgroup_default) ++ return; + kernfs_put(rdtgrp->kn); + kfree(rdtgrp); + } +@@ -2802,6 +2808,12 @@ static int rdt_get_tree(struct fs_contex + goto out; + } + ++ /* Avoid races from pending operations from a previous mount */ ++ if (atomic_read(&rdtgroup_default.waitcount) != 0) { ++ ret = -EBUSY; ++ goto out; ++ } ++ + ret = setup_rmid_lru_list(); + if (ret) + goto out; +@@ -3164,6 +3176,7 @@ static void resctrl_fs_teardown(void) + mon_put_kn_priv(); + rdt_pseudo_lock_release(); + rdtgroup_default.mode = RDT_MODE_SHAREABLE; ++ rdtgroup_default.flags = RDT_DELETED; + closid_exit(); + schemata_list_destroy(); + rdtgroup_destroy_root(); +@@ -4264,6 +4277,7 @@ static int rdtgroup_setup_root(struct rd + + ctx->kfc.root = rdt_root; + rdtgroup_default.kn = kernfs_root_to_node(rdt_root); ++ rdtgroup_default.flags = 0; + + return 0; + } diff --git a/queue-7.1/input-ims-pcu-add-response-length-checks.patch b/queue-7.1/input-ims-pcu-add-response-length-checks.patch new file mode 100644 index 0000000000..50f342646e --- /dev/null +++ b/queue-7.1/input-ims-pcu-add-response-length-checks.patch @@ -0,0 +1,199 @@ +From 48c9d92fd4ee3a8f5d2cb46c802a0eff8e67c79c Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:40:54 -0700 +Subject: Input: ims-pcu - add response length checks + +From: Dmitry Torokhov + +commit 48c9d92fd4ee3a8f5d2cb46c802a0eff8e67c79c upstream. + +The driver processes response data from device buffers without verifying +that the device actually sent enough data. This can lead to +out-of-bounds reads or processing stale data. + +Add checks for the expected response length before accessing the +buffers. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 87 ++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 81 insertions(+), 6 deletions(-) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -407,7 +407,16 @@ static void ims_pcu_destroy_gamepad(stru + + static void ims_pcu_report_events(struct ims_pcu *pcu) + { +- u32 data = get_unaligned_be32(&pcu->read_buf[3]); ++ u32 data; ++ ++ /* 6-axis setting (1 byte) + button data + checksum */ ++ if (pcu->read_pos < IMS_PCU_DATA_OFFSET + 1 + sizeof(data) + 1) { ++ dev_warn(pcu->dev, "Short buttons report: %d bytes\n", ++ pcu->read_pos); ++ return; ++ } ++ ++ data = get_unaligned_be32(&pcu->read_buf[IMS_PCU_DATA_OFFSET + 1]); + + ims_pcu_buttons_report(pcu, data & ~IMS_PCU_GAMEPAD_MASK); + if (pcu->gamepad) +@@ -687,11 +696,19 @@ static int __ims_pcu_execute_bl_command( + return error; + } + +- if (expected_response && pcu->cmd_buf[2] != expected_response) { +- dev_err(pcu->dev, +- "Unexpected response from bootloader: 0x%02x, wanted 0x%02x\n", +- pcu->cmd_buf[2], expected_response); +- return -EINVAL; ++ if (expected_response) { ++ if (pcu->cmd_buf_len < 3) { ++ dev_err(pcu->dev, "Short response from bootloader: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ ++ if (pcu->cmd_buf[2] != expected_response) { ++ dev_err(pcu->dev, ++ "Unexpected response from bootloader: 0x%02x, wanted 0x%02x\n", ++ pcu->cmd_buf[2], expected_response); ++ return -EINVAL; ++ } + } + + return 0; +@@ -719,6 +736,12 @@ static int ims_pcu_get_info(struct ims_p + return error; + } + ++ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + IMS_PCU_SET_INFO_SIZE + 1) { ++ dev_err(pcu->dev, "Short GET_INFO response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + memcpy(pcu->part_number, + &pcu->cmd_buf[IMS_PCU_INFO_PART_OFFSET], + sizeof(pcu->part_number)); +@@ -816,6 +839,12 @@ static int ims_pcu_verify_block(struct i + return error; + } + ++ if (pcu->cmd_buf_len < IMS_PCU_BL_DATA_OFFSET + sizeof(*fragment) + len + 1) { ++ dev_err(pcu->dev, "Short READ_APP response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + fragment = (void *)&pcu->cmd_buf[IMS_PCU_BL_DATA_OFFSET]; + if (get_unaligned_le32(&fragment->addr) != addr || + fragment->len != len) { +@@ -1010,6 +1039,10 @@ ims_pcu_backlight_get_brightness(struct + error); + /* Assume the LED is OFF */ + brightness = LED_OFF; ++ } else if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 2 + 1) { ++ dev_err(pcu->dev, "Short GET_BRIGHTNESS response: %d bytes\n", ++ pcu->cmd_buf_len); ++ brightness = LED_OFF; + } else { + brightness = + get_unaligned_le16(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET]); +@@ -1286,6 +1319,12 @@ static int ims_pcu_read_ofn_config(struc + if (error) + return error; + ++ if (pcu->cmd_buf_len < OFN_REG_RESULT_OFFSET + 2 + 1) { ++ dev_err(pcu->dev, "Short OFN_GET_CONFIG response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + result = (s16)get_unaligned_le16(pcu->cmd_buf + OFN_REG_RESULT_OFFSET); + if (result < 0) + return -EIO; +@@ -1306,6 +1345,12 @@ static int ims_pcu_write_ofn_config(stru + if (error) + return error; + ++ if (pcu->cmd_buf_len < OFN_REG_RESULT_OFFSET + 2 + 1) { ++ dev_err(pcu->dev, "Short OFN_SET_CONFIG response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + result = (s16)get_unaligned_le16(pcu->cmd_buf + OFN_REG_RESULT_OFFSET); + if (result < 0) + return -EIO; +@@ -1844,6 +1889,12 @@ static int ims_pcu_get_device_info(struc + return error; + } + ++ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 6 + 1) { ++ dev_err(pcu->dev, "Short GET_FW_VERSION response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + snprintf(pcu->fw_version, sizeof(pcu->fw_version), + "%02d%02d%02d%02d.%c%c", + pcu->cmd_buf[2], pcu->cmd_buf[3], pcu->cmd_buf[4], pcu->cmd_buf[5], +@@ -1856,6 +1907,12 @@ static int ims_pcu_get_device_info(struc + return error; + } + ++ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 6 + 1) { ++ dev_err(pcu->dev, "Short GET_BL_VERSION response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + snprintf(pcu->bl_version, sizeof(pcu->bl_version), + "%02d%02d%02d%02d.%c%c", + pcu->cmd_buf[2], pcu->cmd_buf[3], pcu->cmd_buf[4], pcu->cmd_buf[5], +@@ -1868,6 +1925,12 @@ static int ims_pcu_get_device_info(struc + return error; + } + ++ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 1 + 1) { ++ dev_err(pcu->dev, "Short RESET_REASON response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + snprintf(pcu->reset_reason, sizeof(pcu->reset_reason), + "%02x", pcu->cmd_buf[IMS_PCU_DATA_OFFSET]); + +@@ -1894,6 +1957,12 @@ static int ims_pcu_identify_type(struct + return error; + } + ++ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 1 + 1) { ++ dev_err(pcu->dev, "Short GET_DEVICE_ID response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + *device_id = pcu->cmd_buf[IMS_PCU_DATA_OFFSET]; + dev_dbg(pcu->dev, "Detected device ID: %d\n", *device_id); + +@@ -1985,6 +2054,12 @@ static int ims_pcu_init_bootloader_mode( + return error; + } + ++ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 15 + 4 + 1) { ++ dev_err(pcu->dev, "Short QUERY_DEVICE response: %d bytes\n", ++ pcu->cmd_buf_len); ++ return -EIO; ++ } ++ + pcu->fw_start_addr = + get_unaligned_le32(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET + 11]); + pcu->fw_end_addr = diff --git a/queue-7.1/input-ims-pcu-fix-dma-mapping-violation-in-line-setup.patch b/queue-7.1/input-ims-pcu-fix-dma-mapping-violation-in-line-setup.patch new file mode 100644 index 0000000000..7138e684d9 --- /dev/null +++ b/queue-7.1/input-ims-pcu-fix-dma-mapping-violation-in-line-setup.patch @@ -0,0 +1,47 @@ +From 8adf4289d945e8990e4336436a97da71d21d2cae Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:30:44 -0700 +Subject: Input: ims-pcu - fix DMA mapping violation in line setup + +From: Dmitry Torokhov + +commit 8adf4289d945e8990e4336436a97da71d21d2cae upstream. + +In ims_pcu_line_setup(), the driver uses pcu->cmd_buf as a transfer +buffer for usb_control_msg(). However, pcu->cmd_buf is embedded in the +struct ims_pcu allocation, which violates DMA mapping rules regarding +cacheline alignment. + +Use a heap-allocated buffer for the line coding data instead. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -1841,11 +1841,16 @@ static void ims_pcu_stop_io(struct ims_p + static int ims_pcu_line_setup(struct ims_pcu *pcu) + { + struct usb_host_interface *interface = pcu->ctrl_intf->cur_altsetting; +- struct usb_cdc_line_coding *line = (void *)pcu->cmd_buf; ++ struct usb_cdc_line_coding *line __free(kfree) = ++ kmalloc(sizeof(*line), GFP_KERNEL); + int error; + +- memset(line, 0, sizeof(*line)); ++ if (!line) ++ return -ENOMEM; ++ + line->dwDTERate = cpu_to_le32(57600); ++ line->bCharFormat = USB_CDC_1_STOP_BITS; ++ line->bParityType = USB_CDC_NO_PARITY; + line->bDataBits = 8; + + error = usb_control_msg(pcu->udev, usb_sndctrlpipe(pcu->udev, 0), diff --git a/queue-7.1/input-ims-pcu-fix-firmware-leak-in-async-update.patch b/queue-7.1/input-ims-pcu-fix-firmware-leak-in-async-update.patch new file mode 100644 index 0000000000..5b2bc1a5b7 --- /dev/null +++ b/queue-7.1/input-ims-pcu-fix-firmware-leak-in-async-update.patch @@ -0,0 +1,45 @@ +From d48795b5cd6828d36b707e8d62fc9e5c90e004ab Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:25:31 -0700 +Subject: Input: ims-pcu - fix firmware leak in async update + +From: Dmitry Torokhov + +commit d48795b5cd6828d36b707e8d62fc9e5c90e004ab upstream. + +The firmware object was not being released if validation failed. +Use __free(firmware) to ensure the firmware is always released. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -964,9 +964,10 @@ out: + return retval; + } + +-static void ims_pcu_process_async_firmware(const struct firmware *fw, ++static void ims_pcu_process_async_firmware(const struct firmware *_fw, + void *context) + { ++ const struct firmware *fw __free(firmware) = _fw; + struct ims_pcu *pcu = context; + int error; + +@@ -986,8 +987,6 @@ static void ims_pcu_process_async_firmwa + scoped_guard(mutex, &pcu->cmd_mutex) + ims_pcu_handle_firmware_update(pcu, fw); + +- release_firmware(fw); +- + out: + complete(&pcu->async_firmware_done); + } diff --git a/queue-7.1/input-ims-pcu-fix-logic-error-in-packet-reset.patch b/queue-7.1/input-ims-pcu-fix-logic-error-in-packet-reset.patch new file mode 100644 index 0000000000..432795b940 --- /dev/null +++ b/queue-7.1/input-ims-pcu-fix-logic-error-in-packet-reset.patch @@ -0,0 +1,37 @@ +From 2c9b85a14abb4811e8d4773ccd13559e59792efb Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:29:41 -0700 +Subject: Input: ims-pcu - fix logic error in packet reset + +From: Dmitry Torokhov + +commit 2c9b85a14abb4811e8d4773ccd13559e59792efb upstream. + +ims_pcu_reset_packet() incorrectly sets have_stx to true, which implies +that the start-of-packet delimiter has already been received. This +causes the protocol parser to skip waiting for the next STX byte and +potentially process garbage data. + +Correctly set have_stx to false when resetting the packet state. + +Fixes: 875115b82c29 ("Input: ims-pcu - fix heap-buffer-overflow in ims_pcu_process_data()") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -450,7 +450,7 @@ static void ims_pcu_handle_response(stru + + static void ims_pcu_reset_packet(struct ims_pcu *pcu) + { +- pcu->have_stx = true; ++ pcu->have_stx = false; + pcu->have_dle = false; + pcu->read_pos = 0; + pcu->check_sum = 0; diff --git a/queue-7.1/input-ims-pcu-fix-out-of-bounds-read-in-ims_pcu_irq-debug-logging.patch b/queue-7.1/input-ims-pcu-fix-out-of-bounds-read-in-ims_pcu_irq-debug-logging.patch new file mode 100644 index 0000000000..ec5cfc8e3d --- /dev/null +++ b/queue-7.1/input-ims-pcu-fix-out-of-bounds-read-in-ims_pcu_irq-debug-logging.patch @@ -0,0 +1,38 @@ +From 403b0a6970b1084bb27907c0f8225801fdd0fe1d Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:30:21 -0700 +Subject: Input: ims-pcu - fix out-of-bounds read in ims_pcu_irq() debug logging + +From: Dmitry Torokhov + +commit 403b0a6970b1084bb27907c0f8225801fdd0fe1d upstream. + +The debug logging in ims_pcu_irq() unconditionally prints data from +pcu->urb_in_buf. However, if the interrupt fired for pcu->urb_ctrl, the +actual data resides in pcu->urb_ctrl_buf. If urb->actual_length for the +control URB exceeds pcu->max_in_size, this leads to an out-of-bounds +read. + +Fix this by printing from the correct buffer associated with the URB. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -1579,7 +1579,7 @@ static void ims_pcu_irq(struct urb *urb) + } + + dev_dbg(pcu->dev, "%s: received %d: %*ph\n", __func__, +- urb->actual_length, urb->actual_length, pcu->urb_in_buf); ++ urb->actual_length, urb->actual_length, urb->transfer_buffer); + + if (urb == pcu->urb_in) + ims_pcu_process_data(pcu, urb); diff --git a/queue-7.1/input-ims-pcu-fix-potential-infinite-loop-in-cdc-union-descriptor-parsing.patch b/queue-7.1/input-ims-pcu-fix-potential-infinite-loop-in-cdc-union-descriptor-parsing.patch new file mode 100644 index 0000000000..dad11e1e71 --- /dev/null +++ b/queue-7.1/input-ims-pcu-fix-potential-infinite-loop-in-cdc-union-descriptor-parsing.patch @@ -0,0 +1,41 @@ +From d4579af29e67ca8722db0a1194227f8015c8981d Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 21:42:39 -0700 +Subject: Input: ims-pcu - fix potential infinite loop in CDC union descriptor parsing + +From: Dmitry Torokhov + +commit d4579af29e67ca8722db0a1194227f8015c8981d upstream. + +The driver parses CDC union descriptors in ims_pcu_get_cdc_union_desc() +by iterating through the extra descriptor data. However, it does not +verify that the bLength of each descriptor is at least 2. A malicious +device could provide a descriptor with bLength = 0, leading to an +infinite loop in the driver. + +Add a check to ensure bLength is at least 2 before proceeding with +parsing. + +Fixes: 628329d52474 (Input: add IMS Passenger Control Unit driver) +Cc: stable@vger.kernel.org +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -1707,8 +1707,9 @@ ims_pcu_get_cdc_union_desc(struct usb_in + while (buflen >= sizeof(*union_desc)) { + union_desc = (struct usb_cdc_union_desc *)buf; + +- if (union_desc->bLength > buflen) { +- dev_err(&intf->dev, "Too large descriptor\n"); ++ if (union_desc->bLength < 2 || union_desc->bLength > buflen) { ++ dev_err(&intf->dev, "Invalid descriptor length: %d\n", ++ union_desc->bLength); + return NULL; + } + diff --git a/queue-7.1/input-ims-pcu-fix-race-condition-in-reset_device-sysfs-callback.patch b/queue-7.1/input-ims-pcu-fix-race-condition-in-reset_device-sysfs-callback.patch new file mode 100644 index 0000000000..4e03b79603 --- /dev/null +++ b/queue-7.1/input-ims-pcu-fix-race-condition-in-reset_device-sysfs-callback.patch @@ -0,0 +1,37 @@ +From 411b8c4b274737c3bf08e1e025801161603cfffc Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:29:04 -0700 +Subject: Input: ims-pcu - fix race condition in reset_device sysfs callback + +From: Dmitry Torokhov + +commit 411b8c4b274737c3bf08e1e025801161603cfffc upstream. + +The ims_pcu_reset_device() sysfs callback calls ims_pcu_execute_command() +without acquiring pcu->cmd_mutex. This can lead to data races and +corruption of the shared command buffer if triggered concurrently with +other commands. + +Acquire pcu->cmd_mutex before calling ims_pcu_execute_command(). + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -1186,6 +1186,8 @@ static ssize_t ims_pcu_reset_device(stru + + dev_info(pcu->dev, "Attempting to reset device\n"); + ++ guard(mutex)(&pcu->cmd_mutex); ++ + error = ims_pcu_execute_command(pcu, PCU_RESET, &reset_byte, 1); + if (error) { + dev_info(pcu->dev, diff --git a/queue-7.1/input-ims-pcu-fix-type-confusion-in-cdc-union-descriptor-parsing.patch b/queue-7.1/input-ims-pcu-fix-type-confusion-in-cdc-union-descriptor-parsing.patch new file mode 100644 index 0000000000..415d630330 --- /dev/null +++ b/queue-7.1/input-ims-pcu-fix-type-confusion-in-cdc-union-descriptor-parsing.patch @@ -0,0 +1,38 @@ +From ca459e237bc49567649c56bc72e4c602fb92fd67 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:25:11 -0700 +Subject: Input: ims-pcu - fix type confusion in CDC union descriptor parsing + +From: Dmitry Torokhov + +commit ca459e237bc49567649c56bc72e4c602fb92fd67 upstream. + +The driver currently trusts the bMasterInterface0 from the CDC union +descriptor without verifying that it matches the interface being +probed. This could lead to the driver overwriting the private data of +another interface. + +Validate that the control interface found in the descriptor is indeed +the one we are probing. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -1747,7 +1747,7 @@ static int ims_pcu_parse_cdc_data(struct + + pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev, + union_desc->bMasterInterface0); +- if (!pcu->ctrl_intf) ++ if (pcu->ctrl_intf != intf) + return -EINVAL; + + alt = pcu->ctrl_intf->cur_altsetting; diff --git a/queue-7.1/input-ims-pcu-fix-use-after-free-and-double-free-in-disconnect.patch b/queue-7.1/input-ims-pcu-fix-use-after-free-and-double-free-in-disconnect.patch new file mode 100644 index 0000000000..70cca10934 --- /dev/null +++ b/queue-7.1/input-ims-pcu-fix-use-after-free-and-double-free-in-disconnect.patch @@ -0,0 +1,48 @@ +From 462a999917755a3bf77448dfd64307963cf0a9f0 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:24:47 -0700 +Subject: Input: ims-pcu - fix use-after-free and double-free in disconnect + +From: Dmitry Torokhov + +commit 462a999917755a3bf77448dfd64307963cf0a9f0 upstream. + +ims_pcu_disconnect() only intended to perform cleanup when the primary +(control) interface is unbound. However, it currently relies on the +interface class to distinguish between control and data interfaces. +A malicious device could present a data interface with the same class +as the control interface, leading to premature cleanup and potential +use-after-free or double-free. + +Switch to verifying that the interface being disconnected is indeed +the control interface. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -2071,7 +2071,6 @@ err_free_mem: + static void ims_pcu_disconnect(struct usb_interface *intf) + { + struct ims_pcu *pcu = usb_get_intfdata(intf); +- struct usb_host_interface *alt = intf->cur_altsetting; + + usb_set_intfdata(intf, NULL); + +@@ -2079,7 +2078,7 @@ static void ims_pcu_disconnect(struct us + * See if we are dealing with control or data interface. The cleanup + * happens when we unbind primary (control) interface. + */ +- if (alt->desc.bInterfaceClass != USB_CLASS_COMM) ++ if (intf != pcu->ctrl_intf) + return; + + ims_pcu_stop_io(pcu); diff --git a/queue-7.1/input-ims-pcu-only-expose-sysfs-attributes-on-control-interface.patch b/queue-7.1/input-ims-pcu-only-expose-sysfs-attributes-on-control-interface.patch new file mode 100644 index 0000000000..364c5b98a2 --- /dev/null +++ b/queue-7.1/input-ims-pcu-only-expose-sysfs-attributes-on-control-interface.patch @@ -0,0 +1,66 @@ +From 001428ea4d2c371107cb984108e266adf99f1f1e Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Sun, 31 May 2026 21:42:35 -0700 +Subject: Input: ims-pcu - only expose sysfs attributes on control interface + +From: Dmitry Torokhov + +commit 001428ea4d2c371107cb984108e266adf99f1f1e upstream. + +When the driver was converted to use the driver core to instantiate device +attributes (via .dev_groups in the usb_driver structure), the attributes +started appearing on all interfaces bound to the driver. Since the ims-pcu +driver manually claims the secondary data interface during probe, the +driver core automatically creates the sysfs attributes for that interface +as well. + +However, the driver only supports these attributes on the primary control +interface. Data interfaces lack the necessary descriptors and internal +state to handle these requests, and accessing them can lead to unexpected +behavior or crashes. + +Fix this by updating the is_visible() callbacks for both the main and OFN +attribute groups to verify that the interface being accessed is indeed the +control interface. + +Fixes: 204d18a7a0c6 ("Input: ims-pcu - use driver core to instantiate device attributes") +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/ahp23lj4_vXIeUBl@google.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1249,6 +1250,9 @@ static umode_t ims_pcu_is_attr_visible(s + struct ims_pcu *pcu = usb_get_intfdata(intf); + umode_t mode = attr->mode; + ++ if (intf != pcu->ctrl_intf) ++ return 0; ++ + if (pcu->bootloader_mode) { + if (attr != &dev_attr_update_firmware_status.attr && + attr != &dev_attr_update_firmware.attr && +@@ -1488,6 +1492,9 @@ static umode_t ims_pcu_ofn_is_attr_visib + struct ims_pcu *pcu = usb_get_intfdata(intf); + umode_t mode = attr->mode; + ++ if (intf != pcu->ctrl_intf) ++ return SYSFS_GROUP_INVISIBLE; ++ + /* + * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor. + */ diff --git a/queue-7.1/input-ims-pcu-release-data-interface-on-disconnect.patch b/queue-7.1/input-ims-pcu-release-data-interface-on-disconnect.patch new file mode 100644 index 0000000000..fb65c9d99b --- /dev/null +++ b/queue-7.1/input-ims-pcu-release-data-interface-on-disconnect.patch @@ -0,0 +1,32 @@ +From 441c510a649c8ddce38aa0311334ed8bb546b36c Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:22:55 -0700 +Subject: Input: ims-pcu - release data interface on disconnect + +From: Dmitry Torokhov + +commit 441c510a649c8ddce38aa0311334ed8bb546b36c upstream. + +During probe the driver claims the data interface, but it never releases +it. Release it in disconnect to avoid leaving it permanently claimed. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -2096,6 +2096,7 @@ static void ims_pcu_disconnect(struct us + ims_pcu_destroy_application_mode(pcu); + + ims_pcu_buffers_free(pcu); ++ usb_driver_release_interface(&ims_pcu_driver, pcu->data_intf); + kfree(pcu); + } + diff --git a/queue-7.1/input-ims-pcu-validate-control-endpoint-type.patch b/queue-7.1/input-ims-pcu-validate-control-endpoint-type.patch new file mode 100644 index 0000000000..98edfc2319 --- /dev/null +++ b/queue-7.1/input-ims-pcu-validate-control-endpoint-type.patch @@ -0,0 +1,42 @@ +From baf56975806534268e24acf9a8abb1c447ce11e9 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 22 May 2026 10:29:26 -0700 +Subject: Input: ims-pcu - validate control endpoint type + +From: Dmitry Torokhov + +commit baf56975806534268e24acf9a8abb1c447ce11e9 upstream. + +The driver currently assumes that the first endpoint of the control +interface is an interrupt IN endpoint without verifying it. A malicious +device could provide a different endpoint type, which would then be +passed to usb_fill_int_urb(), potentially leading to kernel warnings +or undefined behavior. + +Verify that the control endpoint is an interrupt IN endpoint. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Cc: stable@vger.kernel.org +Reported-by: Sashiko bot +Assisted-by: Gemini:gemini-3.1-pro +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -1709,6 +1709,12 @@ static int ims_pcu_parse_cdc_data(struct + return -ENODEV; + + pcu->ep_ctrl = &alt->endpoint[0].desc; ++ if (!usb_endpoint_is_int_in(pcu->ep_ctrl)) { ++ dev_err(pcu->dev, ++ "Control endpoint is not INTERRUPT IN\n"); ++ return -EINVAL; ++ } ++ + pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl); + + pcu->data_intf = usb_ifnum_to_if(pcu->udev, diff --git a/queue-7.1/mmc-vub300-fix-use-after-free-on-probe-failure.patch b/queue-7.1/mmc-vub300-fix-use-after-free-on-probe-failure.patch new file mode 100644 index 0000000000..34940975d7 --- /dev/null +++ b/queue-7.1/mmc-vub300-fix-use-after-free-on-probe-failure.patch @@ -0,0 +1,85 @@ +From a3b5f242997a3be7404112fd48784881560aea57 Mon Sep 17 00:00:00 2001 +From: Guangshuo Li +Date: Fri, 12 Jun 2026 11:27:56 +0800 +Subject: mmc: vub300: fix use-after-free on probe failure + +From: Guangshuo Li + +commit a3b5f242997a3be7404112fd48784881560aea57 upstream. + +The vub300 driver lifetime-manages its controller state using +vub300->kref, with vub300_delete() freeing the mmc host when the last +reference is dropped. The probe error path after the inactivity timer has +been armed still bypasses that lifetime rule, however, and falls through +to mmc_free_host() directly if mmc_add_host() fails. + +The race window is between arming the inactivity timer and reaching the +probe error unwind after mmc_add_host() fails: + + probe thread timer/workqueue + ------------ --------------- + kref_init(&vub300->kref) ref = 1 + kref_get(&vub300->kref) ref = 2, timer ref + add_timer(inactivity_timer) fires after one second + | + | race window + |<----------------------------------------------------> + | + mmc_add_host(mmc) + inactivity timer fires + vub300_queue_dead_work() + kref_get() ref = 3 + queue_work(deadwork) + mmc_add_host() fails + timer_delete_sync() + mmc_free_host(mmc) + frees vub300 + deadwork runs + use-after-free + +The inactivity timeout is one second, so this would require +mmc_add_host() to both fail and take more than one second to do so. This +is unlikely to happen in practice, but the error path is still wrong. + +timer_delete_sync() only waits for the timer callback itself. It does +not flush deadwork that the callback may already have queued. As a +result, queued deadwork can still hold a kref while the probe error path +directly frees the backing mmc host, including the vub300 storage. + +Fix this by using the same lifetime mechanism as disconnect. Clear +vub300->interface so that the timer callback and any queued deadwork +return early and drop their references, then drop the initial probe +reference and return without falling through to err_free_host. + +Fixes: 0613ad2401f8 ("mmc: vub300: fix return value check of mmc_add_host()") +Signed-off-by: Guangshuo Li +Reviewed-by: Johan Hovold +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/vub300.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/mmc/host/vub300.c ++++ b/drivers/mmc/host/vub300.c +@@ -2336,12 +2336,16 @@ static int vub300_probe(struct usb_inter + interface_to_InterfaceNumber(interface)); + retval = mmc_add_host(mmc); + if (retval) +- goto err_delete_timer; ++ goto err_stop_io; + + return 0; + +-err_delete_timer: +- timer_delete_sync(&vub300->inactivity_timer); ++err_stop_io: ++ vub300->interface = NULL; ++ kref_put(&vub300->kref, vub300_delete); ++ ++ return retval; ++ + err_free_host: + mmc_free_host(mmc); + /* diff --git a/queue-7.1/net-mlx5e-macsec-fix-use-after-free-of-metadata_dst-on-rx-sc-delete.patch b/queue-7.1/net-mlx5e-macsec-fix-use-after-free-of-metadata_dst-on-rx-sc-delete.patch new file mode 100644 index 0000000000..35831c6b62 --- /dev/null +++ b/queue-7.1/net-mlx5e-macsec-fix-use-after-free-of-metadata_dst-on-rx-sc-delete.patch @@ -0,0 +1,135 @@ +From de74d8fd10291763d97b218f09adcc7513c975e4 Mon Sep 17 00:00:00 2001 +From: Doruk Tan Ozturk +Date: Sun, 28 Jun 2026 00:30:59 +0200 +Subject: net/mlx5e: macsec: fix use-after-free of metadata_dst on RX SC delete + +From: Doruk Tan Ozturk + +commit de74d8fd10291763d97b218f09adcc7513c975e4 upstream. + +When an offloaded MACsec RX SC is deleted, macsec_del_rxsc_ctx() freed +the per-SC metadata_dst with metadata_dst_free(), which kfree()s the +object unconditionally and ignores the dst reference count. The RX +datapath in mlx5e_macsec_offload_handle_rx_skb() looks up the SC under +rcu_read_lock() via xa_load(), takes a reference with dst_hold() and +attaches the dst to the skb with skb_dst_set(). A reader that already +obtained the rx_sc pointer can race with the delete path and operate on +freed memory. + +Fix the owner side by dropping the reference with dst_release() instead +of freeing unconditionally, and convert the RX datapath to +dst_hold_safe() so a reader racing the SC delete cannot attach a dst +whose last reference was just dropped; only attach it when a reference +was actually taken. + +mlx5e_macsec_add_rxsc() also published sc_xarray_element via xa_alloc() +before rx_sc->md_dst was allocated and initialised, so a datapath reader +that looked the SC up by fs_id could observe rx_sc with md_dst still +NULL or, on weakly-ordered architectures, a non-NULL md_dst pointer +whose contents were not yet visible. NULL-check the xa_load() result and +md_dst on the datapath, and reorder add_rxsc() so the xa_alloc() publish +happens only after md_dst is fully initialised; the xarray RCU publish +then pairs with the rcu_read_lock()/xa_load() in the datapath. + +Note: macsec_del_rxsc_ctx() also kfree()s rx_sc->sc_xarray_element +without an RCU grace period while the same datapath reads it under +rcu_read_lock(); that is a separate pre-existing issue left to a +follow-up patch. + +Found by 0sec automated security-research tooling (https://0sec.ai). + +Fixes: b7c9400cbc48 ("net/mlx5e: Implement MACsec Rx data path using MACsec skb_metadata_dst") +Cc: stable@vger.kernel.org +Signed-off-by: Doruk Tan Ozturk +Reviewed-by: Tariq Toukan +Link: https://patch.msgid.link/20260627223059.29917-1-doruk@0sec.ai +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 47 ++++++++------ + 1 file changed, 28 insertions(+), 19 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +@@ -714,34 +714,43 @@ static int mlx5e_macsec_add_rxsc(struct + } + + sc_xarray_element->rx_sc = rx_sc; +- err = xa_alloc(&macsec->sc_xarray, &sc_xarray_element->fs_id, sc_xarray_element, +- XA_LIMIT(1, MLX5_MACEC_RX_FS_ID_MAX), GFP_KERNEL); +- if (err) { +- if (err == -EBUSY) +- netdev_err(ctx->netdev, +- "MACsec offload: unable to create entry for RX SC (%d Rx SCs already allocated)\n", +- MLX5_MACEC_RX_FS_ID_MAX); +- goto destroy_sc_xarray_elemenet; +- } + + rx_sc->md_dst = metadata_dst_alloc(0, METADATA_MACSEC, GFP_KERNEL); + if (!rx_sc->md_dst) { + err = -ENOMEM; +- goto erase_xa_alloc; ++ goto destroy_sc_xarray_elemenet; + } + + rx_sc->sci = ctx_rx_sc->sci; + rx_sc->active = ctx_rx_sc->active; +- list_add_rcu(&rx_sc->rx_sc_list_element, rx_sc_list); +- + rx_sc->sc_xarray_element = sc_xarray_element; + rx_sc->md_dst->u.macsec_info.sci = rx_sc->sci; ++ ++ /* ++ * Publish the fully-initialised SC last: xa_alloc() makes ++ * sc_xarray_element->rx_sc (and rx_sc->md_dst) reachable from the RX ++ * datapath via xa_load(). Doing it only after md_dst is allocated and ++ * initialised pairs with the rcu_read_lock()/xa_load() in ++ * mlx5e_macsec_offload_handle_rx_skb(), so a reader can never observe ++ * a non-NULL md_dst with uninitialised contents. ++ */ ++ err = xa_alloc(&macsec->sc_xarray, &sc_xarray_element->fs_id, sc_xarray_element, ++ XA_LIMIT(1, MLX5_MACEC_RX_FS_ID_MAX), GFP_KERNEL); ++ if (err) { ++ if (err == -EBUSY) ++ netdev_err(ctx->netdev, ++ "MACsec offload: unable to create entry for RX SC (%d Rx SCs already allocated)\n", ++ MLX5_MACEC_RX_FS_ID_MAX); ++ goto destroy_md_dst; ++ } ++ ++ list_add_rcu(&rx_sc->rx_sc_list_element, rx_sc_list); + mutex_unlock(&macsec->lock); + + return 0; + +-erase_xa_alloc: +- xa_erase(&macsec->sc_xarray, sc_xarray_element->fs_id); ++destroy_md_dst: ++ dst_release(&rx_sc->md_dst->dst); + destroy_sc_xarray_elemenet: + kfree(sc_xarray_element); + destroy_rx_sc: +@@ -829,7 +838,7 @@ static void macsec_del_rxsc_ctx(struct m + */ + list_del_rcu(&rx_sc->rx_sc_list_element); + xa_erase(&macsec->sc_xarray, rx_sc->sc_xarray_element->fs_id); +- metadata_dst_free(rx_sc->md_dst); ++ dst_release(&rx_sc->md_dst->dst); + kfree(rx_sc->sc_xarray_element); + kfree_rcu_mightsleep(rx_sc); + } +@@ -1695,10 +1704,10 @@ void mlx5e_macsec_offload_handle_rx_skb( + + rcu_read_lock(); + sc_xarray_element = xa_load(&macsec->sc_xarray, fs_id); +- rx_sc = sc_xarray_element->rx_sc; +- if (rx_sc) { +- dst_hold(&rx_sc->md_dst->dst); +- skb_dst_set(skb, &rx_sc->md_dst->dst); ++ rx_sc = sc_xarray_element ? sc_xarray_element->rx_sc : NULL; ++ if (rx_sc && rx_sc->md_dst) { ++ if (dst_hold_safe(&rx_sc->md_dst->dst)) ++ skb_dst_set(skb, &rx_sc->md_dst->dst); + } + + rcu_read_unlock(); diff --git a/queue-7.1/series b/queue-7.1/series index 1b9ec0aa69..acaaa39935 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -1888,3 +1888,20 @@ scsi-target-bound-pr-out-transportid-parsing-to-the-received-buffer.patch scsi-target-core-fix-iscsi-isid-use-after-free-in-register-and-move.patch scsi-elx-efct-fix-refcount-leak-in-efct_hw_io_abort.patch scsi-elx-efct-fix-i-o-leak-on-unsupported-additional-cdb.patch +fs-resctrl-fix-use-after-free-during-unmount.patch +input-ims-pcu-fix-use-after-free-and-double-free-in-disconnect.patch +input-ims-pcu-only-expose-sysfs-attributes-on-control-interface.patch +input-ims-pcu-release-data-interface-on-disconnect.patch +input-ims-pcu-validate-control-endpoint-type.patch +input-ims-pcu-add-response-length-checks.patch +input-ims-pcu-fix-dma-mapping-violation-in-line-setup.patch +input-ims-pcu-fix-firmware-leak-in-async-update.patch +input-ims-pcu-fix-logic-error-in-packet-reset.patch +input-ims-pcu-fix-out-of-bounds-read-in-ims_pcu_irq-debug-logging.patch +input-ims-pcu-fix-potential-infinite-loop-in-cdc-union-descriptor-parsing.patch +input-ims-pcu-fix-race-condition-in-reset_device-sysfs-callback.patch +input-ims-pcu-fix-type-confusion-in-cdc-union-descriptor-parsing.patch +mmc-vub300-fix-use-after-free-on-probe-failure.patch +net-mlx5e-macsec-fix-use-after-free-of-metadata_dst-on-rx-sc-delete.patch +tracing-user_events-fix-use-after-free-in-user_event_mm_dup.patch +wifi-libertas_tf-fix-use-after-free-in-lbtf_free_adapter.patch diff --git a/queue-7.1/tracing-user_events-fix-use-after-free-in-user_event_mm_dup.patch b/queue-7.1/tracing-user_events-fix-use-after-free-in-user_event_mm_dup.patch new file mode 100644 index 0000000000..0d7f5f45ec --- /dev/null +++ b/queue-7.1/tracing-user_events-fix-use-after-free-in-user_event_mm_dup.patch @@ -0,0 +1,144 @@ +From 50fd6dd755c6e48a38af2fa4621167eea56829c2 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Tue, 7 Jul 2026 12:59:11 -0400 +Subject: tracing/user_events: Fix use-after-free in user_event_mm_dup() + +From: Michael Bommarito + +commit 50fd6dd755c6e48a38af2fa4621167eea56829c2 upstream. + +user_event_mm_dup() walks the parent mm's enabler list locklessly under +rcu_read_lock() during fork() (from copy_process()); it does not take +event_mutex: + + rcu_read_lock(); + list_for_each_entry_rcu(enabler, &old_mm->enablers, mm_enablers_link) + enabler->event = user_event_get(orig->event); + +user_event_enabler_destroy() removes an enabler from that list with +list_del_rcu() and then, without waiting for a grace period, drops the +enabler's user_event reference with user_event_put() and frees the enabler +with kfree(). A reader that loaded the enabler before the list_del_rcu() +can still be walking it, which leads to two use-after-frees: + + - kfree(enabler) frees the enabler while that reader dereferences + enabler->event. + + - user_event_put() may drop the last reference to the user_event, which + is then freed (via delayed_destroy_user_event() on a work queue), while + the same reader does user_event_get(orig->event) on it. + +Both are reachable by an unprivileged task that can open user_events_data: +one multithreaded process that registers an enabler and then concurrently +unregisters it and calls fork() triggers the race. KASAN reports a +slab-use-after-free in user_event_mm_dup() during clone(), with a +"refcount_t: addition on 0" warning when the user_event is freed. + +The enabler use-after-free was found first; the user_event one was reported +by XIAO WU, and the earlier enabler-only fix did not address it. + +Defer both the user_event_put() and the kfree(enabler) to a work item +queued with queue_rcu_work(), so they run only after an RCU grace period, +once all readers walking the enabler list have finished. The put must run +in process context because user_event_put() takes event_mutex on the last +reference, so a work queue is used rather than call_rcu(). The now-unlocked +put lets the locked argument of user_event_enabler_destroy() be removed; +all callers are updated. + +Fixes: 7235759084a4 ("tracing/user_events: Use remote writes for event enablement") +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260707165912.2560537-2-michael.bommarito@gmail.com +Reported-by: XIAO WU +Closes: https://lore.kernel.org/all/tencent_89647CE40DC452B891C65C94D1B271DE8E07@qq.com/ +Suggested-by: Beau Belgrave +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Michael Bommarito +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace_events_user.c | 39 ++++++++++++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 7 deletions(-) + +--- a/kernel/trace/trace_events_user.c ++++ b/kernel/trace/trace_events_user.c +@@ -109,6 +109,9 @@ struct user_event_enabler { + + /* Track enable bit, flags, etc. Aligned for bitops. */ + unsigned long values; ++ ++ /* Defer the event put and enabler free past an RCU grace period. */ ++ struct rcu_work put_rwork; + }; + + /* Bits 0-5 are for the bit to update upon enable/disable (0-63 allowed) */ +@@ -396,17 +399,39 @@ error: + return NULL; + }; + +-static void user_event_enabler_destroy(struct user_event_enabler *enabler, +- bool locked) ++static void delayed_user_event_enabler_put(struct work_struct *work) + { +- list_del_rcu(&enabler->mm_enablers_link); ++ struct user_event_enabler *enabler = container_of(to_rcu_work(work), ++ struct user_event_enabler, put_rwork); + + /* No longer tracking the event via the enabler */ +- user_event_put(enabler->event, locked); ++ user_event_put(enabler->event, false); + ++ /* Run from queue_rcu_work(), the RCU grace period has elapsed */ + kfree(enabler); + } + ++static void user_event_enabler_destroy(struct user_event_enabler *enabler) ++{ ++ list_del_rcu(&enabler->mm_enablers_link); ++ ++ /* ++ * The enabler is removed from an RCU-traversed list ++ * (user_event_mm_dup() walks mm->enablers under rcu_read_lock() only), ++ * and readers there dereference enabler->event and take a new ref on ++ * it. Both the put of that event reference and the free of the enabler ++ * therefore have to wait for a grace period so no reader can be looking ++ * at the enabler or racing the last put of its event. ++ * ++ * The put itself must not run in RCU context: when it drops the last ++ * reference user_event_put() takes event_mutex, which cannot be taken ++ * from a softirq/RCU callback. Defer both to a work item scheduled ++ * after a grace period via queue_rcu_work(). ++ */ ++ INIT_RCU_WORK(&enabler->put_rwork, delayed_user_event_enabler_put); ++ queue_rcu_work(system_percpu_wq, &enabler->put_rwork); ++} ++ + static int user_event_mm_fault_in(struct user_event_mm *mm, unsigned long uaddr, + int attempt) + { +@@ -464,7 +489,7 @@ static void user_event_enabler_fault_fix + + /* User asked for enabler to be removed during fault */ + if (test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler))) { +- user_event_enabler_destroy(enabler, true); ++ user_event_enabler_destroy(enabler); + goto out; + } + +@@ -764,7 +789,7 @@ static void user_event_mm_destroy(struct + struct user_event_enabler *enabler, *next; + + list_for_each_entry_safe(enabler, next, &mm->enablers, mm_enablers_link) +- user_event_enabler_destroy(enabler, false); ++ user_event_enabler_destroy(enabler); + + mmdrop(mm->mm); + kfree(mm); +@@ -2645,7 +2670,7 @@ static long user_events_ioctl_unreg(unsi + flags |= enabler->values & ENABLE_VAL_COMPAT_MASK; + + if (!test_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler))) +- user_event_enabler_destroy(enabler, true); ++ user_event_enabler_destroy(enabler); + + /* Removed at least one */ + ret = 0; diff --git a/queue-7.1/wifi-libertas_tf-fix-use-after-free-in-lbtf_free_adapter.patch b/queue-7.1/wifi-libertas_tf-fix-use-after-free-in-lbtf_free_adapter.patch new file mode 100644 index 0000000000..9130b7fb56 --- /dev/null +++ b/queue-7.1/wifi-libertas_tf-fix-use-after-free-in-lbtf_free_adapter.patch @@ -0,0 +1,45 @@ +From aa6dcd5c8dd9ba1d7d0f60093bcda41c0d6d438d Mon Sep 17 00:00:00 2001 +From: Maoyi Xie +Date: Mon, 22 Jun 2026 15:53:38 +0800 +Subject: wifi: libertas_tf: fix use-after-free in lbtf_free_adapter() + +From: Maoyi Xie + +commit aa6dcd5c8dd9ba1d7d0f60093bcda41c0d6d438d upstream. + +lbtf_free_adapter() calls timer_delete(&priv->command_timer), which does +not wait for a running command_timer_fn() callback. lbtf_free_adapter() +runs on the teardown path right before ieee80211_free_hw() frees priv, +both in lbtf_remove_card() and in the probe error path. command_timer is +armed by mod_timer() in lbtf_cmd() whenever a firmware command is sent. +command_timer_fn() dereferences priv. If a command times out as the +device is removed, command_timer_fn() runs concurrently with teardown and +dereferences priv after it has been freed. + +This is the same use-after-free that commit 03cc8f90d053 ("wifi: libertas: +fix use-after-free in lbs_free_adapter()") fixed in the sibling libertas +driver. The libertas_tf variant has the identical pattern and was left +unchanged. Use timer_delete_sync() so any in-flight callback completes +before priv is freed. + +Fixes: 06b16ae53192 ("libertas_tf: main.c, data paths and mac80211 handlers") +Cc: stable@vger.kernel.org +Signed-off-by: Maoyi Xie +Link: https://patch.msgid.link/178211481807.2212567.8773346114561900100@maoyixie.com +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/marvell/libertas_tf/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/marvell/libertas_tf/main.c ++++ b/drivers/net/wireless/marvell/libertas_tf/main.c +@@ -174,7 +174,7 @@ static void lbtf_free_adapter(struct lbt + { + lbtf_deb_enter(LBTF_DEB_MAIN); + lbtf_free_cmd_buffer(priv); +- timer_delete(&priv->command_timer); ++ timer_delete_sync(&priv->command_timer); + lbtf_deb_leave(LBTF_DEB_MAIN); + } +