From 99322873ca8c886385a889b48fe9ef1674ad4ba9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 4 Jun 2026 10:54:47 +0200 Subject: [PATCH] 7.0-stable patches added patches: auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch bluetooth-hci_conn-fix-memory-leak-in-hci_le_big_terminate.patch bluetooth-hci_qca-use-100-ms-ssr-delay-for-rampatch-and-nvm-loading.patch bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch bluetooth-iso-fix-uaf-in-iso_recv_frame.patch bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch disable-wattribute-alias-for-clang-23-and-newer.patch gpio-shared-fix-deadlock-on-shared-proxy-s-parent-removal.patch gpio-shared-fix-lockdep-false-positive-by-removing-unneeded-lock.patch gpio-shared-undo-the-vote-of-the-proxy-on-gpio-free.patch hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch i2c-davinci-fix-division-by-zero-on-missing-clock-frequency.patch iio-adc-ad4695-fix-call-ordering-in-offload-buffer-postenable.patch iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch iio-adc-nxp-sar-adc-avoid-division-by-zero.patch iio-adc-nxp-sar-adc-fix-division-by-zero-in-write_raw.patch iio-adc-nxp-sar-adc-zero-initialize-dma_slave_config.patch iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch iio-chemical-mhz19b-reject-oversized-serial-replies.patch iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch iio-dac-ad3530r-fix-ad3531-ad3531r-powerdown-mode-strings.patch iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch iio-dac-ad5686-fix-input-raw-value-check.patch iio-dac-ad5686-fix-powerdown-control-on-dual-channel-devices.patch iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch iio-fix-iio_multiply_value-use-in-iio_read_channel_processed_scale.patch iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch iio-light-veml6070-fix-resource-leak-in-probe-error-path.patch iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch input-elan_i2c-validate-firmware-size-before-use.patch input-xpad-fix-out-of-bounds-access-for-share-button.patch ipc-limit-next_id-allocation-to-the-valid-id-range.patch kvm-arm64-correctly-cap-zcr_el2-provided-by-a-guest-hypervisor.patch kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch kvm-sev-ignore-port-i-o-requests-of-length-0.patch kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch memfd-deny-writeable-mappings-when-implying-seal_write.patch mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch mm-memcontrol-propagate-nmi-slab-stats-to-memcg-vmstats.patch mm-migrate_device-fix-pgtable-leak-in-migrate_vma_insert_huge_pmd_page.patch mm-rmap-initialize-nr_pages-to-1-at-loop-start-in-try_to_unmap_one.patch mm-vmalloc-do-not-trigger-bug-on-bh-disabled-context.patch parport-fix-race-between-port-and-client-registration.patch rust_binder-avoid-calling-pending_oneway_finished-on-tf_update_txn.patch rust_binder-avoid-holding-lock-when-dropping-delivered_death.patch smb-client-fix-uninitialized-variable-in-smb2_writev_callback.patch usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch usb-cdns3-plat-fix-unbalanced-pm_runtime_forbid-call-permanently-leaks-the-runtime-pm-usage-counter-across-bind-unbind-cycles.patch usb-dwc2-fix-use-after-free-in-debug-code.patch usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch zram-fix-use-after-free-in-zram_writeback_endio.patch --- ...ob-read-on-zero-length-message_store.patch | 62 +++++++ ...-memory-leak-in-hci_le_big_terminate.patch | 41 +++++ ...r-delay-for-rampatch-and-nvm-loading.patch | 54 ++++++ ...nc-fix-uaf-in-hci_le_create_cis_sync.patch | 76 +++++++++ ...g-length-checks-in-hidp_input_report.patch | 80 +++++++++ ...etooth-iso-fix-uaf-in-iso_recv_frame.patch | 57 +++++++ ...so_sock_clear_timer-with-socket-lock.patch | 59 +++++++ ...f-leak-in-l2cap_chan_timeout-on-conn.patch | 40 +++++ ...-to-close-channels-in-cleanup_listen.patch | 69 ++++++++ ...tribute-alias-for-clang-23-and-newer.patch | 126 ++++++++++++++ ...ock-on-shared-proxy-s-parent-removal.patch | 63 +++++++ ...e-positive-by-removing-unneeded-lock.patch | 42 +++++ ...o-the-vote-of-the-proxy-on-gpio-free.patch | 47 ++++++ ...crash-if-hpfs_map_dnode_bitmap-fails.patch | 32 ++++ ...n-by-zero-on-missing-clock-frequency.patch | 47 ++++++ ...rdering-in-offload-buffer-postenable.patch | 87 ++++++++++ ...cked-return-value-in-mt6358_read_imp.patch | 38 +++++ ...fix-unbalanced-clk_disable_unprepare.patch | 108 ++++++++++++ ...c-nxp-sar-adc-avoid-division-by-zero.patch | 69 ++++++++ ...dc-fix-division-by-zero-in-write_raw.patch | 52 ++++++ ...adc-zero-initialize-dma_slave_config.patch | 37 ++++ ...rror-handling-in-vprbrd_iio_read_raw.patch | 44 +++++ ...cer-mode-in-postdisable-for-dual-mux.patch | 75 +++++++++ ...ce-leak-in-iio_buffer_enqueue_dmabuf.patch | 55 ++++++ ...mer-fix-use-after-free-in-error-path.patch | 54 ++++++ ...z19b-reject-oversized-serial-replies.patch | 77 +++++++++ ...30-fix-division-by-zero-in-write_raw.patch | 34 ++++ ...d3531-ad3531r-powerdown-mode-strings.patch | 121 +++++++++++++ ...re-lock-when-doing-powerdown-control.patch | 63 +++++++ ...dac-ad5686-fix-input-raw-value-check.patch | 35 ++++ ...down-control-on-dual-channel-devices.patch | 130 ++++++++++++++ ...tialization-for-single-channel-parts.patch | 60 +++++++ ...return-value-check-in-powerdown-sync.patch | 54 ++++++ ...-in-iio_read_channel_processed_scale.patch | 41 +++++ ...60-fix-division-by-zero-in-write_raw.patch | 38 +++++ ...c-read-into-the-wrong-stack-location.patch | 53 ++++++ ...conf-not-being-initialized-correctly.patch | 66 ++++++++ ...ix-resource-leak-in-probe-error-path.patch | 64 +++++++ ...fault-drdy-pin-selection-for-lis2mdl.patch | 60 +++++++ ...ancel-delayed-work_refresh-on-remove.patch | 31 ++++ ...-fix-broken-prom-checksum-validation.patch | 41 +++++ ...2c-validate-firmware-size-before-use.patch | 36 ++++ ...ut-of-bounds-access-for-share-button.patch | 45 +++++ ..._id-allocation-to-the-valid-id-range.patch | 81 +++++++++ ...r_el2-provided-by-a-guest-hypervisor.patch | 159 ++++++++++++++++++ ...mu-preserve-aarch32-counter-low-bits.patch | 46 +++++ ...gainst-the-actual-size-of-the-buffer.patch | 66 ++++++++ ...x-length-of-the-in-ghcb-scratch-area.patch | 101 +++++++++++ ...tly-pass-psc-buffer-to-snp_begin_psc.patch | 70 ++++++++ ...ignore-port-i-o-requests-of-length-0.patch | 49 ++++++ ...cb-scratch-area-if-ghcb-v2-is-in-use.patch | 108 ++++++++++++ ...ding-entries-indices-from-psc-buffer.patch | 71 ++++++++ ...as-the-minimum-size-for-psc-requests.patch | 42 +++++ ...to-setup-scratch-area-with-min_len-0.patch | 37 ++++ ...when-transitioning-from-xavic-x2avic.patch | 83 +++++++++ ...le-mappings-when-implying-seal_write.patch | 67 ++++++++ ...elete-tried-region-in-regions_rmdirs.patch | 90 ++++++++++ ...gate-nmi-slab-stats-to-memcg-vmstats.patch | 57 +++++++ ...-in-migrate_vma_insert_huge_pmd_page.patch | 55 ++++++ ...-1-at-loop-start-in-try_to_unmap_one.patch | 72 ++++++++ ...t-trigger-bug-on-bh-disabled-context.patch | 57 +++++++ ...between-port-and-client-registration.patch | 109 ++++++++++++ ...ing_oneway_finished-on-tf_update_txn.patch | 86 ++++++++++ ...g-lock-when-dropping-delivered_death.patch | 52 ++++++ queue-7.0/series | 73 ++++++++ ...zed-variable-in-smb2_writev_callback.patch | 31 ++++ ...and-move-quirk-definitions-to-header.patch | 49 ++++++ ...request-skipping-after-clearing-halt.patch | 67 ++++++++ ...tion-on-usb3_phy-acquisition-failure.patch | 45 +++++ ...ge-counter-across-bind-unbind-cycles.patch | 35 ++++ ...wc2-fix-use-after-free-in-debug-code.patch | 46 +++++ ...emory-corruption-with-small-endpoint.patch | 55 ++++++ ...e-percpu-refs-in-dynamic-trampolines.patch | 102 +++++++++++ ...e-after-free-in-zram_writeback_endio.patch | 114 +++++++++++++ 74 files changed, 4738 insertions(+) create mode 100644 queue-7.0/auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch create mode 100644 queue-7.0/bluetooth-hci_conn-fix-memory-leak-in-hci_le_big_terminate.patch create mode 100644 queue-7.0/bluetooth-hci_qca-use-100-ms-ssr-delay-for-rampatch-and-nvm-loading.patch create mode 100644 queue-7.0/bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch create mode 100644 queue-7.0/bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch create mode 100644 queue-7.0/bluetooth-iso-fix-uaf-in-iso_recv_frame.patch create mode 100644 queue-7.0/bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch create mode 100644 queue-7.0/bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch create mode 100644 queue-7.0/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch create mode 100644 queue-7.0/disable-wattribute-alias-for-clang-23-and-newer.patch create mode 100644 queue-7.0/gpio-shared-fix-deadlock-on-shared-proxy-s-parent-removal.patch create mode 100644 queue-7.0/gpio-shared-fix-lockdep-false-positive-by-removing-unneeded-lock.patch create mode 100644 queue-7.0/gpio-shared-undo-the-vote-of-the-proxy-on-gpio-free.patch create mode 100644 queue-7.0/hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch create mode 100644 queue-7.0/i2c-davinci-fix-division-by-zero-on-missing-clock-frequency.patch create mode 100644 queue-7.0/iio-adc-ad4695-fix-call-ordering-in-offload-buffer-postenable.patch create mode 100644 queue-7.0/iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch create mode 100644 queue-7.0/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch create mode 100644 queue-7.0/iio-adc-nxp-sar-adc-avoid-division-by-zero.patch create mode 100644 queue-7.0/iio-adc-nxp-sar-adc-fix-division-by-zero-in-write_raw.patch create mode 100644 queue-7.0/iio-adc-nxp-sar-adc-zero-initialize-dma_slave_config.patch create mode 100644 queue-7.0/iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch create mode 100644 queue-7.0/iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch create mode 100644 queue-7.0/iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch create mode 100644 queue-7.0/iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch create mode 100644 queue-7.0/iio-chemical-mhz19b-reject-oversized-serial-replies.patch create mode 100644 queue-7.0/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch create mode 100644 queue-7.0/iio-dac-ad3530r-fix-ad3531-ad3531r-powerdown-mode-strings.patch create mode 100644 queue-7.0/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch create mode 100644 queue-7.0/iio-dac-ad5686-fix-input-raw-value-check.patch create mode 100644 queue-7.0/iio-dac-ad5686-fix-powerdown-control-on-dual-channel-devices.patch create mode 100644 queue-7.0/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch create mode 100644 queue-7.0/iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch create mode 100644 queue-7.0/iio-fix-iio_multiply_value-use-in-iio_read_channel_processed_scale.patch create mode 100644 queue-7.0/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch create mode 100644 queue-7.0/iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch create mode 100644 queue-7.0/iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch create mode 100644 queue-7.0/iio-light-veml6070-fix-resource-leak-in-probe-error-path.patch create mode 100644 queue-7.0/iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch create mode 100644 queue-7.0/iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch create mode 100644 queue-7.0/iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch create mode 100644 queue-7.0/input-elan_i2c-validate-firmware-size-before-use.patch create mode 100644 queue-7.0/input-xpad-fix-out-of-bounds-access-for-share-button.patch create mode 100644 queue-7.0/ipc-limit-next_id-allocation-to-the-valid-id-range.patch create mode 100644 queue-7.0/kvm-arm64-correctly-cap-zcr_el2-provided-by-a-guest-hypervisor.patch create mode 100644 queue-7.0/kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch create mode 100644 queue-7.0/kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch create mode 100644 queue-7.0/kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch create mode 100644 queue-7.0/kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch create mode 100644 queue-7.0/kvm-sev-ignore-port-i-o-requests-of-length-0.patch create mode 100644 queue-7.0/kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch create mode 100644 queue-7.0/kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch create mode 100644 queue-7.0/kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch create mode 100644 queue-7.0/kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch create mode 100644 queue-7.0/kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch create mode 100644 queue-7.0/memfd-deny-writeable-mappings-when-implying-seal_write.patch create mode 100644 queue-7.0/mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch create mode 100644 queue-7.0/mm-memcontrol-propagate-nmi-slab-stats-to-memcg-vmstats.patch create mode 100644 queue-7.0/mm-migrate_device-fix-pgtable-leak-in-migrate_vma_insert_huge_pmd_page.patch create mode 100644 queue-7.0/mm-rmap-initialize-nr_pages-to-1-at-loop-start-in-try_to_unmap_one.patch create mode 100644 queue-7.0/mm-vmalloc-do-not-trigger-bug-on-bh-disabled-context.patch create mode 100644 queue-7.0/parport-fix-race-between-port-and-client-registration.patch create mode 100644 queue-7.0/rust_binder-avoid-calling-pending_oneway_finished-on-tf_update_txn.patch create mode 100644 queue-7.0/rust_binder-avoid-holding-lock-when-dropping-delivered_death.patch create mode 100644 queue-7.0/smb-client-fix-uninitialized-variable-in-smb2_writev_callback.patch create mode 100644 queue-7.0/usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch create mode 100644 queue-7.0/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch create mode 100644 queue-7.0/usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch create mode 100644 queue-7.0/usb-cdns3-plat-fix-unbalanced-pm_runtime_forbid-call-permanently-leaks-the-runtime-pm-usage-counter-across-bind-unbind-cycles.patch create mode 100644 queue-7.0/usb-dwc2-fix-use-after-free-in-debug-code.patch create mode 100644 queue-7.0/usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch create mode 100644 queue-7.0/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch create mode 100644 queue-7.0/zram-fix-use-after-free-in-zram_writeback_endio.patch diff --git a/queue-7.0/auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch b/queue-7.0/auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch new file mode 100644 index 0000000000..b5a4785c54 --- /dev/null +++ b/queue-7.0/auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch @@ -0,0 +1,62 @@ +From a7511dcd9dd4bc55d123f9b800c8a4ed2662e5c6 Mon Sep 17 00:00:00 2001 +From: Stepan Ionichev +Date: Thu, 14 May 2026 22:43:42 +0500 +Subject: auxdisplay: line-display: fix OOB read on zero-length message_store() + +From: Stepan Ionichev + +commit a7511dcd9dd4bc55d123f9b800c8a4ed2662e5c6 upstream. + +linedisp_display() unconditionally reads msg[count - 1] before +checking whether count is zero, so a write of zero bytes to the +message sysfs attribute hits msg[-1]: + + write(fd, "", 0); + + -> message_store(..., buf, count=0) + -> linedisp_display(linedisp, buf, count=0) + -> msg[count - 1] == '\n' ; OOB read + +The kernfs write buffer for that store is a 1-byte allocation +(kernfs_fop_write_iter() does kmalloc(len + 1) with len == 0), +so msg[-1] is a 1-byte read before the slab object. On a +KASAN-enabled kernel this trips an out-of-bounds report and +panics; on stock kernels it silently reads adjacent slab data +and, if that byte happens to be '\n', the following count-- +wraps ssize_t 0 to -1 and is then passed to kmemdup_nul(). + +linedisp_display() is reached from the message_store() sysfs +callback (drivers/auxdisplay/line-display.c message attribute, +mode 0644) and from the in-tree initial-message setup with +count == -1, so the OOB path is only userspace-triggerable via +zero-byte writes; vfs_write() does not short-circuit on +count == 0 and kernfs_fop_write_iter() dispatches the store +callback regardless. + +Guard the trailing-newline trim with a count check. The +existing if (!count) block then takes the clear-display path +unchanged. + +Affects every auxdisplay driver that registers via +linedisp_register() / linedisp_attach(): ht16k33, max6959, +img-ascii-lcd, seg-led-gpio. + +Fixes: 7e76aece6f03 ("auxdisplay: Extract character line display core support") +Signed-off-by: Stepan Ionichev +Signed-off-by: Andy Shevchenko +Signed-off-by: Greg Kroah-Hartman +--- + drivers/auxdisplay/line-display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/auxdisplay/line-display.c ++++ b/drivers/auxdisplay/line-display.c +@@ -173,7 +173,7 @@ static int linedisp_display(struct lined + count = strlen(msg); + + /* if the string ends with a newline, trim it */ +- if (msg[count - 1] == '\n') ++ if (count && msg[count - 1] == '\n') + count--; + + if (!count) { diff --git a/queue-7.0/bluetooth-hci_conn-fix-memory-leak-in-hci_le_big_terminate.patch b/queue-7.0/bluetooth-hci_conn-fix-memory-leak-in-hci_le_big_terminate.patch new file mode 100644 index 0000000000..1be55f7523 --- /dev/null +++ b/queue-7.0/bluetooth-hci_conn-fix-memory-leak-in-hci_le_big_terminate.patch @@ -0,0 +1,41 @@ +From bfa9d28960ed677d556bdf097073bc3129686229 Mon Sep 17 00:00:00 2001 +From: Pavitra Jha +Date: Thu, 21 May 2026 04:04:14 -0400 +Subject: Bluetooth: hci_conn: Fix memory leak in hci_le_big_terminate() + +From: Pavitra Jha + +commit bfa9d28960ed677d556bdf097073bc3129686229 upstream. + +hci_le_big_terminate() allocates iso_list_data via kzalloc_obj but +returns 0 without freeing it when neither pa_sync_term nor big_sync_term +flags are set after evaluating the PA and BIG sync connection state. + +This early-return path was introduced when hci_le_big_terminate() was +refactored to take struct hci_conn instead of raw u8 parameters, adding +PA/BIG flag evaluation logic. The existing kfree() on hci_cmd_sync_queue +failure does not cover this path. + +Fixes: a7bcffc673de ("Bluetooth: Add PA_LINK to distinguish BIG sync and PA sync connections") +Cc: stable@vger.kernel.org +Signed-off-by: Pavitra Jha +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_conn.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -803,8 +803,10 @@ static int hci_le_big_terminate(struct h + d->big_sync_term = true; + } + +- if (!d->pa_sync_term && !d->big_sync_term) ++ if (!d->pa_sync_term && !d->big_sync_term) { ++ kfree(d); + return 0; ++ } + + ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d, + terminate_big_destroy); diff --git a/queue-7.0/bluetooth-hci_qca-use-100-ms-ssr-delay-for-rampatch-and-nvm-loading.patch b/queue-7.0/bluetooth-hci_qca-use-100-ms-ssr-delay-for-rampatch-and-nvm-loading.patch new file mode 100644 index 0000000000..178c83829c --- /dev/null +++ b/queue-7.0/bluetooth-hci_qca-use-100-ms-ssr-delay-for-rampatch-and-nvm-loading.patch @@ -0,0 +1,54 @@ +From fa21e86caba2347e89eb65af926205a36a097c53 Mon Sep 17 00:00:00 2001 +From: Shuai Zhang +Date: Mon, 25 May 2026 14:51:56 +0800 +Subject: Bluetooth: hci_qca: Use 100 ms SSR delay for rampatch and NVM loading + +From: Shuai Zhang + +commit fa21e86caba2347e89eb65af926205a36a097c53 upstream. + +When bt_en is pulled high by hardware, the host does not re-download +the firmware after SSR. The controller loads the rampatch and NVM +internally. + +On HMT chip, the rampatch is ~264 KB and the NVM is ~9.4 KB. The +loading process takes approximately 70 ms. The previous 50 ms delay is +too short, causing the controller to not respond to the reset command +sent by the host, which leads to BT initialization failure: + + Bluetooth: hci0: QCA memdump Done, received 458752, total 458752 + Bluetooth: hci0: mem_dump_status: 2 + Bluetooth: hci0: Opcode 0x0c03 failed: -110 + +Increase the delay to 100 ms, which was confirmed as a safe value by +the controller, to ensure the controller has finished loading the +firmware before the host sends commands. + +Steps to reproduce: +1. Trigger SSR and wait for SSR to complete: + hcitool cmd 0x3f 0c 26 +2. Run "bluetoothctl power on" and observe that BT fails to start. + +Fixes: fce1a9244a0f ("Bluetooth: hci_qca: Fix SSR (SubSystem Restart) fail when BT_EN is pulled up by hw") +Cc: stable@vger.kernel.org +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Shuai Zhang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/hci_qca.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -1677,8 +1677,8 @@ static void qca_hw_error(struct hci_dev + mod_timer(&qca->tx_idle_timer, jiffies + + msecs_to_jiffies(qca->tx_idle_delay)); + +- /* Controller reset completion time is 50ms */ +- msleep(50); ++ /* Wait for the controller to load the rampatch and NVM. */ ++ msleep(100); + + clear_bit(QCA_SSR_TRIGGERED, &qca->flags); + clear_bit(QCA_IBS_DISABLED, &qca->flags); diff --git a/queue-7.0/bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch b/queue-7.0/bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch new file mode 100644 index 0000000000..d35354b123 --- /dev/null +++ b/queue-7.0/bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch @@ -0,0 +1,76 @@ +From bfea6091e0fffb270c20e74384b660910277eb6c Mon Sep 17 00:00:00 2001 +From: Doruk Tan Ozturk +Date: Mon, 25 May 2026 18:24:38 +0200 +Subject: Bluetooth: hci_sync: fix UAF in hci_le_create_cis_sync + +From: Doruk Tan Ozturk + +commit bfea6091e0fffb270c20e74384b660910277eb6c upstream. + +hci_le_create_cis_sync() dereferences conn->conn_timeout after releasing +both rcu_read_lock() and hci_dev_lock(hdev). The conn pointer was +obtained from an RCU-protected iteration over hdev->conn_hash.list and +is not valid once these locks are dropped. A concurrent disconnect can +free the hci_conn between the unlock and the dereference, causing a +use-after-free read. + +The cancellation mechanism in hci_conn_del() cannot prevent this because +hci_le_create_cis_pending() queues hci_create_cis_sync with data=NULL: + + hci_cmd_sync_queue(hdev, hci_create_cis_sync, NULL, NULL); + +While hci_conn_del() dequeues with data=conn: + + hci_cmd_sync_dequeue(hdev, NULL, conn, NULL); + +Since NULL != conn, the lookup in _hci_cmd_sync_lookup_entry() never +matches, and the pending work item is not cancelled. + +Fix this by saving conn->conn_timeout into a local variable while the +locks are still held, so the stale conn pointer is never dereferenced +after unlock. + +This is the same class of bug as the one fixed by commit 035c25007c9e +("Bluetooth: hci_sync: Fix UAF on le_read_features_complete") which +addressed the identical pattern in a different function. + +This vulnerability was identified using 0sec.ai, an open-source +automated security auditing platform (https://github.com/0sec-labs). + +Fixes: c09b80be6ffc ("Bluetooth: hci_conn: Fix not waiting for HCI_EVT_LE_CIS_ESTABLISHED") +Cc: stable@vger.kernel.org +Reported-by: Doruk Tan Ozturk +Signed-off-by: Doruk Tan Ozturk +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_sync.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -6711,6 +6711,7 @@ int hci_le_create_cis_sync(struct hci_de + DEFINE_FLEX(struct hci_cp_le_create_cis, cmd, cis, num_cis, 0x1f); + size_t aux_num_cis = 0; + struct hci_conn *conn; ++ u16 timeout = 0; + u8 cig = BT_ISO_QOS_CIG_UNSET; + + /* The spec allows only one pending LE Create CIS command at a time. If +@@ -6781,6 +6782,7 @@ int hci_le_create_cis_sync(struct hci_de + set_bit(HCI_CONN_CREATE_CIS, &conn->flags); + cis->acl_handle = cpu_to_le16(conn->parent->handle); + cis->cis_handle = cpu_to_le16(conn->handle); ++ timeout = conn->conn_timeout; + aux_num_cis++; + + if (aux_num_cis >= cmd->num_cis) +@@ -6800,7 +6802,7 @@ done: + return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CIS, + struct_size(cmd, cis, cmd->num_cis), + cmd, HCI_EVT_LE_CIS_ESTABLISHED, +- conn->conn_timeout, NULL); ++ timeout, NULL); + } + + int hci_le_remove_cig_sync(struct hci_dev *hdev, u8 handle) diff --git a/queue-7.0/bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch b/queue-7.0/bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch new file mode 100644 index 0000000000..22b9ac5b9b --- /dev/null +++ b/queue-7.0/bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch @@ -0,0 +1,80 @@ +From 2a3ac9ee11dbb9845f3947cef4a79dba658cf6f6 Mon Sep 17 00:00:00 2001 +From: Muhammad Bilal +Date: Wed, 20 May 2026 18:56:43 -0400 +Subject: Bluetooth: HIDP: fix missing length checks in hidp_input_report() + +From: Muhammad Bilal + +commit 2a3ac9ee11dbb9845f3947cef4a79dba658cf6f6 upstream. + +hidp_input_report() reads keyboard and mouse payload data from an skb +without first verifying that skb->len contains enough data. + +hidp_recv_intr_frame() pulls the 1-byte HIDP header before dispatching +to hidp_input_report(). If a paired device sends a truncated packet, +the handler reads beyond the valid skb data, resulting in an +out-of-bounds read of skb data. The OOB bytes may be interpreted as +phantom key presses or spurious mouse movement. + +Replace the open-coded length tracking and pointer arithmetic with +skb_pull_data() calls. skb_pull_data() returns NULL if the requested +bytes are not present, eliminating the need for a manual size variable +and the separate skb->len guard. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Signed-off-by: Muhammad Bilal +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hidp/core.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +--- a/net/bluetooth/hidp/core.c ++++ b/net/bluetooth/hidp/core.c +@@ -179,12 +179,21 @@ static void hidp_input_report(struct hid + { + struct input_dev *dev = session->input; + unsigned char *keys = session->keys; +- unsigned char *udata = skb->data + 1; +- signed char *sdata = skb->data + 1; +- int i, size = skb->len - 1; ++ unsigned char *udata; ++ signed char *sdata; ++ u8 *hdr; ++ int i; ++ ++ hdr = skb_pull_data(skb, 1); ++ if (!hdr) ++ return; + +- switch (skb->data[0]) { ++ switch (*hdr) { + case 0x01: /* Keyboard report */ ++ udata = skb_pull_data(skb, 8); ++ if (!udata) ++ break; ++ + for (i = 0; i < 8; i++) + input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1); + +@@ -213,6 +222,10 @@ static void hidp_input_report(struct hid + break; + + case 0x02: /* Mouse report */ ++ sdata = skb_pull_data(skb, 3); ++ if (!sdata) ++ break; ++ + input_report_key(dev, BTN_LEFT, sdata[0] & 0x01); + input_report_key(dev, BTN_RIGHT, sdata[0] & 0x02); + input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04); +@@ -222,7 +235,7 @@ static void hidp_input_report(struct hid + input_report_rel(dev, REL_X, sdata[1]); + input_report_rel(dev, REL_Y, sdata[2]); + +- if (size > 3) ++ if (skb->len > 0) + input_report_rel(dev, REL_WHEEL, sdata[3]); + break; + } diff --git a/queue-7.0/bluetooth-iso-fix-uaf-in-iso_recv_frame.patch b/queue-7.0/bluetooth-iso-fix-uaf-in-iso_recv_frame.patch new file mode 100644 index 0000000000..46db4d5ac2 --- /dev/null +++ b/queue-7.0/bluetooth-iso-fix-uaf-in-iso_recv_frame.patch @@ -0,0 +1,57 @@ +From 47f23a259517abbdb8032c057a1e8a6bf3734878 Mon Sep 17 00:00:00 2001 +From: Muhammad Bilal +Date: Wed, 27 May 2026 04:59:17 +0000 +Subject: Bluetooth: ISO: fix UAF in iso_recv_frame + +From: Muhammad Bilal + +commit 47f23a259517abbdb8032c057a1e8a6bf3734878 upstream. + +iso_recv_frame reads conn->sk under iso_conn_lock but releases the lock +before using sk, with no reference held. A concurrent iso_sock_kill() +can free sk in that window, causing use-after-free on sk->sk_state and +sock_queue_rcv_skb(). + +Fix by replacing the bare pointer read with iso_sock_hold(conn), which +calls sock_hold() while the spinlock is held, atomically elevating the +refcount before the lock drops. Add a drop_put label so sock_put() is +called on all exit paths where the hold succeeded. + +Fixes: ccf74f2390d60a2f9a75ef496d2564abb478f46a ("Bluetooth: Add BTPROTO_ISO socket type") +Cc: stable@vger.kernel.org +Signed-off-by: Muhammad Bilal +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/iso.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -572,7 +572,7 @@ static void iso_recv_frame(struct iso_co + struct sock *sk; + + iso_conn_lock(conn); +- sk = conn->sk; ++ sk = iso_sock_hold(conn); + iso_conn_unlock(conn); + + if (!sk) +@@ -581,11 +581,15 @@ static void iso_recv_frame(struct iso_co + BT_DBG("sk %p len %d", sk, skb->len); + + if (sk->sk_state != BT_CONNECTED) +- goto drop; ++ goto drop_put; + +- if (!sock_queue_rcv_skb(sk, skb)) ++ if (!sock_queue_rcv_skb(sk, skb)) { ++ sock_put(sk); + return; ++ } + ++drop_put: ++ sock_put(sk); + drop: + kfree_skb(skb); + } diff --git a/queue-7.0/bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch b/queue-7.0/bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch new file mode 100644 index 0000000000..ae29eb7e4b --- /dev/null +++ b/queue-7.0/bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch @@ -0,0 +1,59 @@ +From 4b5f8e608749b7e8fa386c6e4301cf9272595859 Mon Sep 17 00:00:00 2001 +From: Muhammad Bilal +Date: Wed, 27 May 2026 04:59:18 +0000 +Subject: Bluetooth: ISO: serialize iso_sock_clear_timer with socket lock + +From: Muhammad Bilal + +commit 4b5f8e608749b7e8fa386c6e4301cf9272595859 upstream. + +iso_sock_close() calls iso_sock_clear_timer() before acquiring +lock_sock(sk). + +iso_sock_clear_timer() reads iso_pi(sk)->conn twice without the +socket lock held: + + if (!iso_pi(sk)->conn) + return; + cancel_delayed_work(&iso_pi(sk)->conn->timeout_work); + +Concurrently, iso_conn_del() executes under lock_sock(sk) and calls +iso_chan_del(), which sets iso_pi(sk)->conn to NULL and may result in +the final reference to the connection being dropped: + + CPU0 CPU1 + ---- ---- + iso_sock_clear_timer() + if (conn != NULL) ... lock_sock(sk) + iso_chan_del() + iso_pi(sk)->conn = NULL + cancel_delayed_work(conn) /* NULL deref or UAF */ + +iso_pi(sk)->conn is not stable across the unlock window, causing a +NULL pointer dereference or use-after-free. + +Serialize iso_sock_clear_timer() with the socket lock by moving it +inside lock_sock()/release_sock(), matching the pattern used in +iso_conn_del() and all other call sites. + +Fixes: ccf74f2390d60a2f9a75ef496d2564abb478f46a ("Bluetooth: Add BTPROTO_ISO socket type") +Cc: stable@vger.kernel.org +Signed-off-by: Muhammad Bilal +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/iso.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -872,8 +872,8 @@ static void __iso_sock_close(struct sock + /* Must be called on unlocked socket. */ + static void iso_sock_close(struct sock *sk) + { +- iso_sock_clear_timer(sk); + lock_sock(sk); ++ iso_sock_clear_timer(sk); + __iso_sock_close(sk); + release_sock(sk); + iso_sock_kill(sk); diff --git a/queue-7.0/bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch b/queue-7.0/bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch new file mode 100644 index 0000000000..a88d8a0e35 --- /dev/null +++ b/queue-7.0/bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch @@ -0,0 +1,40 @@ +From 9dbd84990394c51f5cee1e8871bb5ff8af5ed939 Mon Sep 17 00:00:00 2001 +From: Siwei Zhang +Date: Wed, 20 May 2026 22:30:36 -0400 +Subject: Bluetooth: L2CAP: fix chan ref leak in l2cap_chan_timeout() on !conn + +From: Siwei Zhang + +commit 9dbd84990394c51f5cee1e8871bb5ff8af5ed939 upstream. + +__set_chan_timer() takes a l2cap_chan reference via l2cap_chan_hold() +before scheduling the delayed work. The normal path in +l2cap_chan_timeout() drops this reference with l2cap_chan_put() at the +end, but the early return when chan->conn is NULL skips the put, +leaking the reference. + +Add the missing l2cap_chan_put() before the early return. + +Fixes: adf0398cee86 ("Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout") +Cc: stable@vger.kernel.org +Signed-off-by: Siwei Zhang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/l2cap_core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -411,8 +411,10 @@ static void l2cap_chan_timeout(struct wo + + BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); + +- if (!conn) ++ if (!conn) { ++ l2cap_chan_put(chan); + return; ++ } + + mutex_lock(&conn->lock); + /* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling diff --git a/queue-7.0/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch b/queue-7.0/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch new file mode 100644 index 0000000000..c6fdc3c17a --- /dev/null +++ b/queue-7.0/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch @@ -0,0 +1,69 @@ +From 8c8e620467a7b51562dbcefbd1f09f288d7d710d Mon Sep 17 00:00:00 2001 +From: Siwei Zhang +Date: Wed, 20 May 2026 22:12:20 -0400 +Subject: Bluetooth: L2CAP: use chan timer to close channels in cleanup_listen() + +From: Siwei Zhang + +commit 8c8e620467a7b51562dbcefbd1f09f288d7d710d upstream. + +l2cap_chan_close() removes the channel from conn->chan_l, which +must be done under conn->lock. cleanup_listen() runs under the +parent sk_lock, so acquiring conn->lock would invert the +established conn->lock -> chan->lock -> sk_lock order. + +Instead of calling l2cap_chan_close() directly, schedule +l2cap_chan_timeout with delay 0 to close the channel +asynchronously. The timeout handler already acquires conn->lock +and chan->lock in the correct order. + +The timer is only armed when chan->conn is still set: if it is +already NULL, l2cap_conn_del() has already processed this channel +(l2cap_chan_del + l2cap_sock_teardown_cb + l2cap_sock_close_cb), +so there is nothing left to do. If l2cap_conn_del() races in +after the timer is armed, __clear_chan_timer() inside +l2cap_chan_del() cancels it; if the timer has already fired, the +handler returns harmlessly because chan->conn was cleared. + +Fixes: 3df91ea20e74 ("Bluetooth: Revert to mutexes from RCU list") +Cc: # 0b58004: Bluetooth: fix UAF in l2cap_sock_cleanup_listen() vs l2cap_conn_del() +Signed-off-by: Siwei Zhang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/l2cap_sock.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/net/bluetooth/l2cap_sock.c ++++ b/net/bluetooth/l2cap_sock.c +@@ -1499,6 +1499,10 @@ static void l2cap_sock_cleanup_listen(st + * pin it (hold_unless_zero() additionally skips a chan already past + * its last reference). We then drop the sk lock before taking + * chan->lock, so sk and chan locks are never held together. ++ * ++ * Since we cannot call l2cap_chan_close() without conn->lock, ++ * schedule l2cap_chan_timeout to close the channel; it already ++ * acquires conn->lock -> chan->lock in the correct order. + */ + while ((sk = bt_accept_dequeue(parent, NULL))) { + struct l2cap_chan *chan; +@@ -1516,14 +1520,12 @@ static void l2cap_sock_cleanup_listen(st + state_to_string(chan->state)); + + l2cap_chan_lock(chan); +- __clear_chan_timer(chan); +- l2cap_chan_close(chan, ECONNRESET); +- /* l2cap_conn_del() may already have killed this socket +- * (it sets SOCK_DEAD); skip the duplicate to avoid a +- * double sock_put()/l2cap_chan_put(). ++ /* Since we cannot call l2cap_chan_close() without ++ * conn->lock, schedule its timer to trigger the close ++ * and cleanup of this channel. + */ +- if (!sock_flag(sk, SOCK_DEAD)) +- l2cap_sock_kill(sk); ++ if (chan->conn) ++ __set_chan_timer(chan, 0); + l2cap_chan_unlock(chan); + + l2cap_chan_put(chan); diff --git a/queue-7.0/disable-wattribute-alias-for-clang-23-and-newer.patch b/queue-7.0/disable-wattribute-alias-for-clang-23-and-newer.patch new file mode 100644 index 0000000000..b1176ca477 --- /dev/null +++ b/queue-7.0/disable-wattribute-alias-for-clang-23-and-newer.patch @@ -0,0 +1,126 @@ +From 175db11786bde9061db526bf1ac5107d915f5163 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Sat, 16 May 2026 04:34:14 +0900 +Subject: Disable -Wattribute-alias for clang-23 and newer + +From: Nathan Chancellor + +commit 175db11786bde9061db526bf1ac5107d915f5163 upstream. + +Clang recently added support for -Wattribute-alias [1], which results in +the same warnings that necessitated commit bee20031772a ("disable +-Wattribute-alias warning for SYSCALL_DEFINEx()") for GCC. + + kernel/time/itimer.c:325:1: error: alias and aliasee have different types 'long (unsigned int)' and 'long (typeof (__builtin_choose_expr((__builtin_types_compatible_p(typeof ((unsigned int)0), typeof (0LL)) || __builtin_types_compatible_p(typeof ((unsigned int)0), typeof (0ULL))), 0LL, 0L)))' (aka 'long (long)') [-Werror,-Wattribute-alias] + 325 | SYSCALL_DEFINE1(alarm, unsigned int, seconds) + | ^ + include/linux/syscalls.h:225:36: note: expanded from macro 'SYSCALL_DEFINE1' + 225 | #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) + | ^ + include/linux/syscalls.h:236:2: note: expanded from macro 'SYSCALL_DEFINEx' + 236 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) + | ^ + include/linux/syscalls.h:251:18: note: expanded from macro '__SYSCALL_DEFINEx' + 251 | __attribute__((alias(__stringify(__se_sys##name)))); \ + | ^ + kernel/time/itimer.c:325:1: note: aliasee is declared here + include/linux/syscalls.h:225:36: note: expanded from macro 'SYSCALL_DEFINE1' + 225 | #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) + | ^ + include/linux/syscalls.h:236:2: note: expanded from macro 'SYSCALL_DEFINEx' + 236 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) + | ^ + include/linux/syscalls.h:255:18: note: expanded from macro '__SYSCALL_DEFINEx' + 255 | asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + | ^ + :16:1: note: expanded from here + 16 | __se_sys_alarm + | ^ + +Disable the warnings in the same way for clang-23 and newer. Disable the +warning about unknown warning options to avoid breaking the build for +versions of clang-23 that do not have -Wattribute-alias, such as ones +deployed by vendors like Android or CI systems or when bisecting LLVM +between llvmorg-23-init and release/23.x. + +Cc: stable@vger.kernel.org +Closes: https://github.com/ClangBuiltLinux/linux/issues/2163 +Link: https://github.com/llvm/llvm-project/commit/40da6920a0d71d49dfa2392b09153600b0759f5e [1] +Link: https://patch.msgid.link/20260515-syscall-disable-attribute-alias-for-clang-v1-1-9a9d95d41df6@kernel.org +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/include/asm/syscall_wrapper.h | 4 ++++ + include/linux/compat.h | 4 ++++ + include/linux/compiler-clang.h | 6 ++++++ + include/linux/compiler_types.h | 4 ++++ + include/linux/syscalls.h | 4 ++++ + 5 files changed, 22 insertions(+) + +--- a/arch/riscv/include/asm/syscall_wrapper.h ++++ b/arch/riscv/include/asm/syscall_wrapper.h +@@ -32,6 +32,10 @@ asmlinkage long __riscv_sys_ni_syscall(c + __diag_push(); \ + __diag_ignore(GCC, 8, "-Wattribute-alias", \ + "Type aliasing is used to sanitize syscall arguments"); \ ++ __diag_ignore(clang, 23, "-Wunknown-warning-option", \ ++ "Avoid breaking versions without -Wattribute-alias"); \ ++ __diag_ignore(clang, 23, "-Wattribute-alias", \ ++ "Type aliasing is used to sanitize syscall arguments"); \ + static long __se_##prefix##name(ulong, ulong, ulong, ulong, ulong, ulong, \ + ulong) \ + __attribute__((alias(__stringify(___se_##prefix##name)))); \ +--- a/include/linux/compat.h ++++ b/include/linux/compat.h +@@ -72,6 +72,10 @@ + __diag_push(); \ + __diag_ignore(GCC, 8, "-Wattribute-alias", \ + "Type aliasing is used to sanitize syscall arguments");\ ++ __diag_ignore(clang, 23, "-Wunknown-warning-option", \ ++ "Avoid breaking versions without -Wattribute-alias"); \ ++ __diag_ignore(clang, 23, "-Wattribute-alias", \ ++ "Type aliasing is used to sanitize syscall arguments"); \ + asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(__se_compat_sys##name)))); \ + ALLOW_ERROR_INJECTION(compat_sys##name, ERRNO); \ +--- a/include/linux/compiler-clang.h ++++ b/include/linux/compiler-clang.h +@@ -131,6 +131,12 @@ + #define __diag_str(s) __diag_str1(s) + #define __diag(s) _Pragma(__diag_str(clang diagnostic s)) + ++#if CONFIG_CLANG_VERSION >= 230000 ++#define __diag_clang_23(s) __diag(s) ++#else ++#define __diag_clang_23(s) ++#endif ++ + #define __diag_clang_13(s) __diag(s) + + #define __diag_ignore_all(option, comment) \ +--- a/include/linux/compiler_types.h ++++ b/include/linux/compiler_types.h +@@ -718,6 +718,10 @@ struct ftrace_likely_data { + #define __diag_GCC(version, severity, string) + #endif + ++#ifndef __diag_clang ++#define __diag_clang(version, severity, string) ++#endif ++ + #define __diag_push() __diag(push) + #define __diag_pop() __diag(pop) + +--- a/include/linux/syscalls.h ++++ b/include/linux/syscalls.h +@@ -247,6 +247,10 @@ static inline int is_syscall_trace_event + __diag_push(); \ + __diag_ignore(GCC, 8, "-Wattribute-alias", \ + "Type aliasing is used to sanitize syscall arguments");\ ++ __diag_ignore(clang, 23, "-Wunknown-warning-option", \ ++ "Avoid breaking versions without -Wattribute-alias");\ ++ __diag_ignore(clang, 23, "-Wattribute-alias", \ ++ "Type aliasing is used to sanitize syscall arguments");\ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(__se_sys##name)))); \ + ALLOW_ERROR_INJECTION(sys##name, ERRNO); \ diff --git a/queue-7.0/gpio-shared-fix-deadlock-on-shared-proxy-s-parent-removal.patch b/queue-7.0/gpio-shared-fix-deadlock-on-shared-proxy-s-parent-removal.patch new file mode 100644 index 0000000000..05179b4e89 --- /dev/null +++ b/queue-7.0/gpio-shared-fix-deadlock-on-shared-proxy-s-parent-removal.patch @@ -0,0 +1,63 @@ +From a1b836607304f71051f9f9dcccf8b5097b86a1fb Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski +Date: Fri, 22 May 2026 11:12:36 +0200 +Subject: gpio: shared: fix deadlock on shared proxy's parent removal + +From: Bartosz Golaszewski + +commit a1b836607304f71051f9f9dcccf8b5097b86a1fb upstream. + +Commit 710abda58055 ("gpio: shared: call gpio_chip::of_xlate() if set") +used the mutex embedded in struct gpio_shared_entry to protect the +offset field which now can be modified after assignment. The critical +section however is too wide and introduced a potential deadlock on the +removal of the shared GPIO proxy's parent. + +Make the critical section shorter - only protect the offset when it's +being read. + +While at it: mention the fact that the entry lock is now also used to +protect against concurrent access to the offset field in the structure's +documentation. + +Cc: stable@vger.kernel.org +Fixes: 710abda58055 ("gpio: shared: call gpio_chip::of_xlate() if set") +Reviewed-by: Linus Walleij +Link: https://patch.msgid.link/20260522-gpio-shared-deadlock-v1-1-76bca088f8c0@oss.qualcomm.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpio/gpiolib-shared.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c +index e02d6b93a4ab..087b64c06c9f 100644 +--- a/drivers/gpio/gpiolib-shared.c ++++ b/drivers/gpio/gpiolib-shared.c +@@ -53,7 +53,7 @@ struct gpio_shared_entry { + unsigned int offset; + /* Index in the property value array. */ + size_t index; +- /* Synchronizes the modification of shared_desc. */ ++ /* Synchronizes the modification of shared_desc and offset. */ + struct mutex lock; + struct gpio_shared_desc *shared_desc; + struct kref ref; +@@ -598,12 +598,11 @@ void gpio_device_teardown_shared(struct gpio_device *gdev) + struct gpio_shared_ref *ref; + + list_for_each_entry(entry, &gpio_shared_list, list) { +- guard(mutex)(&entry->lock); +- + if (!device_match_fwnode(&gdev->dev, entry->fwnode)) + continue; + +- gpiod_free_commit(&gdev->descs[entry->offset]); ++ scoped_guard(mutex, &entry->lock) ++ gpiod_free_commit(&gdev->descs[entry->offset]); + + list_for_each_entry(ref, &entry->refs, list) { + guard(mutex)(&ref->lock); +-- +2.54.0 + diff --git a/queue-7.0/gpio-shared-fix-lockdep-false-positive-by-removing-unneeded-lock.patch b/queue-7.0/gpio-shared-fix-lockdep-false-positive-by-removing-unneeded-lock.patch new file mode 100644 index 0000000000..4e76ccb766 --- /dev/null +++ b/queue-7.0/gpio-shared-fix-lockdep-false-positive-by-removing-unneeded-lock.patch @@ -0,0 +1,42 @@ +From 9d7697fabbc72428f981c01ddbe0a6be0ce8b6fa Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski +Date: Fri, 22 May 2026 11:12:37 +0200 +Subject: gpio: shared: fix lockdep false positive by removing unneeded lock + +From: Bartosz Golaszewski + +commit 9d7697fabbc72428f981c01ddbe0a6be0ce8b6fa upstream. + +By the time gpio_device_teardown_shared() is called, the parent device +is gone from the global list of GPIO devices and all outstanding SRCU +read-side critical sections have completed. That means that no +concurrent gpio_find_and_request() can call +gpio_shared_add_proxy_lookup() for this device at this time. There's +also no risk of the parent device being re-bound to the driver before +the unbinding completes (including the child devices). + +Lockdep produces a false-positive report about a possible circular +dependency as it doesn't know the ordering guarantee. Not taking the +ref->lock in gpio_device_teardown_shared() silences it and is safe to do. + +Cc: stable@vger.kernel.org +Fixes: ea513dd3c066 ("gpio: shared: make locking more fine-grained") +Reviewed-by: Linus Walleij +Link: https://patch.msgid.link/20260522-gpio-shared-deadlock-v1-2-76bca088f8c0@oss.qualcomm.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpio/gpiolib-shared.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/gpio/gpiolib-shared.c ++++ b/drivers/gpio/gpiolib-shared.c +@@ -605,8 +605,6 @@ void gpio_device_teardown_shared(struct + gpiod_free_commit(&gdev->descs[entry->offset]); + + list_for_each_entry(ref, &entry->refs, list) { +- guard(mutex)(&ref->lock); +- + if (ref->lookup) { + gpiod_remove_lookup_table(ref->lookup); + kfree(ref->lookup->table[0].key); diff --git a/queue-7.0/gpio-shared-undo-the-vote-of-the-proxy-on-gpio-free.patch b/queue-7.0/gpio-shared-undo-the-vote-of-the-proxy-on-gpio-free.patch new file mode 100644 index 0000000000..cef9e49576 --- /dev/null +++ b/queue-7.0/gpio-shared-undo-the-vote-of-the-proxy-on-gpio-free.patch @@ -0,0 +1,47 @@ +From bbec30f7e19d9a1c604da7164b8057ccee590e72 Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski +Date: Fri, 22 May 2026 09:49:35 +0200 +Subject: gpio: shared: undo the vote of the proxy on GPIO free + +From: Bartosz Golaszewski + +commit bbec30f7e19d9a1c604da7164b8057ccee590e72 upstream. + +When the user of a shared GPIO managed by gpio-shared-proxy calls +gpiod_put() to release it, we never undo the potential "vote" for +driving the shared line "high". In the free() callback, check if this +proxy voted for "high" and - if so - decrease the number of votes and +potentially revert the value to low if this is the last user. + +Cc: stable@vger.kernel.org +Fixes: e992d54c6f97 ("gpio: shared-proxy: implement the shared GPIO proxy driver") +Closes: https://sashiko.dev/#/patchset/20260513-gpio-shared-dynamic-voting-v1-1-8e1c49961b7d%40oss.qualcomm.com +Reviewed-by: Linus Walleij +Link: https://patch.msgid.link/20260522-gpio-shared-free-vote-v3-1-8a4fddc6bedb@oss.qualcomm.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpio/gpio-shared-proxy.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/gpio/gpio-shared-proxy.c ++++ b/drivers/gpio/gpio-shared-proxy.c +@@ -103,9 +103,18 @@ static void gpio_shared_proxy_free(struc + { + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + struct gpio_shared_desc *shared_desc = proxy->shared_desc; ++ int ret; + + guard(gpio_shared_desc_lock)(shared_desc); + ++ if (proxy->voted_high) { ++ ret = gpio_shared_proxy_set_unlocked(proxy, ++ shared_desc->can_sleep ? gpiod_set_value_cansleep : gpiod_set_value, 0); ++ if (ret) ++ dev_err(proxy->dev, ++ "Failed to unset the shared GPIO value on release: %d\n", ret); ++ } ++ + proxy->shared_desc->usecnt--; + + dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n", diff --git a/queue-7.0/hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch b/queue-7.0/hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch new file mode 100644 index 0000000000..772c2de40a --- /dev/null +++ b/queue-7.0/hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch @@ -0,0 +1,32 @@ +From 974820a59efde7c1a7e1260bcfe9bb81f833cc9f Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 25 May 2026 14:48:58 +0200 +Subject: hpfs: fix a crash if hpfs_map_dnode_bitmap fails + +From: Mikulas Patocka + +commit 974820a59efde7c1a7e1260bcfe9bb81f833cc9f upstream. + +If hpfs_map_dnode_bitmap fails, the code would call hpfs_brelse4 on +uninitialized quad buffer head, causing a crash. + +Signed-off-by: Mikulas Patocka +Reported-by: Farhad Alemi +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + fs/hpfs/alloc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/hpfs/alloc.c ++++ b/fs/hpfs/alloc.c +@@ -372,8 +372,8 @@ int hpfs_check_free_dnodes(struct super_ + return 0; + } + } ++ hpfs_brelse4(&qbh); + } +- hpfs_brelse4(&qbh); + i = 0; + if (hpfs_sb(s)->sb_c_bitmap != -1) { + bmp = hpfs_map_bitmap(s, b, &qbh, "chkdn1"); diff --git a/queue-7.0/i2c-davinci-fix-division-by-zero-on-missing-clock-frequency.patch b/queue-7.0/i2c-davinci-fix-division-by-zero-on-missing-clock-frequency.patch new file mode 100644 index 0000000000..d60e005379 --- /dev/null +++ b/queue-7.0/i2c-davinci-fix-division-by-zero-on-missing-clock-frequency.patch @@ -0,0 +1,47 @@ +From 030675aa54cf757769b3db65642433d626b3ed7c Mon Sep 17 00:00:00 2001 +From: Chaitanya Sabnis +Date: Tue, 26 May 2026 15:52:40 +0530 +Subject: i2c: davinci: fix division by zero on missing clock-frequency + +From: Chaitanya Sabnis + +commit 030675aa54cf757769b3db65642433d626b3ed7c upstream. + +When the 'clock-frequency' property is missing from the device tree, +the driver falls back to DAVINCI_I2C_DEFAULT_BUS_FREQ. However, this +macro was defined in kHz (100), whereas the device tree property is +expected in Hz. + +The probe function divided the fallback value by 1000, causing +integer truncation that resulted in dev->bus_freq = 0. This triggered +a deterministic division-by-zero kernel panic when calculating clock +dividers later in the probe sequence. + +Fix this by redefining DAVINCI_I2C_DEFAULT_BUS_FREQ in Hz (100000) +to match the expected device tree property unit, allowing the existing +division logic to work correctly for both cases. + +Fixes: b04ce6385979 ("i2c: davinci: kill platform data") +Reported-by: Sashiko +Closes: https://lore.kernel.org/all/20260514044726.57297C2BCB7@smtp.kernel.org/ +Signed-off-by: Chaitanya Sabnis +Cc: # v6.14+ +Reviewed-by: Bartosz Golaszewski +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20260526102240.4949-1-chaitanya.msabnis@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-davinci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/i2c/busses/i2c-davinci.c ++++ b/drivers/i2c/busses/i2c-davinci.c +@@ -117,7 +117,7 @@ + /* timeout for pm runtime autosuspend */ + #define DAVINCI_I2C_PM_TIMEOUT 1000 /* ms */ + +-#define DAVINCI_I2C_DEFAULT_BUS_FREQ 100 ++#define DAVINCI_I2C_DEFAULT_BUS_FREQ 100000 + + struct davinci_i2c_dev { + struct device *dev; diff --git a/queue-7.0/iio-adc-ad4695-fix-call-ordering-in-offload-buffer-postenable.patch b/queue-7.0/iio-adc-ad4695-fix-call-ordering-in-offload-buffer-postenable.patch new file mode 100644 index 0000000000..def7ea6b64 --- /dev/null +++ b/queue-7.0/iio-adc-ad4695-fix-call-ordering-in-offload-buffer-postenable.patch @@ -0,0 +1,87 @@ +From 1a772719318c11e146f6fbe621fffd230a6f456a Mon Sep 17 00:00:00 2001 +From: Radu Sabau +Date: Wed, 8 Apr 2026 13:32:13 +0300 +Subject: iio: adc: ad4695: Fix call ordering in offload buffer postenable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Radu Sabau + +commit 1a772719318c11e146f6fbe621fffd230a6f456a upstream. + +ad4695_enter_advanced_sequencer_mode() was called after +spi_offload_trigger_enable(). That is wrong because +ad4695_enter_advanced_sequencer_mode() issues regular SPI transfers to +put the ADC into advanced sequencer mode, and not all SPI offload capable +controllers support regular SPI transfers while offloading is enabled. + +Fix this by calling ad4695_enter_advanced_sequencer_mode() before +spi_offload_trigger_enable(), so the ADC is fully configured before the +first CNV pulse can occur. This is consistent with the same constraint +that already applies to the BUSY_GP_EN write above it. + +Update the error unwind labels accordingly: add err_exit_conversion_mode +so that a failure of spi_offload_trigger_enable() correctly exits +conversion mode before clearing BUSY_GP_EN. + +Fixes: f09f140e3ea8 ("iio: adc: ad4695: Add support for SPI offload") +Reviewed-by: Nuno Sá +Reviewed-by: David Lechner +Signed-off-by: Radu Sabau +Cc: Stable@vger.kernel.org +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ad4695.c | 23 ++++++++--------------- + 1 file changed, 8 insertions(+), 15 deletions(-) + +--- a/drivers/iio/adc/ad4695.c ++++ b/drivers/iio/adc/ad4695.c +@@ -876,14 +876,14 @@ static int ad4695_offload_buffer_postena + if (ret) + goto err_unoptimize_message; + +- ret = spi_offload_trigger_enable(st->offload, st->offload_trigger, +- &config); ++ ret = ad4695_enter_advanced_sequencer_mode(st, num_slots); + if (ret) + goto err_disable_busy_output; + +- ret = ad4695_enter_advanced_sequencer_mode(st, num_slots); ++ ret = spi_offload_trigger_enable(st->offload, st->offload_trigger, ++ &config); + if (ret) +- goto err_offload_trigger_disable; ++ goto err_exit_conversion_mode; + + mutex_lock(&st->cnv_pwm_lock); + pwm_get_state(st->cnv_pwm, &state); +@@ -895,23 +895,16 @@ static int ad4695_offload_buffer_postena + ret = pwm_apply_might_sleep(st->cnv_pwm, &state); + mutex_unlock(&st->cnv_pwm_lock); + if (ret) +- goto err_offload_exit_conversion_mode; ++ goto err_offload_trigger_disable; + + return 0; + +-err_offload_exit_conversion_mode: +- /* +- * We have to unwind in a different order to avoid triggering offload. +- * ad4695_exit_conversion_mode() triggers a conversion, so it has to be +- * done after spi_offload_trigger_disable(). +- */ +- spi_offload_trigger_disable(st->offload, st->offload_trigger); +- ad4695_exit_conversion_mode(st); +- goto err_disable_busy_output; +- + err_offload_trigger_disable: + spi_offload_trigger_disable(st->offload, st->offload_trigger); + ++err_exit_conversion_mode: ++ ad4695_exit_conversion_mode(st); ++ + err_disable_busy_output: + regmap_clear_bits(st->regmap, AD4695_REG_GP_MODE, + AD4695_REG_GP_MODE_BUSY_GP_EN); diff --git a/queue-7.0/iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch b/queue-7.0/iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch new file mode 100644 index 0000000000..ded96a24ec --- /dev/null +++ b/queue-7.0/iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch @@ -0,0 +1,38 @@ +From f9bbd943c34a9ad60e593a4b99ce2394e4e2381b Mon Sep 17 00:00:00 2001 +From: Salah Triki +Date: Mon, 27 Apr 2026 21:12:38 +0100 +Subject: iio: adc: mt6359: fix unchecked return value in mt6358_read_imp + +From: Salah Triki + +commit f9bbd943c34a9ad60e593a4b99ce2394e4e2381b upstream. + +In mt6358_read_imp(), the variable val_v is passed to regmap_read() +but the return value is not checked. If the read fails, val_v remains +uninitialized and its random stack content is subsequently reported +as a measurement result. + +Initialize val_v to zero to ensure a predictable value is reported +in case of bus failure and to prevent potential stack data leakage. +This also satisfies static analyzers that might otherwise flag the +variable as used uninitialized. + +Fixes: 3587914bf61d ("iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC") +Signed-off-by: Salah Triki +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/mt6359-auxadc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/iio/adc/mt6359-auxadc.c ++++ b/drivers/iio/adc/mt6359-auxadc.c +@@ -497,6 +497,7 @@ static int mt6358_read_imp(struct mt6359 + return ret; + + /* Read the params before stopping */ ++ val_v = 0; + regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v); + + mt6358_stop_imp_conv(adc_dev); diff --git a/queue-7.0/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch b/queue-7.0/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch new file mode 100644 index 0000000000..2c7eed6fd3 --- /dev/null +++ b/queue-7.0/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch @@ -0,0 +1,108 @@ +From 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c Mon Sep 17 00:00:00 2001 +From: David Carlier +Date: Tue, 14 Apr 2026 13:30:06 +0100 +Subject: iio: adc: npcm: fix unbalanced clk_disable_unprepare() + +From: David Carlier + +commit 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c upstream. + +The driver acquired the ADC clock with devm_clk_get() and read its +rate, but never called clk_prepare_enable(). The probe error path and +npcm_adc_remove() both called clk_disable_unprepare() unconditionally, +causing the clk framework's enable/prepare counts to underflow on +probe failure or module unbind. + +The issue went unnoticed because NPCM BMC firmware leaves the ADC +clock enabled at boot, so the driver happened to work in practice. + +Switch to devm_clk_get_enabled() so the clock is properly enabled +during probe and automatically released by the device-managed +cleanup, and drop the now-redundant clk_disable_unprepare() from +both the probe error path and remove(). + +While at it, drop the duplicate error message on devm_request_irq() +failure since the IRQ core already logs it. + +Fixes: 9bf85fbc9d8f ("iio: adc: add NPCM ADC driver") +Signed-off-by: David Carlier +Reviewed-by: Andy Shevchenko +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/npcm_adc.c | 25 ++++++++----------------- + 1 file changed, 8 insertions(+), 17 deletions(-) + +--- a/drivers/iio/adc/npcm_adc.c ++++ b/drivers/iio/adc/npcm_adc.c +@@ -231,7 +231,7 @@ static int npcm_adc_probe(struct platfor + if (IS_ERR(info->reset)) + return PTR_ERR(info->reset); + +- info->adc_clk = devm_clk_get(&pdev->dev, NULL); ++ info->adc_clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(info->adc_clk)) { + dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n"); + return PTR_ERR(info->adc_clk); +@@ -244,17 +244,13 @@ static int npcm_adc_probe(struct platfor + info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2); + + irq = platform_get_irq(pdev, 0); +- if (irq < 0) { +- ret = irq; +- goto err_disable_clk; +- } ++ if (irq < 0) ++ return irq; + + ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0, + "NPCM_ADC", indio_dev); +- if (ret < 0) { +- dev_err(dev, "failed requesting interrupt\n"); +- goto err_disable_clk; +- } ++ if (ret < 0) ++ return ret; + + reg_con = ioread32(info->regs + NPCM_ADCCON); + info->vref = devm_regulator_get_optional(&pdev->dev, "vref"); +@@ -262,7 +258,7 @@ static int npcm_adc_probe(struct platfor + ret = regulator_enable(info->vref); + if (ret) { + dev_err(&pdev->dev, "Can't enable ADC reference voltage\n"); +- goto err_disable_clk; ++ return ret; + } + + iowrite32(reg_con & ~NPCM_ADCCON_REFSEL, +@@ -272,10 +268,8 @@ static int npcm_adc_probe(struct platfor + * Any error which is not ENODEV indicates the regulator + * has been specified and so is a failure case. + */ +- if (PTR_ERR(info->vref) != -ENODEV) { +- ret = PTR_ERR(info->vref); +- goto err_disable_clk; +- } ++ if (PTR_ERR(info->vref) != -ENODEV) ++ return PTR_ERR(info->vref); + + /* Use internal reference */ + iowrite32(reg_con | NPCM_ADCCON_REFSEL, +@@ -314,8 +308,6 @@ err_iio_register: + iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON); + if (!IS_ERR(info->vref)) + regulator_disable(info->vref); +-err_disable_clk: +- clk_disable_unprepare(info->adc_clk); + + return ret; + } +@@ -332,7 +324,6 @@ static void npcm_adc_remove(struct platf + iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON); + if (!IS_ERR(info->vref)) + regulator_disable(info->vref); +- clk_disable_unprepare(info->adc_clk); + } + + static struct platform_driver npcm_adc_driver = { diff --git a/queue-7.0/iio-adc-nxp-sar-adc-avoid-division-by-zero.patch b/queue-7.0/iio-adc-nxp-sar-adc-avoid-division-by-zero.patch new file mode 100644 index 0000000000..27ccc2bc56 --- /dev/null +++ b/queue-7.0/iio-adc-nxp-sar-adc-avoid-division-by-zero.patch @@ -0,0 +1,69 @@ +From 7e5c0f97c66ad538b87c04a640573371fb434b4f Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Thu, 16 Apr 2026 11:01:22 +0200 +Subject: iio: adc: nxp-sar-adc: Avoid division by zero + +From: Andy Shevchenko + +commit 7e5c0f97c66ad538b87c04a640573371fb434b4f upstream. + +When Common Clock Framework is disabled, clk_get_rate() returns 0. +This is used as part of the divisor to perform nanosecond delays +with help of ndelay(). When the above condition occurs the compiler, +due to unspecified behaviour, is free to do what it wants to. Here +it saturates the value, which is logical from mathematics point of +view. However, the ndelay() implementation has set a reasonable +upper threshold and refuses to provide anything for such a long +delay. That's why code may not be linked under these circumstances. + +To solve the issue, provide a wrapper that calls ndelay() when +the value is known not to be zero. + +Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202603311958.ly6uROit-lkp@intel.com/ +Signed-off-by: Andy Shevchenko +Acked-by: Daniel Lezcano +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/nxp-sar-adc.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/iio/adc/nxp-sar-adc.c ++++ b/drivers/iio/adc/nxp-sar-adc.c +@@ -198,6 +198,15 @@ static void nxp_sar_adc_irq_cfg(struct n + writel(0, NXP_SAR_ADC_IMR(info->regs)); + } + ++static void nxp_sar_adc_wait_for(struct nxp_sar_adc *info, unsigned int cycles) ++{ ++ u64 rate; ++ ++ rate = clk_get_rate(info->clk); ++ if (rate) ++ ndelay(div64_u64(NSEC_PER_SEC, rate * cycles)); ++} ++ + static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable) + { + u32 mcr; +@@ -221,7 +230,7 @@ static bool nxp_sar_adc_set_enabled(stru + * configuration of NCMR and the setting of NSTART. + */ + if (enable) +- ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk) * 3)); ++ nxp_sar_adc_wait_for(info, 3); + + return pwdn; + } +@@ -468,7 +477,7 @@ static void nxp_sar_adc_stop_conversion( + * only when the capture finishes. The delay will be very + * short, usec-ish, which is acceptable in the atomic context. + */ +- ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk)) * 80); ++ nxp_sar_adc_wait_for(info, 80); + } + + static int nxp_sar_adc_start_conversion(struct nxp_sar_adc *info, bool raw) diff --git a/queue-7.0/iio-adc-nxp-sar-adc-fix-division-by-zero-in-write_raw.patch b/queue-7.0/iio-adc-nxp-sar-adc-fix-division-by-zero-in-write_raw.patch new file mode 100644 index 0000000000..f204ab52ce --- /dev/null +++ b/queue-7.0/iio-adc-nxp-sar-adc-fix-division-by-zero-in-write_raw.patch @@ -0,0 +1,52 @@ +From a9aba21a539c668a66b58eeb08ad3909e5a54c2a Mon Sep 17 00:00:00 2001 +From: Antoniu Miclaus +Date: Wed, 1 Apr 2026 18:29:24 +0300 +Subject: iio: adc: nxp-sar-adc: fix division by zero in write_raw + +From: Antoniu Miclaus + +commit a9aba21a539c668a66b58eeb08ad3909e5a54c2a upstream. + +Add a validation check for the sampling frequency value before using it +as a divisor. A user writing zero or a negative value to the +sampling_frequency sysfs attribute triggers a division by zero in the +kernel. + +Also prevent unsigned integer underflow when the computed cycle count is +smaller than NXP_SAR_ADC_CONV_TIME, which would wrap the u32 inpsamp to +a huge value. + +Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms") +Signed-off-by: Antoniu Miclaus +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/nxp-sar-adc.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/iio/adc/nxp-sar-adc.c ++++ b/drivers/iio/adc/nxp-sar-adc.c +@@ -559,6 +559,9 @@ static int nxp_sar_adc_write_raw(struct + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: ++ if (val <= 0) ++ return -EINVAL; ++ + /* + * Configures the sample period duration in terms of the SAR + * controller clock. The minimum acceptable value is 8. +@@ -567,7 +570,11 @@ static int nxp_sar_adc_write_raw(struct + * sampling timing which gives us the number of cycles expected. + * The value is 8-bit wide, consequently the max value is 0xFF. + */ +- inpsamp = clk_get_rate(info->clk) / val - NXP_SAR_ADC_CONV_TIME; ++ inpsamp = clk_get_rate(info->clk) / val; ++ if (inpsamp < NXP_SAR_ADC_CONV_TIME) ++ return -EINVAL; ++ ++ inpsamp -= NXP_SAR_ADC_CONV_TIME; + nxp_sar_adc_conversion_timing_set(info, inpsamp); + return 0; + diff --git a/queue-7.0/iio-adc-nxp-sar-adc-zero-initialize-dma_slave_config.patch b/queue-7.0/iio-adc-nxp-sar-adc-zero-initialize-dma_slave_config.patch new file mode 100644 index 0000000000..6b5aeb7623 --- /dev/null +++ b/queue-7.0/iio-adc-nxp-sar-adc-zero-initialize-dma_slave_config.patch @@ -0,0 +1,37 @@ +From 8ce176501f836634f9c0419c0820140f968e9dc5 Mon Sep 17 00:00:00 2001 +From: Shuvam Pandey +Date: Mon, 6 Apr 2026 15:38:24 +0545 +Subject: iio: adc: nxp-sar-adc: zero-initialize dma_slave_config + +From: Shuvam Pandey + +commit 8ce176501f836634f9c0419c0820140f968e9dc5 upstream. + +nxp_sar_adc_start_cyclic_dma() only fills the RX-side members of +dma_slave_config before passing it to dmaengine_slave_config(). + +Zero-initialize the structure so unused members do not contain stack +garbage. Some DMA engines consult optional dma_slave_config fields, so +leaving them uninitialized can cause DMA setup failures. + +Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms") +Signed-off-by: Shuvam Pandey +Reviewed-by: David Lechner +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/nxp-sar-adc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/adc/nxp-sar-adc.c ++++ b/drivers/iio/adc/nxp-sar-adc.c +@@ -675,7 +675,7 @@ static void nxp_sar_adc_dma_cb(void *dat + static int nxp_sar_adc_start_cyclic_dma(struct iio_dev *indio_dev) + { + struct nxp_sar_adc *info = iio_priv(indio_dev); +- struct dma_slave_config config; ++ struct dma_slave_config config = { }; + struct dma_async_tx_descriptor *desc; + int ret; + diff --git a/queue-7.0/iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch b/queue-7.0/iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch new file mode 100644 index 0000000000..4621c0024b --- /dev/null +++ b/queue-7.0/iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch @@ -0,0 +1,44 @@ +From 422b5bbf333f75fb486855ad0eedc23cf21f3277 Mon Sep 17 00:00:00 2001 +From: Salah Triki +Date: Thu, 7 May 2026 20:07:51 +0100 +Subject: iio: adc: viperboard: Fix error handling in vprbrd_iio_read_raw +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Salah Triki + +commit 422b5bbf333f75fb486855ad0eedc23cf21f3277 upstream. + +The driver proceeds to the reception phase even if the preceding +transmission fails. + +This uses a goto error label for an early bail out and ensures the mutex is +properly unlocked in case of failure. + +Fixes: ffd8a6e7a778 ("iio: adc: Add viperboard adc driver") +Signed-off-by: Salah Triki +Reviewed-by: Joshua Crofts +Reviewed-by: Maxwell Doose +Reviewed-by: Nuno Sá +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/viperboard_adc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/iio/adc/viperboard_adc.c ++++ b/drivers/iio/adc/viperboard_adc.c +@@ -70,8 +70,10 @@ static int vprbrd_iio_read_raw(struct ii + VPRBRD_USB_TYPE_OUT, 0x0000, 0x0000, admsg, + sizeof(struct vprbrd_adc_msg), VPRBRD_USB_TIMEOUT_MS); + if (ret != sizeof(struct vprbrd_adc_msg)) { +- dev_err(&iio_dev->dev, "usb send error on adc read\n"); ++ mutex_unlock(&vb->lock); + error = -EREMOTEIO; ++ dev_err(&iio_dev->dev, "usb send error on adc read\n"); ++ goto error; + } + + ret = usb_control_msg(vb->usb_dev, diff --git a/queue-7.0/iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch b/queue-7.0/iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch new file mode 100644 index 0000000000..1994512c99 --- /dev/null +++ b/queue-7.0/iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch @@ -0,0 +1,75 @@ +From 852534744c2d35626a604f128ff0b8ec12805591 Mon Sep 17 00:00:00 2001 +From: Christofer Jonason +Date: Wed, 4 Mar 2026 10:07:27 +0100 +Subject: iio: adc: xilinx-xadc: Fix sequencer mode in postdisable for dual mux +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christofer Jonason + +commit 852534744c2d35626a604f128ff0b8ec12805591 upstream. + +xadc_postdisable() unconditionally sets the sequencer to continuous +mode. For dual external multiplexer configurations this is incorrect: +simultaneous sampling mode is required so that ADC-A samples through +the mux on VAUX[0-7] while ADC-B simultaneously samples through the +mux on VAUX[8-15]. In continuous mode only ADC-A is active, so +VAUX[8-15] channels return incorrect data. + +Since postdisable is also called from xadc_probe() to set the initial +idle state, the wrong sequencer mode is active from the moment the +driver loads. + +The preenable path already uses xadc_get_seq_mode() which returns +SIMULTANEOUS for dual mux. Fix postdisable to do the same. + +Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver") +Cc: stable@vger.kernel.org +Signed-off-by: Christofer Jonason +Reviewed-by: Andy Shevchenko +Reviewed-by: Nuno Sá +Reviewed-by: Salih Erim +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/xilinx-xadc-core.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -817,6 +817,7 @@ static int xadc_postdisable(struct iio_d + { + struct xadc *xadc = iio_priv(indio_dev); + unsigned long scan_mask; ++ int seq_mode; + int ret; + int i; + +@@ -824,6 +825,12 @@ static int xadc_postdisable(struct iio_d + for (i = 0; i < indio_dev->num_channels; i++) + scan_mask |= BIT(indio_dev->channels[i].scan_index); + ++ /* ++ * Use the correct sequencer mode for the idle state: simultaneous ++ * mode for dual external mux configurations, continuous otherwise. ++ */ ++ seq_mode = xadc_get_seq_mode(xadc, scan_mask); ++ + /* Enable all channels and calibration */ + ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(0), scan_mask & 0xffff); + if (ret) +@@ -834,11 +841,11 @@ static int xadc_postdisable(struct iio_d + return ret; + + ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_SEQ_MASK, +- XADC_CONF1_SEQ_CONTINUOUS); ++ seq_mode); + if (ret) + return ret; + +- return xadc_power_adc_b(xadc, XADC_CONF1_SEQ_CONTINUOUS); ++ return xadc_power_adc_b(xadc, seq_mode); + } + + static int xadc_preenable(struct iio_dev *indio_dev) diff --git a/queue-7.0/iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch b/queue-7.0/iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch new file mode 100644 index 0000000000..752e389b61 --- /dev/null +++ b/queue-7.0/iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch @@ -0,0 +1,55 @@ +From a093999355084bdbfe6e97f1dd232e58a1525f0b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Beno=C3=AEt=20Monin?= +Date: Wed, 1 Apr 2026 17:24:58 +0200 +Subject: iio: buffer: Fix DMA fence leak in iio_buffer_enqueue_dmabuf() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benoît Monin + +commit a093999355084bdbfe6e97f1dd232e58a1525f0b upstream. + +iio_buffer_enqueue_dmabuf() allocates a struct iio_dma_fence (104 bytes, +kmalloc-128) via kmalloc_obj()+dma_fence_init(), which sets the initial +kref to 1. It then calls dma_resv_add_fence() which takes a second +reference (kref=2), and stores a raw pointer in block->fence. + +On the success path the function returns without calling dma_fence_put() +to release the initial reference, so every buffer enqueue permanently +leaks one kmalloc-128 allocation. + +The iio_buffer_cleanup() work item only releases the temporary reference +taken during completion signalling by iio_buffer_signal_dmabuf_done(); +the initial reference from dma_fence_init() is never released. + +With four iio_rwdev instances at 240kHz and 512 samples per buffer, +this produces ~1875 kmalloc-128 allocations per second matching the +observed slab growth exactly. A test with ftrace confirmed that the +dma_fence_destroy event was never triggered. + +Fix by calling dma_fence_put() after dma_resv_add_fence(), transferring +ownership of the fence to the DMA reservation object. The DMA fence then +gets properly discarded after being signalled. + +Fixes: 3e26d9f08fbe0 ("iio: core: Add new DMABUF interface infrastructure") +Originally-by: James Nuss +Signed-off-by: Benoît Monin +Reviewed-by: Paul Cercueil +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/industrialio-buffer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/iio/industrialio-buffer.c ++++ b/drivers/iio/industrialio-buffer.c +@@ -1909,6 +1909,7 @@ static int iio_buffer_enqueue_dmabuf(str + + dma_resv_add_fence(dmabuf->resv, &fence->base, + dma_to_ram ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ); ++ dma_fence_put(&fence->base); + dma_resv_unlock(dmabuf->resv); + + cookie = dma_fence_begin_signalling(); diff --git a/queue-7.0/iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch b/queue-7.0/iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch new file mode 100644 index 0000000000..5f811ee3d1 --- /dev/null +++ b/queue-7.0/iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch @@ -0,0 +1,54 @@ +From 6f5ed4f2c7c83f33344e0ba179f72a12e5dad4a4 Mon Sep 17 00:00:00 2001 +From: Felix Gu +Date: Thu, 30 Apr 2026 21:29:06 +0800 +Subject: iio: buffer: hw-consumer: fix use-after-free in error path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felix Gu + +commit 6f5ed4f2c7c83f33344e0ba179f72a12e5dad4a4 upstream. + +In the err_put_buffers cleanup path of iio_hw_consumer_alloc(), the code +was using list_for_each_entry() to iterate through buffers while calling +iio_buffer_put() which can free the current buffer if refcount drops to 0. +The list_for_each_entry() loop macro then evaluates buf->head.next to +continue iteration, accessing the freed buffer. + +Fix this by using list_for_each_entry_safe(). + +Fixes: 48b66f8f936f ("iio: Add hardware consumer buffer support") +Reported-by: sashiko +Closes: https://sashiko.dev/#/patchset/20260427-iio_buf-v1-1-2bbdac844647%40gmail.com +Signed-off-by: Felix Gu +Reviewed-by: Andy Shevchenko +Reviewed-by: Nuno Sá +Reviewed-by: Maxwell Doose +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/buffer/industrialio-hw-consumer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/iio/buffer/industrialio-hw-consumer.c ++++ b/drivers/iio/buffer/industrialio-hw-consumer.c +@@ -82,7 +82,7 @@ static struct hw_consumer_buffer *iio_hw + */ + struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev) + { +- struct hw_consumer_buffer *buf; ++ struct hw_consumer_buffer *buf, *tmp; + struct iio_hw_consumer *hwc; + struct iio_channel *chan; + int ret; +@@ -113,7 +113,7 @@ struct iio_hw_consumer *iio_hw_consumer_ + return hwc; + + err_put_buffers: +- list_for_each_entry(buf, &hwc->buffers, head) ++ list_for_each_entry_safe(buf, tmp, &hwc->buffers, head) + iio_buffer_put(&buf->buffer); + iio_channel_release_all(hwc->channels); + err_free_hwc: diff --git a/queue-7.0/iio-chemical-mhz19b-reject-oversized-serial-replies.patch b/queue-7.0/iio-chemical-mhz19b-reject-oversized-serial-replies.patch new file mode 100644 index 0000000000..b33443472a --- /dev/null +++ b/queue-7.0/iio-chemical-mhz19b-reject-oversized-serial-replies.patch @@ -0,0 +1,77 @@ +From 673478bc29cf72010faaf293c1c8c667393335a0 Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Thu, 2 Apr 2026 13:40:15 +0800 +Subject: iio: chemical: mhz19b: reject oversized serial replies + +From: Pengpeng Hou + +commit 673478bc29cf72010faaf293c1c8c667393335a0 upstream. + +mhz19b_receive_buf() appends each serdev chunk into the fixed +MHZ19B_CMD_SIZE receive buffer and advances buf_idx by len without +checking that the chunk fits in the remaining space. A large callback +can therefore overflow st->buf before the command path validates the +reply. + +Reset the reply state before each command and reject oversized serial +replies before copying them into the fixed buffer. When an oversized +reply is detected, wake the waiter and report -EMSGSIZE instead of +overwriting st->buf. + +Fixes: 4572a70b3681 ("iio: chemical: Add support for Winsen MHZ19B CO2 sensor") +Cc: stable@vger.kernel.org +Signed-off-by: Pengpeng Hou +Acked-by: Gyeyoung Baek +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/chemical/mhz19b.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/iio/chemical/mhz19b.c ++++ b/drivers/iio/chemical/mhz19b.c +@@ -52,6 +52,8 @@ struct mhz19b_state { + struct completion buf_ready; + + u8 buf_idx; ++ bool buf_overflow; ++ + /* + * Serdev receive buffer. + * When data is received from the MH-Z19B, +@@ -106,6 +108,10 @@ static int mhz19b_serdev_cmd(struct iio_ + cmd_buf[8] = mhz19b_get_checksum(cmd_buf); + + /* Write buf to uart ctrl synchronously */ ++ st->buf_idx = 0; ++ st->buf_overflow = false; ++ reinit_completion(&st->buf_ready); ++ + ret = serdev_device_write(serdev, cmd_buf, MHZ19B_CMD_SIZE, 0); + if (ret < 0) + return ret; +@@ -121,6 +127,9 @@ static int mhz19b_serdev_cmd(struct iio_ + if (!ret) + return -ETIMEDOUT; + ++ if (st->buf_overflow) ++ return -EMSGSIZE; ++ + if (st->buf[8] != mhz19b_get_checksum(st->buf)) { + dev_err(dev, "checksum err"); + return -EINVAL; +@@ -240,6 +249,14 @@ static size_t mhz19b_receive_buf(struct + { + struct iio_dev *indio_dev = dev_get_drvdata(&serdev->dev); + struct mhz19b_state *st = iio_priv(indio_dev); ++ size_t remaining = MHZ19B_CMD_SIZE - st->buf_idx; ++ ++ if (len > remaining) { ++ st->buf_idx = 0; ++ st->buf_overflow = true; ++ complete(&st->buf_ready); ++ return len; ++ } + + memcpy(st->buf + st->buf_idx, data, len); + st->buf_idx += len; diff --git a/queue-7.0/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch b/queue-7.0/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch new file mode 100644 index 0000000000..83666f651e --- /dev/null +++ b/queue-7.0/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch @@ -0,0 +1,34 @@ +From 5aba4f94b225617a55fed442a70329b2ee19c0a5 Mon Sep 17 00:00:00 2001 +From: Antoniu Miclaus +Date: Wed, 1 Apr 2026 14:08:29 +0300 +Subject: iio: chemical: scd30: fix division by zero in write_raw + +From: Antoniu Miclaus + +commit 5aba4f94b225617a55fed442a70329b2ee19c0a5 upstream. + +Add a zero check for val2 before using it as a divisor when setting the +sampling frequency. A user writing a zero fractional part to the +sampling_frequency sysfs attribute triggers a division by zero in the +kernel. + +Fixes: 64b3d8b1b0f5 ("iio: chemical: scd30: add core driver") +Signed-off-by: Antoniu Miclaus +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/chemical/scd30_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/chemical/scd30_core.c ++++ b/drivers/iio/chemical/scd30_core.c +@@ -256,7 +256,7 @@ static int scd30_write_raw(struct iio_de + guard(mutex)(&state->lock); + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: +- if (val) ++ if (val || !val2) + return -EINVAL; + + val = 1000000000 / val2; diff --git a/queue-7.0/iio-dac-ad3530r-fix-ad3531-ad3531r-powerdown-mode-strings.patch b/queue-7.0/iio-dac-ad3530r-fix-ad3531-ad3531r-powerdown-mode-strings.patch new file mode 100644 index 0000000000..966c0e6dba --- /dev/null +++ b/queue-7.0/iio-dac-ad3530r-fix-ad3531-ad3531r-powerdown-mode-strings.patch @@ -0,0 +1,121 @@ +From ebd250c2581ec46c64c73fdfa918c9a7f757505e Mon Sep 17 00:00:00 2001 +From: Kim Seer Paller +Date: Tue, 5 May 2026 12:34:32 +0800 +Subject: iio: dac: ad3530r: Fix AD3531/AD3531R powerdown mode strings + +From: Kim Seer Paller + +commit ebd250c2581ec46c64c73fdfa918c9a7f757505e upstream. + +The AD3531/AD3531R has different output operating modes from the +AD3530/AD3530R. According to the AD3531/AD3531R datasheet, the +powerdown modes are: + 01: 500 Ohm output impedance + 10: 3.85 kOhm output impedance + 11: 16 kOhm output impedance + +The driver currently uses the AD3530R modes (1k, 7.7k, 32k) for all +variants, which is incorrect for AD3531/AD3531R. + +Add AD3531R-specific powerdown mode strings and assign them to the +AD3531/AD3531R chip variants. + +Fixes: 93583174a3df ("iio: dac: ad3530r: Add driver for AD3530R and AD3531R") +Signed-off-by: Kim Seer Paller +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/dac/ad3530r.c | 54 ++++++++++++++++++++++++++++++++++------------ + 1 file changed, 40 insertions(+), 14 deletions(-) + +--- a/drivers/iio/dac/ad3530r.c ++++ b/drivers/iio/dac/ad3530r.c +@@ -105,6 +105,12 @@ static const char * const ad3530r_powerd + "32kohm_to_gnd", + }; + ++static const char * const ad3531r_powerdown_modes[] = { ++ "500ohm_to_gnd", ++ "3.85kohm_to_gnd", ++ "16kohm_to_gnd", ++}; ++ + static int ad3530r_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) + { +@@ -133,6 +139,13 @@ static const struct iio_enum ad3530r_pow + .set = ad3530r_set_powerdown_mode, + }; + ++static const struct iio_enum ad3531r_powerdown_mode_enum = { ++ .items = ad3531r_powerdown_modes, ++ .num_items = ARRAY_SIZE(ad3531r_powerdown_modes), ++ .get = ad3530r_get_powerdown_mode, ++ .set = ad3530r_set_powerdown_mode, ++}; ++ + static ssize_t ad3530r_get_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, +@@ -276,7 +289,20 @@ static const struct iio_chan_spec_ext_in + { } + }; + +-#define AD3530R_CHAN(_chan) \ ++static const struct iio_chan_spec_ext_info ad3531r_ext_info[] = { ++ { ++ .name = "powerdown", ++ .shared = IIO_SEPARATE, ++ .read = ad3530r_get_dac_powerdown, ++ .write = ad3530r_set_dac_powerdown, ++ }, ++ IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad3531r_powerdown_mode_enum), ++ IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, ++ &ad3531r_powerdown_mode_enum), ++ { } ++}; ++ ++#define AD3530R_CHAN(_chan, _ext_info) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ +@@ -284,25 +310,25 @@ static const struct iio_chan_spec_ext_in + .output = 1, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ +- .ext_info = ad3530r_ext_info, \ ++ .ext_info = _ext_info, \ + } + + static const struct iio_chan_spec ad3530r_channels[] = { +- AD3530R_CHAN(0), +- AD3530R_CHAN(1), +- AD3530R_CHAN(2), +- AD3530R_CHAN(3), +- AD3530R_CHAN(4), +- AD3530R_CHAN(5), +- AD3530R_CHAN(6), +- AD3530R_CHAN(7), ++ AD3530R_CHAN(0, ad3530r_ext_info), ++ AD3530R_CHAN(1, ad3530r_ext_info), ++ AD3530R_CHAN(2, ad3530r_ext_info), ++ AD3530R_CHAN(3, ad3530r_ext_info), ++ AD3530R_CHAN(4, ad3530r_ext_info), ++ AD3530R_CHAN(5, ad3530r_ext_info), ++ AD3530R_CHAN(6, ad3530r_ext_info), ++ AD3530R_CHAN(7, ad3530r_ext_info), + }; + + static const struct iio_chan_spec ad3531r_channels[] = { +- AD3530R_CHAN(0), +- AD3530R_CHAN(1), +- AD3530R_CHAN(2), +- AD3530R_CHAN(3), ++ AD3530R_CHAN(0, ad3531r_ext_info), ++ AD3530R_CHAN(1, ad3531r_ext_info), ++ AD3530R_CHAN(2, ad3531r_ext_info), ++ AD3530R_CHAN(3, ad3531r_ext_info), + }; + + static const struct ad3530r_chip_info ad3530_chip = { diff --git a/queue-7.0/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch b/queue-7.0/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch new file mode 100644 index 0000000000..2bf66782e8 --- /dev/null +++ b/queue-7.0/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch @@ -0,0 +1,63 @@ +From 5237c3175cae5ab05f18878cec3301a04403859e Mon Sep 17 00:00:00 2001 +From: Rodrigo Alencar +Date: Tue, 5 May 2026 13:35:04 +0100 +Subject: iio: dac: ad5686: acquire lock when doing powerdown control + +From: Rodrigo Alencar + +commit 5237c3175cae5ab05f18878cec3301a04403859e upstream. + +Protect access of pwr_down_mode and pwr_down_mask fields with existing +mutex lock. Each channel exposes their own attributes for controlling +powerdown modes and powerdown state. This fixes potential race conditions +as those the write functions perform non-atomic read-modify-write +operations to those pwr_down_* fields. This issue exists since the ad5686 +driver was first introduced. + +Fixes: c2f37c8dcadc ("iio: dac: New driver for AD5686R, AD5685R, AD5684R Digital to analog converters") +Signed-off-by: Rodrigo Alencar +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/dac/ad5686.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/iio/dac/ad5686.c ++++ b/drivers/iio/dac/ad5686.c +@@ -30,6 +30,8 @@ static int ad5686_get_powerdown_mode(str + { + struct ad5686_state *st = iio_priv(indio_dev); + ++ guard(mutex)(&st->lock); ++ + return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1; + } + +@@ -39,6 +41,8 @@ static int ad5686_set_powerdown_mode(str + { + struct ad5686_state *st = iio_priv(indio_dev); + ++ guard(mutex)(&st->lock); ++ + st->pwr_down_mode &= ~(0x3 << (chan->channel * 2)); + st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2)); + +@@ -57,6 +61,8 @@ static ssize_t ad5686_read_dac_powerdown + { + struct ad5686_state *st = iio_priv(indio_dev); + ++ guard(mutex)(&st->lock); ++ + return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & + (0x3 << (chan->channel * 2)))); + } +@@ -77,6 +83,8 @@ static ssize_t ad5686_write_dac_powerdow + if (ret) + return ret; + ++ guard(mutex)(&st->lock); ++ + if (readin) + st->pwr_down_mask |= (0x3 << (chan->channel * 2)); + else diff --git a/queue-7.0/iio-dac-ad5686-fix-input-raw-value-check.patch b/queue-7.0/iio-dac-ad5686-fix-input-raw-value-check.patch new file mode 100644 index 0000000000..eb1037ea39 --- /dev/null +++ b/queue-7.0/iio-dac-ad5686-fix-input-raw-value-check.patch @@ -0,0 +1,35 @@ +From d01220ee5e43c65a206df827b39bf5cf5f7b9dce Mon Sep 17 00:00:00 2001 +From: Rodrigo Alencar +Date: Fri, 1 May 2026 10:14:55 +0100 +Subject: iio: dac: ad5686: fix input raw value check + +From: Rodrigo Alencar + +commit d01220ee5e43c65a206df827b39bf5cf5f7b9dce upstream. + +Fix range check for input raw value, which is off by one, i.e., for a +10-bit DAC the max valid value is 1023, but 1 << 10 equals 1024, which +passes the previous check, allowing an out-of-range write. The issue +exists since the ad5686 driver was first introduced. + +Fixes: c2f37c8dcadc ("iio: dac: New driver for AD5686R, AD5685R, AD5684R Digital to analog converters") +Reviewed-by: Andy Shevchenko +Signed-off-by: Rodrigo Alencar +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/dac/ad5686.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/dac/ad5686.c ++++ b/drivers/iio/dac/ad5686.c +@@ -154,7 +154,7 @@ static int ad5686_write_raw(struct iio_d + + switch (mask) { + case IIO_CHAN_INFO_RAW: +- if (val > (1 << chan->scan_type.realbits) || val < 0) ++ if (val >= (1 << chan->scan_type.realbits) || val < 0) + return -EINVAL; + + mutex_lock(&st->lock); diff --git a/queue-7.0/iio-dac-ad5686-fix-powerdown-control-on-dual-channel-devices.patch b/queue-7.0/iio-dac-ad5686-fix-powerdown-control-on-dual-channel-devices.patch new file mode 100644 index 0000000000..fb0d67abd0 --- /dev/null +++ b/queue-7.0/iio-dac-ad5686-fix-powerdown-control-on-dual-channel-devices.patch @@ -0,0 +1,130 @@ +From 8aeaf25a85263a7a43357e16ad78ab969f6f8aeb Mon Sep 17 00:00:00 2001 +From: Rodrigo Alencar +Date: Tue, 5 May 2026 13:35:05 +0100 +Subject: iio: dac: ad5686: fix powerdown control on dual-channel devices + +From: Rodrigo Alencar + +commit 8aeaf25a85263a7a43357e16ad78ab969f6f8aeb upstream. + +Fix powerdown control by using a proper bit shift for the powerdown mask +values. During initialization, powerdown bits are initialized so that +unused bits are set to 1 and the correct bit shift is used. Dual-channel +devices use one-hot encoding in the address and that reflects on the +position of the powerdown bits, which are not channel-index based +for that case. Quad-channel devices also use one-hot encoding for the +channel address but the result of log2(address) coincides with the channel +index value. Mask as 0x3U is used rather than 0x3, because shift can reach +value of 30 (last channel of a 16-channel device), which would mess with +the sign bit. The issue was introduced when first adding support for +dual-channel devices, which overlooked powerdown control differences. + +Fixes: 7dc8faeab3e3 ("iio: dac: ad5686: add support for AD5338R") +Signed-off-by: Rodrigo Alencar +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/dac/ad5686.c | 40 ++++++++++++++++++++++++++++++---------- + 1 file changed, 30 insertions(+), 10 deletions(-) + +--- a/drivers/iio/dac/ad5686.c ++++ b/drivers/iio/dac/ad5686.c +@@ -25,26 +25,37 @@ static const char * const ad5686_powerdo + "three_state" + }; + ++static inline unsigned int ad5686_pd_mask_shift(const struct iio_chan_spec *chan) ++{ ++ if (chan->channel == chan->address) ++ return chan->channel * 2; ++ ++ /* one-hot encoding is used in dual/quad channel devices */ ++ return __ffs(chan->address) * 2; ++} ++ + static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) + { ++ unsigned int shift = ad5686_pd_mask_shift(chan); + struct ad5686_state *st = iio_priv(indio_dev); + + guard(mutex)(&st->lock); + +- return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1; ++ return ((st->pwr_down_mode >> shift) & 0x3U) - 1; + } + + static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int mode) + { ++ unsigned int shift = ad5686_pd_mask_shift(chan); + struct ad5686_state *st = iio_priv(indio_dev); + + guard(mutex)(&st->lock); + +- st->pwr_down_mode &= ~(0x3 << (chan->channel * 2)); +- st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2)); ++ st->pwr_down_mode &= ~(0x3U << shift); ++ st->pwr_down_mode |= (mode + 1) << shift; + + return 0; + } +@@ -59,12 +70,12 @@ static const struct iio_enum ad5686_powe + static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) + { ++ unsigned int shift = ad5686_pd_mask_shift(chan); + struct ad5686_state *st = iio_priv(indio_dev); + + guard(mutex)(&st->lock); + +- return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & +- (0x3 << (chan->channel * 2)))); ++ return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & (0x3U << shift))); + } + + static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, +@@ -86,9 +97,9 @@ static ssize_t ad5686_write_dac_powerdow + guard(mutex)(&st->lock); + + if (readin) +- st->pwr_down_mask |= (0x3 << (chan->channel * 2)); ++ st->pwr_down_mask |= 0x3U << ad5686_pd_mask_shift(chan); + else +- st->pwr_down_mask &= ~(0x3 << (chan->channel * 2)); ++ st->pwr_down_mask &= ~(0x3U << ad5686_pd_mask_shift(chan)); + + switch (st->chip_info->regmap_type) { + case AD5310_REGMAP: +@@ -468,7 +479,7 @@ int ad5686_probe(struct device *dev, + { + struct ad5686_state *st; + struct iio_dev *indio_dev; +- unsigned int val, ref_bit_msk; ++ unsigned int val, ref_bit_msk, shift; + bool has_external_vref; + u8 cmd; + int ret, i; +@@ -492,9 +503,18 @@ int ad5686_probe(struct device *dev, + has_external_vref = ret != -ENODEV; + st->vref_mv = has_external_vref ? ret / 1000 : st->chip_info->int_vref_mv; + ++ /* Initialize masks to all ones provided the max shift (last channel) */ ++ shift = ad5686_pd_mask_shift(&st->chip_info->channels[st->chip_info->num_channels - 1]); ++ st->pwr_down_mask = GENMASK(shift + 1, 0); ++ st->pwr_down_mode = GENMASK(shift + 1, 0); ++ + /* Set all the power down mode for all channels to 1K pulldown */ +- for (i = 0; i < st->chip_info->num_channels; i++) +- st->pwr_down_mode |= (0x01 << (i * 2)); ++ for (i = 0; i < st->chip_info->num_channels; i++) { ++ shift = ad5686_pd_mask_shift(&st->chip_info->channels[i]); ++ st->pwr_down_mask &= ~(0x3U << shift); /* powered up state */ ++ st->pwr_down_mode &= ~(0x3U << shift); ++ st->pwr_down_mode |= 0x01U << shift; ++ } + + indio_dev->name = name; + indio_dev->info = &ad5686_info; diff --git a/queue-7.0/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch b/queue-7.0/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch new file mode 100644 index 0000000000..1035e524b4 --- /dev/null +++ b/queue-7.0/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch @@ -0,0 +1,60 @@ +From ecae2ae606d493cf11457946436335bd0e726663 Mon Sep 17 00:00:00 2001 +From: Rodrigo Alencar +Date: Fri, 1 May 2026 10:14:54 +0100 +Subject: iio: dac: ad5686: fix ref bit initialization for single-channel parts + +From: Rodrigo Alencar + +commit ecae2ae606d493cf11457946436335bd0e726663 upstream. + +The reference bit position was ignored when writing the register at the +probe() function (!!val was used). When such bit is 1, internal voltage +reference is disabled so that an external one can be used. For +multi-channel devices, bit 0 of the Internal Reference Setup command +behaves the same way, so AD5686_REF_BIT_MSK is created. The issue exists +since support for single-channel devices were first introduced. + +Fixes: be1b24d24541 ("iio:dac:ad5686: Add AD5691R/AD5692R/AD5693/AD5693R support") +Reviewed-by: Andy Shevchenko +Signed-off-by: Rodrigo Alencar +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/dac/ad5686.c | 6 +++--- + drivers/iio/dac/ad5686.h | 1 + + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/iio/dac/ad5686.c ++++ b/drivers/iio/dac/ad5686.c +@@ -509,7 +509,7 @@ int ad5686_probe(struct device *dev, + break; + case AD5686_REGMAP: + cmd = AD5686_CMD_INTERNAL_REFER_SETUP; +- ref_bit_msk = 0; ++ ref_bit_msk = AD5686_REF_BIT_MSK; + break; + case AD5693_REGMAP: + cmd = AD5686_CMD_CONTROL_REG; +@@ -520,9 +520,9 @@ int ad5686_probe(struct device *dev, + return -EINVAL; + } + +- val = (has_external_vref | ref_bit_msk); ++ val = has_external_vref ? ref_bit_msk : 0; + +- ret = st->write(st, cmd, 0, !!val); ++ ret = st->write(st, cmd, 0, val); + if (ret) + return ret; + +--- a/drivers/iio/dac/ad5686.h ++++ b/drivers/iio/dac/ad5686.h +@@ -46,6 +46,7 @@ + + #define AD5310_REF_BIT_MSK BIT(8) + #define AD5683_REF_BIT_MSK BIT(12) ++#define AD5686_REF_BIT_MSK BIT(0) + #define AD5693_REF_BIT_MSK BIT(12) + + /** diff --git a/queue-7.0/iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch b/queue-7.0/iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch new file mode 100644 index 0000000000..217cb2623d --- /dev/null +++ b/queue-7.0/iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch @@ -0,0 +1,54 @@ +From d0a228d903425e653f18a4341e60c0538afb6d41 Mon Sep 17 00:00:00 2001 +From: Salah Triki +Date: Mon, 27 Apr 2026 22:33:19 +0100 +Subject: iio: dac: max5821: fix return value check in powerdown sync + +From: Salah Triki + +commit d0a228d903425e653f18a4341e60c0538afb6d41 upstream. + +The function max5821_sync_powerdown_mode() returned the result of +i2c_master_send() directly. If a partial transfer occurred, it would +be incorrectly treated as a success by the caller. + +While the caller currently handles the positive return value of 2 as +success, this patch refactors the function to return 0 on full success +and -EIO on short writes. This ensures robust error handling for +incomplete transfers and improves code maintainability by using +sizeof(outbuf). + +Fixes: 472988972737 ("iio: add support of the max5821") +Signed-off-by: Salah Triki +Reviewed-by: Andy Shevchenko +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/dac/max5821.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/iio/dac/max5821.c ++++ b/drivers/iio/dac/max5821.c +@@ -90,6 +90,7 @@ static int max5821_sync_powerdown_mode(s + const struct iio_chan_spec *chan) + { + u8 outbuf[2]; ++ int ret; + + outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE; + +@@ -103,7 +104,13 @@ static int max5821_sync_powerdown_mode(s + else + outbuf[1] |= MAX5821_EXTENDED_POWER_UP; + +- return i2c_master_send(data->client, outbuf, 2); ++ ret = i2c_master_send(data->client, outbuf, sizeof(outbuf)); ++ if (ret < 0) ++ return ret; ++ if (ret != sizeof(outbuf)) ++ return -EIO; ++ ++ return 0; + } + + static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev, diff --git a/queue-7.0/iio-fix-iio_multiply_value-use-in-iio_read_channel_processed_scale.patch b/queue-7.0/iio-fix-iio_multiply_value-use-in-iio_read_channel_processed_scale.patch new file mode 100644 index 0000000000..560ee3fb26 --- /dev/null +++ b/queue-7.0/iio-fix-iio_multiply_value-use-in-iio_read_channel_processed_scale.patch @@ -0,0 +1,41 @@ +From bb21ee31f5753a7972148798fd7dfb841dd33bdb Mon Sep 17 00:00:00 2001 +From: Svyatoslav Ryhel +Date: Thu, 16 Apr 2026 14:14:42 +0300 +Subject: iio: Fix iio_multiply_value use in iio_read_channel_processed_scale + +From: Svyatoslav Ryhel + +commit bb21ee31f5753a7972148798fd7dfb841dd33bdb upstream. + +The function iio_multiply_value returns IIO_VAL_INT (1) on success or a +negative error number on failure, while iio_read_channel_processed_scale +should return an error code or 0. This creates a situation where the +expected result is treated as an error. Fix this by checking the +iio_multiply_value result separately, instead of passing it as a return +value. + +Fixes: 05f958d003c9 ("iio: Improve iio_read_channel_processed_scale() precision") +Signed-off-by: Svyatoslav Ryhel +Reviewed-by: Hans de Goede +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/inkern.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/iio/inkern.c ++++ b/drivers/iio/inkern.c +@@ -738,7 +738,11 @@ int iio_read_channel_processed_scale(str + if (ret < 0) + return ret; + +- return iio_multiply_value(val, scale, ret, pval, pval2); ++ ret = iio_multiply_value(val, scale, ret, pval, pval2); ++ if (ret < 0) ++ return ret; ++ ++ return 0; + } else { + ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW); + if (ret < 0) diff --git a/queue-7.0/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch b/queue-7.0/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch new file mode 100644 index 0000000000..11367a1372 --- /dev/null +++ b/queue-7.0/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch @@ -0,0 +1,38 @@ +From 761e8b489e6cf166c574034b70637f8a7eadd0ee Mon Sep 17 00:00:00 2001 +From: Antoniu Miclaus +Date: Tue, 31 Mar 2026 13:13:00 +0300 +Subject: iio: gyro: adis16260: fix division by zero in write_raw +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antoniu Miclaus + +commit 761e8b489e6cf166c574034b70637f8a7eadd0ee upstream. + +Add a validation check for the sampling frequency value before using it +as a divisor. A user writing zero to the sampling_frequency sysfs +attribute triggers a division by zero in the kernel. + +Fixes: 089a41985c6c ("staging: iio: adis16260 digital gyro driver") +Signed-off-by: Antoniu Miclaus +Reviewed-by: Nuno Sá +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/gyro/adis16260.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/iio/gyro/adis16260.c ++++ b/drivers/iio/gyro/adis16260.c +@@ -287,6 +287,9 @@ static int adis16260_write_raw(struct ii + addr = adis16260_addresses[chan->scan_index][1]; + return adis_write_reg_16(adis, addr, val); + case IIO_CHAN_INFO_SAMP_FREQ: ++ if (val <= 0) ++ return -EINVAL; ++ + if (spi_get_device_id(adis->spi)->driver_data) + t = 256 / val; + else diff --git a/queue-7.0/iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch b/queue-7.0/iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch new file mode 100644 index 0000000000..b9a66a4e6f --- /dev/null +++ b/queue-7.0/iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch @@ -0,0 +1,53 @@ +From 6bdc3023d62ed5c7d591f0eb27a5adb37fb892ae Mon Sep 17 00:00:00 2001 +From: David Carlier +Date: Tue, 5 May 2026 14:37:48 +0100 +Subject: iio: gyro: itg3200: fix i2c read into the wrong stack location + +From: David Carlier + +commit 6bdc3023d62ed5c7d591f0eb27a5adb37fb892ae upstream. + +itg3200_read_all_channels() takes `__be16 *buf' as a parameter and +fills the i2c_msg destination as `(char *)&buf'. Since `buf' is the +parameter (a pointer), `&buf' is the address of the local pointer +slot on the stack of itg3200_read_all_channels(), not the address +of the caller's scan buffer. The (char *) cast hides the type +mismatch. + +i2c_transfer() therefore writes ITG3200_SCAN_ELEMENTS * sizeof(s16) += 8 bytes into the parameter's stack slot, which is discarded when +the function returns. The caller's scan buffer in +itg3200_trigger_handler() is never written to, so +iio_push_to_buffers_with_timestamp() pushes uninitialised stack +contents to userspace via /dev/iio:deviceX every scan -- both a +functional bug (no actual gyroscope or temperature data is +delivered through the triggered buffer) and an information leak. + +The non-buffered read_raw() path is unaffected: it goes through +itg3200_read_reg_s16() which uses `&out' on a local s16 value, +where that is correct. + +Drop the spurious `&' so the i2c read writes into the caller's +buffer. + +Fixes: 9dbf091da080 ("iio: gyro: Add itg3200") +Cc: stable@vger.kernel.org +Signed-off-by: David Carlier +Reviewed-by: Andy Shevchenko +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/gyro/itg3200_buffer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/gyro/itg3200_buffer.c ++++ b/drivers/iio/gyro/itg3200_buffer.c +@@ -34,7 +34,7 @@ static int itg3200_read_all_channels(str + .addr = i2c->addr, + .flags = i2c->flags | I2C_M_RD, + .len = ITG3200_SCAN_ELEMENTS * sizeof(s16), +- .buf = (char *)&buf, ++ .buf = (char *)buf, + }, + }; + diff --git a/queue-7.0/iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch b/queue-7.0/iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch new file mode 100644 index 0000000000..5395af029f --- /dev/null +++ b/queue-7.0/iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch @@ -0,0 +1,66 @@ +From 1f4f0bcc5255dec5c4c3a1551bf49d8c33b69b20 Mon Sep 17 00:00:00 2001 +From: Aldo Conte +Date: Tue, 7 Apr 2026 17:17:01 +0200 +Subject: iio: light: cm3323: fix reg_conf not being initialized correctly + +From: Aldo Conte + +commit 1f4f0bcc5255dec5c4c3a1551bf49d8c33b69b20 upstream. + +The code stores the return value of i2c_smbus_write_word_data() +in data->reg_conf; however, this value represents the result +of the write operation and not the value actually written to +the configuration register. This meant that the contents of +data->reg_conf did not truly reflect the contents +of the hardware register. + +Instead, save the value of the register before the write +and use this value in the I2C write. + +The bug was found by code inspection: i2c_smbus_write_word_data() +returns 0 on success, not the value written to the register. + +Tested using i2c-stub on a Raspberry Pi 3B running a custom 6.19.10 +kernel. Before loading the driver, the configuration register 0x00 +CM3323_CMD_CONF was populated with 0x0030 using +`i2cset -y 11 0x10 0x00 0x0030 w`, encoding an integration time of 320ms +in bits[6:4]. + +Due to incorrect initialization of data->reg_conf in +cm3323_init(), the print of integration_time returns 0.040000 +instead of the expected 0.320000. This happens because the read of the +integration_time depends on cm3323_get_it_bits() that is based on the +value of data->reg_conf, which is erroneously set to 0. + +With this fix applied, data->reg_conf correctly saves 0x0030 after init +and the successive integration_time reports 0.320000 as expected. + +Fixes: 8b0544263761 ("iio: light: Add support for Capella CM3323 color sensor") +Cc: stable@vger.kernel.org +Signed-off-by: Aldo Conte +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/light/cm3323.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/iio/light/cm3323.c ++++ b/drivers/iio/light/cm3323.c +@@ -89,15 +89,14 @@ static int cm3323_init(struct iio_dev *i + + /* enable sensor and set auto force mode */ + ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT); ++ data->reg_conf = ret; + +- ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret); ++ ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, data->reg_conf); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_conf\n"); + return ret; + } + +- data->reg_conf = ret; +- + return 0; + } + diff --git a/queue-7.0/iio-light-veml6070-fix-resource-leak-in-probe-error-path.patch b/queue-7.0/iio-light-veml6070-fix-resource-leak-in-probe-error-path.patch new file mode 100644 index 0000000000..c56e98ab1b --- /dev/null +++ b/queue-7.0/iio-light-veml6070-fix-resource-leak-in-probe-error-path.patch @@ -0,0 +1,64 @@ +From b66f922f6a4fa92840f662fbcfeb4f8a0f774bcc Mon Sep 17 00:00:00 2001 +From: Felix Gu +Date: Fri, 27 Mar 2026 20:27:54 +0800 +Subject: iio: light: veml6070: Fix resource leak in probe error path + +From: Felix Gu + +commit b66f922f6a4fa92840f662fbcfeb4f8a0f774bcc upstream. + +The driver calls i2c_new_dummy_device() to create a dummy device, +then calls i2c_smbus_write_byte(). If i2c_smbus_write_byte() fails and +returns, the cleanup via devm_add_action_or_reset() was never registered, +so the dummy device leaks. + +Switch to devm_i2c_new_dummy_device() which registers cleanup atomically +with device creation, eliminating the error-path window. + +Fixes: 7501bff87c3e ("iio: light: veml6070: add action for i2c_unregister_device") +Reviewed-by: Andy Shevchenko +Signed-off-by: Felix Gu +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/light/veml6070.c | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) + +--- a/drivers/iio/light/veml6070.c ++++ b/drivers/iio/light/veml6070.c +@@ -245,13 +245,6 @@ static const struct iio_info veml6070_in + .write_raw = veml6070_write_raw, + }; + +-static void veml6070_i2c_unreg(void *p) +-{ +- struct veml6070_data *data = p; +- +- i2c_unregister_device(data->client2); +-} +- + static int veml6070_probe(struct i2c_client *client) + { + struct veml6070_data *data; +@@ -281,7 +274,8 @@ static int veml6070_probe(struct i2c_cli + if (ret < 0) + return ret; + +- data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB); ++ data->client2 = devm_i2c_new_dummy_device(&client->dev, client->adapter, ++ VEML6070_ADDR_DATA_LSB); + if (IS_ERR(data->client2)) + return dev_err_probe(&client->dev, PTR_ERR(data->client2), + "i2c device for second chip address failed\n"); +@@ -292,10 +286,6 @@ static int veml6070_probe(struct i2c_cli + if (ret < 0) + return ret; + +- ret = devm_add_action_or_reset(&client->dev, veml6070_i2c_unreg, data); +- if (ret < 0) +- return ret; +- + return devm_iio_device_register(&client->dev, indio_dev); + } + diff --git a/queue-7.0/iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch b/queue-7.0/iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch new file mode 100644 index 0000000000..6d54dc35aa --- /dev/null +++ b/queue-7.0/iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch @@ -0,0 +1,60 @@ +From 49f79cd28f1e3333cbe0d616ce59ead0b24bf34e Mon Sep 17 00:00:00 2001 +From: Advait Dhamorikar +Date: Tue, 7 Apr 2026 12:50:59 +0530 +Subject: iio: magnetometer: st_magn: fix default DRDY pin selection for LIS2MDL + +From: Advait Dhamorikar + +commit 49f79cd28f1e3333cbe0d616ce59ead0b24bf34e upstream. + +The device tree binding for st,lis2mdl does not support +st,drdy-int-pin property. However, when no platform data is provided +and the property is absent, the driver falls back to default_magn_pdata +which hardcodes drdy_int_pin = 2. This causes +`st_sensors_set_drdy_int_pin` to fail with -EINVAL because the LIS2MDL +sensor settings have no INT2 DRDY mask defined. + +Fix this by checking the sensor's INT2 DRDY mask availability at +probe time and selecting the appropriate default pin. Sensors that +do not support INT2 DRDY will default to INT1, while all others +retain the existing default of INT2. + +Fixes: 38934daf7b5c ("iio: magnetometer: st_magn: Provide default platform data") +Signed-off-by: Advait Dhamorikar +Reviewed-by: Andy Shevchenko +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/magnetometer/st_magn_core.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/iio/magnetometer/st_magn_core.c ++++ b/drivers/iio/magnetometer/st_magn_core.c +@@ -506,6 +506,11 @@ static const struct st_sensors_platform_ + .drdy_int_pin = 2, + }; + ++/* LIS2MDL only supports DRDY on INT1 */ ++static const struct st_sensors_platform_data alt_magn_pdata = { ++ .drdy_int_pin = 1, ++}; ++ + static int st_magn_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *ch, int *val, + int *val2, long mask) +@@ -628,8 +633,12 @@ int st_magn_common_probe(struct iio_dev + mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0]; + mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz; + +- if (!pdata) +- pdata = (struct st_sensors_platform_data *)&default_magn_pdata; ++ if (!pdata) { ++ if (mdata->sensor_settings->drdy_irq.int2.mask) ++ pdata = (struct st_sensors_platform_data *)&default_magn_pdata; ++ else ++ pdata = (struct st_sensors_platform_data *)&alt_magn_pdata; ++ } + + err = st_sensors_init_sensor(indio_dev, pdata); + if (err < 0) diff --git a/queue-7.0/iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch b/queue-7.0/iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch new file mode 100644 index 0000000000..cbedb84a23 --- /dev/null +++ b/queue-7.0/iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch @@ -0,0 +1,31 @@ +From eedf7602fbd929e97e0c480da501dc7a34beb2a8 Mon Sep 17 00:00:00 2001 +From: Sanjay Chitroda +Date: Sun, 26 Apr 2026 14:47:04 +0530 +Subject: iio: ssp_sensors: cancel delayed work_refresh on remove + +From: Sanjay Chitroda + +commit eedf7602fbd929e97e0c480da501dc7a34beb2a8 upstream. + +The work_refresh may still be pending or running when the device is +removed, cancel the delayed work_refresh in remove path. + +Fixes: 50dd64d57eee ("iio: common: ssp_sensors: Add sensorhub driver") +Signed-off-by: Sanjay Chitroda +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/common/ssp_sensors/ssp_dev.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/iio/common/ssp_sensors/ssp_dev.c ++++ b/drivers/iio/common/ssp_sensors/ssp_dev.c +@@ -590,6 +590,7 @@ static void ssp_remove(struct spi_device + ssp_clean_pending_list(data); + + free_irq(data->spi->irq, data); ++ cancel_delayed_work_sync(&data->work_refresh); + + timer_delete_sync(&data->wdt_timer); + cancel_work_sync(&data->work_wdt); diff --git a/queue-7.0/iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch b/queue-7.0/iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch new file mode 100644 index 0000000000..c105712276 --- /dev/null +++ b/queue-7.0/iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch @@ -0,0 +1,41 @@ +From 4701e471c16866e7aa8f5e6a3a6b0d31e097e2c9 Mon Sep 17 00:00:00 2001 +From: Salah Triki +Date: Tue, 5 May 2026 08:10:24 +0100 +Subject: iio: temperature: tsys01: fix broken PROM checksum validation + +From: Salah Triki + +commit 4701e471c16866e7aa8f5e6a3a6b0d31e097e2c9 upstream. + +The current implementation of tsys01_crc_valid() incorrectly sums the +first word (n_prom[0]) repeatedly instead of iterating over the 8 words +retrieved from the PROM. This leads to a checksum mismatch and probe +failure on hardware. + +According to the TSYS01 datasheet, the PROM consists of 8 words. A valid +check must iterate through all 8 words to verify the integrity of the +calibration data. The current driver only checks the first word 8 times. + +Note: This fix was identified during a code audit and is based on +datasheet specifications. It has not been tested on real hardware. + +Fixes: 43e53407f680 ("Add tsys01 meas-spec driver support") +Signed-off-by: Salah Triki +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/temperature/tsys01.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/temperature/tsys01.c ++++ b/drivers/iio/temperature/tsys01.c +@@ -119,7 +119,7 @@ static bool tsys01_crc_valid(u16 *n_prom + u8 sum = 0; + + for (cnt = 0; cnt < TSYS01_PROM_WORDS_NB; cnt++) +- sum += ((n_prom[0] >> 8) + (n_prom[0] & 0xFF)); ++ sum += ((n_prom[cnt] >> 8) + (n_prom[cnt] & 0xFF)); + + return (sum == 0); + } diff --git a/queue-7.0/input-elan_i2c-validate-firmware-size-before-use.patch b/queue-7.0/input-elan_i2c-validate-firmware-size-before-use.patch new file mode 100644 index 0000000000..e1c12b7a28 --- /dev/null +++ b/queue-7.0/input-elan_i2c-validate-firmware-size-before-use.patch @@ -0,0 +1,36 @@ +From 76b0d0baa9ae9c60e726bbe1b6ff0bec2c993634 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Sat, 25 Apr 2026 22:07:06 -0700 +Subject: Input: elan_i2c - validate firmware size before use + +From: Dmitry Torokhov + +commit 76b0d0baa9ae9c60e726bbe1b6ff0bec2c993634 upstream. + +Ensure that the firmware file is large enough to contain the expected +number of pages and the signature (which resides at the end of the +firmware blob) before accessing them to prevent potential out-of-bounds +reads. + +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/ae2dOgiFvXRm4BHo@google.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/mouse/elan_i2c_core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -645,6 +645,11 @@ static ssize_t elan_sysfs_update_fw(stru + return error; + } + ++ if (fw->size < data->fw_signature_address + sizeof(signature)) { ++ dev_err(dev, "firmware file too small\n"); ++ return -EBADF; ++ } ++ + /* Firmware file must match signature data */ + fw_signature = &fw->data[data->fw_signature_address]; + if (memcmp(fw_signature, signature, sizeof(signature)) != 0) { diff --git a/queue-7.0/input-xpad-fix-out-of-bounds-access-for-share-button.patch b/queue-7.0/input-xpad-fix-out-of-bounds-access-for-share-button.patch new file mode 100644 index 0000000000..519ce68737 --- /dev/null +++ b/queue-7.0/input-xpad-fix-out-of-bounds-access-for-share-button.patch @@ -0,0 +1,45 @@ +From 6cdc46b38cf146ce81d4831b6472dbf7731849a2 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Sun, 26 Apr 2026 21:09:33 -0700 +Subject: Input: xpad - fix out-of-bounds access for Share button + +From: Dmitry Torokhov + +commit 6cdc46b38cf146ce81d4831b6472dbf7731849a2 upstream. + +xpadone_process_packet() receives len directly from urb->actual_length +and uses it to index the share-button byte at data[len - 18] or +data[len - 26]. Since both len and data[0] are under the device's +control, a broken controller can send a GIP_CMD_INPUT packet with +actual_length < 18 (e.g. 5 bytes) and reach this code path, causing +accesses beyond the actual array. + +Fix this by calculating the offset and checking bounds against the +packet length. + +Reported-by: Greg Kroah-Hartman +Fixes: 4ef46367073b ("Input: xpad - fix Share button on Xbox One controllers") +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/joystick/xpad.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -1110,10 +1110,10 @@ static void xpadone_process_packet(struc + input_report_key(dev, BTN_START, data[4] & BIT(2)); + input_report_key(dev, BTN_SELECT, data[4] & BIT(3)); + if (xpad->mapping & MAP_SHARE_BUTTON) { +- if (xpad->mapping & MAP_SHARE_OFFSET) +- input_report_key(dev, KEY_RECORD, data[len - 26] & BIT(0)); +- else +- input_report_key(dev, KEY_RECORD, data[len - 18] & BIT(0)); ++ u32 offset = (xpad->mapping & MAP_SHARE_OFFSET) ? 26 : 18; ++ ++ if (len >= offset) ++ input_report_key(dev, KEY_RECORD, data[len - offset] & BIT(0)); + } + + /* buttons A,B,X,Y */ diff --git a/queue-7.0/ipc-limit-next_id-allocation-to-the-valid-id-range.patch b/queue-7.0/ipc-limit-next_id-allocation-to-the-valid-id-range.patch new file mode 100644 index 0000000000..adf55d3525 --- /dev/null +++ b/queue-7.0/ipc-limit-next_id-allocation-to-the-valid-id-range.patch @@ -0,0 +1,81 @@ +From fa0b9b2b7ae3539908d69c2b9ac0d144d9bc5139 Mon Sep 17 00:00:00 2001 +From: Linpu Yu +Date: Sun, 10 May 2026 13:43:30 +0800 +Subject: ipc: limit next_id allocation to the valid ID range + +From: Linpu Yu + +commit fa0b9b2b7ae3539908d69c2b9ac0d144d9bc5139 upstream. + +The checkpoint/restore sysctl path can request the next SysV IPC id +through ids->next_id. ipc_idr_alloc() currently forwards that request to +idr_alloc() with an open-ended upper bound. + +If the valid tail of the SysV IPC id space is full, the allocation can +spill beyond ipc_mni. The returned SysV IPC id still uses the normal +index encoding, so later lookup and removal can target the wrong slot. +This leaves the real IDR entry behind and breaks the IDR state for the +object. + +The bug is in ipc_idr_alloc() in the checkpoint/restore path. + +1. ids->next_id is passed to: + + idr_alloc(&ids->ipcs_idr, new, ipcid_to_idx(next_id), 0, ...) + +2. The zero upper bound makes the allocation effectively open-ended. + Once the valid SysV IPC tail is occupied, idr_alloc() can spill past + ipc_mni and allocate an entry beyond the valid IPC id range. + +3. The new object id is still encoded with the narrower SysV IPC index + width: + + new->id = (new->seq << ipcmni_seq_shift()) + idx + +4. Later removal goes through ipc_rmid(), which uses: + + ipcid_to_idx(ipcp->id) + + That truncates the real IDR index. An object actually stored at a + high index can then be removed as if it lived at a low in-range + index. + +5. For shared memory, shm_destroy() frees the current object anyway, but + the real high IDR slot is left behind as a dangling pointer. + +6. A subsequent walk of /proc/sysvipc/shm reaches the stale IDR entry + and dereferences freed memory. + +Prevent this by bounding the requested allocation to ipc_mni so the +checkpoint/restore path fails once the valid range is exhausted. + +Link: https://lore.kernel.org/cover.1778336914.git.linpu5433@gmail.com +Link: https://lore.kernel.org/2eebe949bfa7d1f6e13b5be6a92c64c850ce9d45.1778336914.git.linpu5433@gmail.com +Fixes: 03f595668017 ("ipc: add sysctl to specify desired next object id") +Signed-off-by: Linpu Yu +Signed-off-by: Ren Wei +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Cc: Kees Cook +Cc: Stanislav Kinsbursky +Cc: Davidlohr Bueso +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + ipc/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/ipc/util.c ++++ b/ipc/util.c +@@ -253,7 +253,7 @@ static inline int ipc_idr_alloc(struct i + } else { + new->seq = ipcid_to_seqx(next_id); + idx = idr_alloc(&ids->ipcs_idr, new, ipcid_to_idx(next_id), +- 0, GFP_NOWAIT); ++ ipc_mni, GFP_NOWAIT); + } + if (idx >= 0) + new->id = (new->seq << ipcmni_seq_shift()) + idx; diff --git a/queue-7.0/kvm-arm64-correctly-cap-zcr_el2-provided-by-a-guest-hypervisor.patch b/queue-7.0/kvm-arm64-correctly-cap-zcr_el2-provided-by-a-guest-hypervisor.patch new file mode 100644 index 0000000000..4c048a80bd --- /dev/null +++ b/queue-7.0/kvm-arm64-correctly-cap-zcr_el2-provided-by-a-guest-hypervisor.patch @@ -0,0 +1,159 @@ +From 83726330748981372bde86ed5411d7b306612991 Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Fri, 29 May 2026 00:01:44 +0100 +Subject: KVM: arm64: Correctly cap ZCR_EL2 provided by a guest hypervisor + +From: Mark Brown + +commit 83726330748981372bde86ed5411d7b306612991 upstream. + +ZCR_EL2 can be updated by a VHE guest hypervisor either using ZCR_EL2 +(which traps) or ZCR_EL1 (which does not trap). KVM handles both in +different way: + +- on ZCR_EL2 trap, ZCR_EL2.LEN is immediately capped at the VM's own + VL limit. This has the potential to break existing SW that relies + on the full LEN field to be stateful. + +- on ZCR_EL1 access, we do absolutely nothing. + +On restoring the SVE context for an L2 guest, we directly restore the +guest hypervisor's view of ZCR_EL2 into the physical ZCR_EL2. If the +guest's view of the register was updated using the ZCR_EL2 accessor, +the value has already been sanitised (with the caveat mentioned above). + +But if the guest used ZCR_EL1, the raw value is written into the HW, +and the L2 guest can now access VLs that it shouldn't. + +Fix all the above by moving the VL capping to the restore points, +ensuring that: + +- the HW is always programmed with a capped value, irrespective of + the accessor being used, + +- the ZCR_EL2.LEN field is always completely stateful, irrespective + of the accessor being used. + +Additionally, move ZCR_EL2 to be a sanitised register, ensuring that +only the LEN field is actually stateful. This requires some creative +construction of the RES0 mask, as the sysreg generation script does +not yet generate RAZ/WI fields. + +Fixes: b3d29a823099 ("KVM: arm64: nv: Handle ZCR_EL2 traps") +Signed-off-by: Mark Brown +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260529-kvm-arm64-fix-zcr-len-nv-v2-1-86cad51992bd@kernel.org +[maz: rewrote commit message, tidy up access_zcr_el2()] +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/include/asm/kvm_host.h | 2 +- + arch/arm64/kvm/hyp/include/hyp/switch.h | 16 ++++++++++------ + arch/arm64/kvm/nested.c | 5 +++++ + arch/arm64/kvm/sys_regs.c | 11 +++-------- + 4 files changed, 19 insertions(+), 15 deletions(-) + +--- a/arch/arm64/include/asm/kvm_host.h ++++ b/arch/arm64/include/asm/kvm_host.h +@@ -495,7 +495,6 @@ enum vcpu_sysreg { + ACTLR_EL2, /* Auxiliary Control Register (EL2) */ + CPTR_EL2, /* Architectural Feature Trap Register (EL2) */ + HACR_EL2, /* Hypervisor Auxiliary Control Register */ +- ZCR_EL2, /* SVE Control Register (EL2) */ + TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */ + TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */ + TCR_EL2, /* Translation Control Register (EL2) */ +@@ -527,6 +526,7 @@ enum vcpu_sysreg { + SCTLR2_EL2, /* System Control Register 2 (EL2) */ + MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */ + CNTHCTL_EL2, /* Counter-timer Hypervisor Control register */ ++ ZCR_EL2, /* SVE Control Register (EL2) */ + + /* Any VNCR-capable reg goes after this point */ + MARKER(__VNCR_START__), +--- a/arch/arm64/kvm/hyp/include/hyp/switch.h ++++ b/arch/arm64/kvm/hyp/include/hyp/switch.h +@@ -431,11 +431,13 @@ static inline bool kvm_hyp_handle_mops(s + + static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu) + { ++ u64 zcr_el2 = vcpu_sve_max_vq(vcpu) - 1; ++ + /* + * The vCPU's saved SVE state layout always matches the max VL of the + * vCPU. Start off with the max VL so we can load the SVE state. + */ +- sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2); ++ sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2); + __sve_restore_state(vcpu_sve_pffr(vcpu), + &vcpu->arch.ctxt.fp_regs.fpsr, + true); +@@ -445,8 +447,10 @@ static inline void __hyp_sve_restore_gue + * nested guest, as the guest hypervisor could select a smaller VL. Slap + * that into hardware before wrapping up. + */ +- if (is_nested_ctxt(vcpu)) +- sve_cond_update_zcr_vq(__vcpu_sys_reg(vcpu, ZCR_EL2), SYS_ZCR_EL2); ++ if (is_nested_ctxt(vcpu)) { ++ zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2)); ++ sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2); ++ } + + write_sysreg_el1(__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)), SYS_ZCR); + } +@@ -470,11 +474,11 @@ static inline void fpsimd_lazy_switch_to + return; + + if (vcpu_has_sve(vcpu)) { ++ zcr_el2 = vcpu_sve_max_vq(vcpu) - 1; ++ + /* A guest hypervisor may restrict the effective max VL. */ + if (is_nested_ctxt(vcpu)) +- zcr_el2 = __vcpu_sys_reg(vcpu, ZCR_EL2); +- else +- zcr_el2 = vcpu_sve_max_vq(vcpu) - 1; ++ zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2)); + + write_sysreg_el2(zcr_el2, SYS_ZCR); + +--- a/arch/arm64/kvm/nested.c ++++ b/arch/arm64/kvm/nested.c +@@ -1825,6 +1825,11 @@ int kvm_init_nv_sysregs(struct kvm_vcpu + resx.res1 = VNCR_EL2_RES1; + set_sysreg_masks(kvm, VNCR_EL2, resx); + ++ /* ZCR_EL2 - bits 8:4 are RAZ/WI so treat them as RES0 */ ++ resx.res0 = ZCR_ELx_RES0 | GENMASK_ULL(8, 4); ++ resx.res1 = ZCR_ELx_RES1; ++ set_sysreg_masks(kvm, ZCR_EL2, resx); ++ + out: + for (enum vcpu_sysreg sr = __SANITISED_REG_START__; sr < NR_SYS_REGS; sr++) + __vcpu_rmw_sys_reg(vcpu, sr, |=, 0); +--- a/arch/arm64/kvm/sys_regs.c ++++ b/arch/arm64/kvm/sys_regs.c +@@ -2764,21 +2764,16 @@ static bool access_zcr_el2(struct kvm_vc + struct sys_reg_params *p, + const struct sys_reg_desc *r) + { +- unsigned int vq; +- + if (guest_hyp_sve_traps_enabled(vcpu)) { + kvm_inject_nested_sve_trap(vcpu); + return false; + } + +- if (!p->is_write) { ++ if (!p->is_write) + p->regval = __vcpu_sys_reg(vcpu, ZCR_EL2); +- return true; +- } ++ else ++ __vcpu_assign_sys_reg(vcpu, ZCR_EL2, p->regval); + +- vq = SYS_FIELD_GET(ZCR_ELx, LEN, p->regval) + 1; +- vq = min(vq, vcpu_sve_max_vq(vcpu)); +- __vcpu_assign_sys_reg(vcpu, ZCR_EL2, vq - 1); + return true; + } + diff --git a/queue-7.0/kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch b/queue-7.0/kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch new file mode 100644 index 0000000000..0f3cb16563 --- /dev/null +++ b/queue-7.0/kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch @@ -0,0 +1,46 @@ +From 1750ad1388e03fb27068cd1f22c9c8b4590fe936 Mon Sep 17 00:00:00 2001 +From: Qiang Ma +Date: Tue, 26 May 2026 15:46:40 +0800 +Subject: KVM: arm64: PMU: Preserve AArch32 counter low bits + +From: Qiang Ma + +commit 1750ad1388e03fb27068cd1f22c9c8b4590fe936 upstream. + +AArch32 writes to PMU event counters cannot update the top 32 bits, +even when PMUv3p5 makes the counters 64-bit. KVM therefore needs to +preserve the existing high half and only update the low half written by +the guest, unless the caller explicitly forces a full reset through +PMCR.P. + +The current code masks @val down to the old high half before taking +lower_32_bits(val), which means the low half is always zero. As a +result, AArch32 writes to event counters discard the guest-provided low +32 bits instead of storing them. + +Build the new value from the old high 32 bits and the low 32 bits of +the value supplied by the guest. + +Fixes: 26d2d0594d70 ("KVM: arm64: PMU: Do not let AArch32 change the counters' top 32 bits") +Signed-off-by: Qiang Ma +Signed-off-by: Marc Zyngier +Link: https://patch.msgid.link/20260526074640.791991-1-maqianga@uniontech.com +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kvm/pmu-emul.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm64/kvm/pmu-emul.c ++++ b/arch/arm64/kvm/pmu-emul.c +@@ -174,8 +174,8 @@ static void kvm_pmu_set_pmc_value(struct + * action is to use PMCR.P, which will reset them to + * 0 (the only use of the 'force' parameter). + */ +- val = __vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32); +- val |= lower_32_bits(val); ++ val = (__vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32)) | ++ lower_32_bits(val); + } + + __vcpu_assign_sys_reg(vcpu, reg, val); diff --git a/queue-7.0/kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch b/queue-7.0/kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch new file mode 100644 index 0000000000..3b58ef2e18 --- /dev/null +++ b/queue-7.0/kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch @@ -0,0 +1,66 @@ +From 121d88de56bc5c0ba0ce2f6381af67f948a7e7c1 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 1 May 2026 13:22:34 -0700 +Subject: KVM: SEV: Check PSC request indices against the actual size of the buffer + +From: Sean Christopherson + +commit 121d88de56bc5c0ba0ce2f6381af67f948a7e7c1 upstream. + +When processing Page State Change (PSC) requests, validate the PSC buffer +against the effective size of the scratch area, which could be less than +the maximum size if the guest provided a pointer that isn't exactly at the +start of the GHCB shared buffer. + +Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT") +Cc: stable@vger.kernel.org +Reviewed-by: Tom Lendacky +Reviewed-by: Michael Roth +Signed-off-by: Sean Christopherson +Message-ID: <20260501202250.2115252-10-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/sev.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -3857,7 +3857,7 @@ static int snp_begin_psc(struct vcpu_svm + struct kvm_vcpu *vcpu = &svm->vcpu; + struct psc_hdr *hdr = &psc->hdr; + struct psc_entry entry_start; +- u16 idx, idx_start, idx_end; ++ u16 idx, idx_start, idx_end, max_nr_entries; + int npages; + bool huge; + u64 gfn; +@@ -3867,6 +3867,19 @@ static int snp_begin_psc(struct vcpu_svm + return 1; + } + ++ /* ++ * GHCB v2 requires the scratch area to reside within the GHCB itself, ++ * and PSC requests are only supported for GHCB v2+. Thus it should be ++ * impossible to exceed the max PSC entry count (which is derived from ++ * the size of the shared GHCB buffer). ++ */ ++ max_nr_entries = (sev_es->ghcb_sa_len - sizeof(struct psc_hdr)) / ++ sizeof(struct psc_entry); ++ if (WARN_ON_ONCE(max_nr_entries > VMGEXIT_PSC_MAX_COUNT)) { ++ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC); ++ return 1; ++ } ++ + next_range: + /* There should be no other PSCs in-flight at this point. */ + if (WARN_ON_ONCE(svm->sev_es.psc_inflight)) { +@@ -3882,7 +3895,7 @@ next_range: + idx_start = hdr->cur_entry; + idx_end = hdr->end_entry; + +- if (idx_end >= VMGEXIT_PSC_MAX_COUNT) { ++ if (idx_end >= max_nr_entries) { + snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR); + return 1; + } diff --git a/queue-7.0/kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch b/queue-7.0/kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch new file mode 100644 index 0000000000..1fd0a74eac --- /dev/null +++ b/queue-7.0/kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch @@ -0,0 +1,101 @@ +From 5867d7e202e09f037cefe77f7af4413c7c0fa088 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 1 May 2026 13:22:31 -0700 +Subject: KVM: SEV: Compute the correct max length of the in-GHCB scratch area + +From: Sean Christopherson + +commit 5867d7e202e09f037cefe77f7af4413c7c0fa088 upstream. + +When setting the length of the GHCB scratch area, and the area is in the +GHCB shared buffer, set the effective length of the scratch area to the max +possible size given the start of the guest-provided pointer, and the end of +the shared buffer. + +The code was "fine" when first introduced, as KVM doesn't consult the +length of the buffer when emulating MMIO, because the passed in @len always +specifies the *max* size required. But for PSC requests, the incoming @len +is just the minimum length (to process the header), and KVM needs to know +the full size of the scratch area to avoid buffer overflows (spoiler alert). + +Opportunistically rename @len => @min_len to better reflect its role. + +Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT") +Cc: stable@vger.kernel.org +Reviewed-by: Tom Lendacky +Reviewed-by: Michael Roth +Signed-off-by: Sean Christopherson +Message-ID: <20260501202250.2115252-7-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/sev.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -3617,7 +3617,7 @@ int pre_sev_run(struct vcpu_svm *svm, in + } + + #define GHCB_SCRATCH_AREA_LIMIT (16ULL * PAGE_SIZE) +-static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) ++static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 min_len) + { + struct vmcb_control_area *control = &svm->vmcb->control; + u64 ghcb_scratch_beg, ghcb_scratch_end; +@@ -3633,10 +3633,10 @@ static int setup_vmgexit_scratch(struct + goto e_scratch; + } + +- scratch_gpa_end = scratch_gpa_beg + len; ++ scratch_gpa_end = scratch_gpa_beg + min_len; + if (scratch_gpa_end < scratch_gpa_beg) { + pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n", +- len, scratch_gpa_beg); ++ min_len, scratch_gpa_beg); + goto e_scratch; + } + +@@ -3660,6 +3660,8 @@ static int setup_vmgexit_scratch(struct + + scratch_va = (void *)svm->sev_es.ghcb; + scratch_va += (scratch_gpa_beg - control->ghcb_gpa); ++ ++ svm->sev_es.ghcb_sa_len = ghcb_scratch_end - scratch_gpa_beg; + } else { + /* GHCB v2 requires the scratch area to be within the GHCB. */ + if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2) +@@ -3669,16 +3671,16 @@ static int setup_vmgexit_scratch(struct + * The guest memory must be read into a kernel buffer, so + * limit the size + */ +- if (len > GHCB_SCRATCH_AREA_LIMIT) { ++ if (min_len > GHCB_SCRATCH_AREA_LIMIT) { + pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n", +- len, GHCB_SCRATCH_AREA_LIMIT); ++ min_len, GHCB_SCRATCH_AREA_LIMIT); + goto e_scratch; + } +- scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT); ++ scratch_va = kvzalloc(min_len, GFP_KERNEL_ACCOUNT); + if (!scratch_va) + return -ENOMEM; + +- if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) { ++ if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, min_len)) { + /* Unable to copy scratch area from guest */ + pr_err("vmgexit: kvm_read_guest for scratch area failed\n"); + +@@ -3694,11 +3696,10 @@ static int setup_vmgexit_scratch(struct + */ + svm->sev_es.ghcb_sa_sync = sync; + svm->sev_es.ghcb_sa_free = true; ++ svm->sev_es.ghcb_sa_len = min_len; + } + + svm->sev_es.ghcb_sa = scratch_va; +- svm->sev_es.ghcb_sa_len = len; +- + return 0; + + e_scratch: diff --git a/queue-7.0/kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch b/queue-7.0/kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch new file mode 100644 index 0000000000..a2732fec42 --- /dev/null +++ b/queue-7.0/kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch @@ -0,0 +1,70 @@ +From ebe4b2dc9cfbfb2d8f665667c4d08f4c6c9bec05 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 1 May 2026 13:22:33 -0700 +Subject: KVM: SEV: Don't explicitly pass PSC buffer to snp_begin_psc() + +From: Sean Christopherson + +commit ebe4b2dc9cfbfb2d8f665667c4d08f4c6c9bec05 upstream. + +Stop explicitly passing the PSC buffer to snp_begin_psc(): it *must* +be the scratch area. This will allow fixing a variety of bugs without +further complicating the code. + +No functional change intended. + +Cc: stable@vger.kernel.org +Reviewed-by: Tom Lendacky +Reviewed-by: Michael Roth +Signed-off-by: Sean Christopherson +Message-ID: <20260501202250.2115252-9-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/sev.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -3796,7 +3796,7 @@ struct psc_buffer { + struct psc_entry entries[]; + } __packed; + +-static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc); ++static int snp_begin_psc(struct vcpu_svm *svm); + + static void snp_complete_psc(struct vcpu_svm *svm, u64 psc_ret) + { +@@ -3838,7 +3838,6 @@ static void __snp_complete_one_psc(struc + static int snp_complete_one_psc(struct kvm_vcpu *vcpu) + { + struct vcpu_svm *svm = to_svm(vcpu); +- struct psc_buffer *psc = svm->sev_es.ghcb_sa; + + if (vcpu->run->hypercall.ret) { + snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC); +@@ -3848,11 +3847,13 @@ static int snp_complete_one_psc(struct k + __snp_complete_one_psc(svm); + + /* Handle the next range (if any). */ +- return snp_begin_psc(svm, psc); ++ return snp_begin_psc(svm); + } + +-static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc) ++static int snp_begin_psc(struct vcpu_svm *svm) + { ++ struct vcpu_sev_es_state *sev_es = &svm->sev_es; ++ struct psc_buffer *psc = sev_es->ghcb_sa; + struct psc_entry *entries = psc->entries; + struct kvm_vcpu *vcpu = &svm->vcpu; + struct psc_hdr *hdr = &psc->hdr; +@@ -4540,7 +4541,7 @@ int sev_handle_vmgexit(struct kvm_vcpu * + if (ret) + break; + +- ret = snp_begin_psc(svm, svm->sev_es.ghcb_sa); ++ ret = snp_begin_psc(svm); + break; + case SVM_VMGEXIT_AP_CREATION: + ret = sev_snp_ap_creation(svm); diff --git a/queue-7.0/kvm-sev-ignore-port-i-o-requests-of-length-0.patch b/queue-7.0/kvm-sev-ignore-port-i-o-requests-of-length-0.patch new file mode 100644 index 0000000000..4414647964 --- /dev/null +++ b/queue-7.0/kvm-sev-ignore-port-i-o-requests-of-length-0.patch @@ -0,0 +1,49 @@ +From 3988bd2723de407ae90fa7a6f6029b4e60238c58 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 1 May 2026 13:22:29 -0700 +Subject: KVM: SEV: Ignore Port I/O requests of length '0' + +From: Sean Christopherson + +commit 3988bd2723de407ae90fa7a6f6029b4e60238c58 upstream. + +Explicitly ignore Port I/O requests of length '0' (or count '0'), so that +setting up the software scratch area (and other code) doesn't have to +worry about underflowing the length, and to allow for WARNing on trying +to configure the scratch area with len==0. + +Fixes: 291bd20d5d88 ("KVM: SVM: Add initial support for a VMGEXIT VMEXIT") +Cc: stable@vger.kernel.org +Reviewed-by: Tom Lendacky +Signed-off-by: Sean Christopherson +Message-ID: <20260501202250.2115252-5-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/sev.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -4545,6 +4545,11 @@ int sev_handle_vmgexit(struct kvm_vcpu * + control->exit_info_1, control->exit_info_2); + ret = -EINVAL; + break; ++ case SVM_EXIT_IOIO: ++ if (!((control->exit_info_1 & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT)) ++ return 1; ++ ++ fallthrough; + default: + ret = svm_invoke_exit_handler(vcpu, control->exit_code); + } +@@ -4565,6 +4570,9 @@ int sev_es_string_io(struct vcpu_svm *sv + if (unlikely(check_mul_overflow(count, size, &bytes))) + return -EINVAL; + ++ if (!bytes) ++ return 1; ++ + r = setup_vmgexit_scratch(svm, in, bytes); + if (r) + return r; diff --git a/queue-7.0/kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch b/queue-7.0/kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch new file mode 100644 index 0000000000..5934b481fa --- /dev/null +++ b/queue-7.0/kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch @@ -0,0 +1,108 @@ +From db3f2195d29344a3cf1e9dd9ab7f21ced7308cf7 Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Fri, 1 May 2026 13:22:26 -0700 +Subject: KVM: SEV: Require in-GHCB scratch area if GHCB v2+ is in use + +From: Michael Roth + +commit db3f2195d29344a3cf1e9dd9ab7f21ced7308cf7 upstream. + +As per the GHCB spec, when using GHCB v2+ require the software scratch area +to reside in the GHCB's shared buffer. Note, things like Page State Change +(PSC) requests _rely_ on this behavior, as the guest can't provide a length +when making the request, i.e. the size of the guest payload is bounded by +the size of the shared buffer. + +Failure to force usage of the GHCB, and a slew of other flaws, lets a +malicious SNP guest corrupt host kernel heap memory, and leak host heap +layout information. + +setup_vmgexit_scratch() allocates a buffer via kvzalloc(exit_info_2), +where exit_info_2 is guest-controlled. With exit_info_2=24, this yields +a 24-byte allocation in kmalloc-cg-32 (32-byte slab objects). The buffer +holds an 8-byte psc_hdr followed by 8-byte psc_entry structs, so only +entries[0] and entries[1] are in-bounds. + +snp_begin_psc() validates end_entry against VMGEXIT_PSC_MAX_COUNT (253) +but NOT against the actual buffer size: + + idx_end = hdr->end_entry; + + if (idx_end >= VMGEXIT_PSC_MAX_COUNT) { // checks 253, not buffer + snp_complete_psc(svm, ...); + return 1; + } + + for (idx = idx_start; idx <= idx_end; idx++) { + entry_start = entries[idx]; // OOB when idx >= 2 + +The guest sets end_entry=10+, causing the host to iterate entries[2+] +which are OOB into adjacent slab objects. For each OOB entry: + + - The host reads 8 bytes (OOB READ / info leak oracle) + - If the data passes PSC validation, __snp_complete_one_psc() writes + cur_page = 1 or 512 into the entry (OOB WRITE, sev.c:3806) + - If validation fails, the error response reveals whether adjacent + memory is zero vs non-zero (information disclosure to guest) + +The guest controls allocation size (exit_info_2), entry range +(cur_entry/end_entry), and can fire unlimited VMGEXITs to repeatedly +hit different slab positions. + +By exploiting the variety of bugs, a malicious SEV-SNP guest can: + - OOB read adjacent kmalloc-cg-32 objects (heap layout disclosure) + - OOB write cur_page bits into adjacent objects (heap corruption) + - Trigger use-after-free conditions across VMGEXITs + +E.g. with KASAN enabled, a single insmod of the PoC guest module +produces 73 KASAN reports: + + BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x126/0x890 + Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199 + + BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x468/0x890 + Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199 + + The buggy address belongs to the object at ffff888XXXXXXXXX + which belongs to the cache kmalloc-cg-32 of size 32 + The buggy address is located N bytes to the right of + allocated 32-byte region [ffff888XXXXXXXXX, ffff888XXXXXXXXX) + + Breakdown: + 62 slab-out-of-bounds (reads + writes past allocation) + 7 slab-use-after-free + 4 use-after-free + +All credit to Stan for the wonderful description and reproducer! + +Reported-by: Stan Shaw +Cc: Michael Roth +Cc: Tom Lendacky +Cc: Peter Gonda +Cc: Jacky Li +Fixes: 4af663c2f64a ("KVM: SEV: Allow per-guest configuration of GHCB protocol version") +Cc: stable@vger.kernel.org +Signed-off-by: Michael Roth +[sean: write changelog] +Reviewed-by: Tom Lendacky +Signed-off-by: Sean Christopherson +Message-ID: <20260501202250.2115252-2-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/sev.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -3658,6 +3658,10 @@ static int setup_vmgexit_scratch(struct + scratch_va = (void *)svm->sev_es.ghcb; + scratch_va += (scratch_gpa_beg - control->ghcb_gpa); + } else { ++ /* GHCB v2 requires the scratch area to be within the GHCB. */ ++ if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2) ++ goto e_scratch; ++ + /* + * The guest memory must be read into a kernel buffer, so + * limit the size diff --git a/queue-7.0/kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch b/queue-7.0/kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch new file mode 100644 index 0000000000..77cac5f59e --- /dev/null +++ b/queue-7.0/kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch @@ -0,0 +1,71 @@ +From c8cc238093ca6c99267032f6cfe78f59389f3157 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 1 May 2026 13:22:35 -0700 +Subject: KVM: SEV: Use READ_ONCE() when reading entries/indices from PSC buffer + +From: Sean Christopherson + +commit c8cc238093ca6c99267032f6cfe78f59389f3157 upstream. + +Use READ_ONCE() when reading entries/indices from the guest-accessible +Page State Change buffer to defend against TOCTOU bugs. + +Don't bother with READ_ONCE()/WRITE_ONCE() for cases where KVM is writing +(and not consuming the result!), as the guest isn't supposed to touch the +buffer while it's being processed. I.e. using READ_ONCE() is all about +protecting against misbehaving guests. + +Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT") +Cc: stable@vger.kernel.org +Reviewed-by: Tom Lendacky +Signed-off-by: Sean Christopherson +Message-ID: <20260501202250.2115252-11-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/sev.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -3827,9 +3827,9 @@ static void __snp_complete_one_psc(struc + */ + for (idx = svm->sev_es.psc_idx; svm->sev_es.psc_inflight; + svm->sev_es.psc_inflight--, idx++) { +- struct psc_entry *entry = &entries[idx]; ++ struct psc_entry entry = READ_ONCE(entries[idx]); + +- entry->cur_page = entry->pagesize ? 512 : 1; ++ entries[idx].cur_page = entry.pagesize ? 512 : 1; + } + + hdr->cur_entry = idx; +@@ -3892,8 +3892,8 @@ next_range: + * validation, so take care to only use validated copies of values used + * for things like array indexing. + */ +- idx_start = hdr->cur_entry; +- idx_end = hdr->end_entry; ++ idx_start = READ_ONCE(hdr->cur_entry); ++ idx_end = READ_ONCE(hdr->end_entry); + + if (idx_end >= max_nr_entries) { + snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR); +@@ -3902,7 +3902,7 @@ next_range: + + /* Find the start of the next range which needs processing. */ + for (idx = idx_start; idx <= idx_end; idx++, hdr->cur_entry++) { +- entry_start = entries[idx]; ++ entry_start = READ_ONCE(entries[idx]); + + gfn = entry_start.gfn; + huge = entry_start.pagesize; +@@ -3946,7 +3946,7 @@ next_range: + * KVM_HC_MAP_GPA_RANGE exit. + */ + while (++idx <= idx_end) { +- struct psc_entry entry = entries[idx]; ++ struct psc_entry entry = READ_ONCE(entries[idx]); + + if (entry.operation != entry_start.operation || + entry.gfn != entry_start.gfn + npages || diff --git a/queue-7.0/kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch b/queue-7.0/kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch new file mode 100644 index 0000000000..f8f107c1dc --- /dev/null +++ b/queue-7.0/kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch @@ -0,0 +1,42 @@ +From 2be54670bdc017004c4a4b8bddb6ff02ebe7dbe2 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 1 May 2026 13:22:30 -0700 +Subject: KVM: SEV: Use the size of the PSC header as the minimum size for PSC requests + +From: Sean Christopherson + +commit 2be54670bdc017004c4a4b8bddb6ff02ebe7dbe2 upstream. + +When handling a Page State Change (PSC) #VMGEXIT use the size of the PSC +header as the minimum size for the scratch area. Per the GHCB spec, PSC +requests do NOT provide the length, i.e. using control->exit_info_2 for the +length is completely made up behavior. The existing code "works", e.g. +even though Linux-as-a-guest always passes '0', because KVM doesn't do +anything with the length when the request is in the GHCB's shared buffer. + +Use the header as the min length. Once the header is retrieved, KVM can +use the specified indices to compute the full size of the request. + +Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT") +Cc: stable@vger.kernel.org +Reviewed-by: Tom Lendacky +Reviewed-by: Michael Roth +Signed-off-by: Sean Christopherson +Message-ID: <20260501202250.2115252-6-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/sev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -4519,7 +4519,7 @@ int sev_handle_vmgexit(struct kvm_vcpu * + vcpu->run->system_event.data[0] = control->ghcb_gpa; + break; + case SVM_VMGEXIT_PSC: +- ret = setup_vmgexit_scratch(svm, true, control->exit_info_2); ++ ret = setup_vmgexit_scratch(svm, true, sizeof(struct psc_hdr)); + if (ret) + break; + diff --git a/queue-7.0/kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch b/queue-7.0/kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch new file mode 100644 index 0000000000..6b1dece874 --- /dev/null +++ b/queue-7.0/kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch @@ -0,0 +1,37 @@ +From f185e05dce6f170f83c4ba602e969b1c3c7a22e6 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 1 May 2026 13:22:32 -0700 +Subject: KVM: SEV: WARN if KVM attempts to setup scratch area with min_len==0 + +From: Sean Christopherson + +commit f185e05dce6f170f83c4ba602e969b1c3c7a22e6 upstream. + +Now that all paths in KVM properly validate the length needed for the +scratch area, and are guaranteed to pass in a non-zero length, WARN if KVM +attempts to configured the scratch area with min_len==0 to guard against +future bugs. + +Cc: stable@vger.kernel.org +Reviewed-by: Tom Lendacky +Reviewed-by: Michael Roth +Signed-off-by: Sean Christopherson +Message-ID: <20260501202250.2115252-8-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/sev.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -3624,6 +3624,9 @@ static int setup_vmgexit_scratch(struct + u64 scratch_gpa_beg, scratch_gpa_end; + void *scratch_va; + ++ if (WARN_ON_ONCE(!min_len)) ++ goto e_scratch; ++ + scratch_gpa_beg = svm->sev_es.sw_scratch; + if (!scratch_gpa_beg) { + pr_err("vmgexit: scratch gpa not provided\n"); diff --git a/queue-7.0/kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch b/queue-7.0/kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch new file mode 100644 index 0000000000..0f0251c0ba --- /dev/null +++ b/queue-7.0/kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch @@ -0,0 +1,83 @@ +From a9e18aa3263f356edae305e29830e5fe63d8597a Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Fri, 15 May 2026 10:15:36 -0700 +Subject: KVM: SVM: Flush the current TLB when transitioning from xAVIC => x2AVIC + +From: Sean Christopherson + +commit a9e18aa3263f356edae305e29830e5fe63d8597a upstream. + +Flush the current TLB when xAVIC *or* x2AVIC is activated, as KVM is +(apparently) responsible for purging TLB entries when transitioning from +xAVIC to x2AVIC. The APM says a whole lot of nothing about TLB flushing +with respect to (x2)AVIC, but empirical data strongly suggests hardware +also does a whole lot of nothing. + +Failure to flush the TLB when enabling x2AVIC can lead to guest accesses +to the APIC base address getting incorrectly redirected to the virtual +APIC page. The flaw most visibly manifests as failures in KVM-Unit-Test's +verify_disabled_apic_mmio() testcase when x2APIC is enabled (though for +reasons unknown, the test only reliably fails with EFI builds). + +Fixes: 0ccf3e7cb95a ("KVM: SVM: Flush the "current" TLB when activating AVIC") +Fixes: 4d1d7942e36a ("KVM: SVM: Introduce logic to (de)activate x2AVIC mode") +Cc: stable@vger.kernel.org +Cc: Naveen N Rao (AMD) +Link: https://patch.msgid.link/20260515171536.1841645-1-seanjc@google.com +Signed-off-by: Sean Christopherson +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/avic.c | 35 +++++++++++++++++++++++++++++------ + 1 file changed, 29 insertions(+), 6 deletions(-) + +--- a/arch/x86/kvm/svm/avic.c ++++ b/arch/x86/kvm/svm/avic.c +@@ -196,6 +196,35 @@ static void avic_activate_vmcb(struct vc + svm_clr_intercept(svm, INTERCEPT_CR8_WRITE); + + /* ++ * Flush the TLB when enabling (x2)AVIC and when transitioning between ++ * xAVIC and x2AVIC, as the CPU may have inserted a TLB entry for the ++ * "wrong" mapping. ++ * ++ * KVM uses a per-VM "scratch" page to back the APIC memslot, because ++ * KVM also uses per-VM page tables *and* maintains the page table (NPT ++ * or shadow page) mappings for said memslot even if one or more vCPUs ++ * have their local APIC hardware-disabled or are in x2APIC mode, i.e. ++ * even if one or more vCPUs' APIC MMIO BAR is effectively disabled. ++ * ++ * If xAVIC is fully enabled, hardware ignores the physical address in ++ * KVM's page tables, i.e. in the leaf SPTE for the APIC memslot, and ++ * instead redirects the access to the AVIC backing page, i.e. to the ++ * vCPU's virtual APIC page. If xAVIC is not enabled (APIC is either ++ * hardware-disabled or in x2APIC mode), then guest accesses will use ++ * the page table mapping verbatim, i.e. will access the per-VM scratch ++ * page, as normal memory. ++ * ++ * In both cases, the CPU is allowed to cache TLB entries for the APIC ++ * base GPA. So, KVM needs to flush the TLB when enabling xAVIC, as ++ * accesses need to be redirected to the virtual APIC page, but the TLB ++ * may contain entries pointing at the scratch page. KVM also needs to ++ * flush the TLB when enabling x2AVIC, as accesses need to go to the ++ * scratch page, but the TLB may contain entries tagged as xAVIC, i.e. ++ * entries pointing to the vCPU's virtual APIC page. ++ */ ++ kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, &svm->vcpu); ++ ++ /* + * Note: KVM supports hybrid-AVIC mode, where KVM emulates x2APIC MSR + * accesses, while interrupt injection to a running vCPU can be + * achieved using AVIC doorbell. KVM disables the APIC access page +@@ -208,12 +237,6 @@ static void avic_activate_vmcb(struct vc + /* Disabling MSR intercept for x2APIC registers */ + avic_set_x2apic_msr_interception(svm, false); + } else { +- /* +- * Flush the TLB, the guest may have inserted a non-APIC +- * mapping into the TLB while AVIC was disabled. +- */ +- kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, &svm->vcpu); +- + /* Enabling MSR intercept for x2APIC registers */ + avic_set_x2apic_msr_interception(svm, true); + } diff --git a/queue-7.0/memfd-deny-writeable-mappings-when-implying-seal_write.patch b/queue-7.0/memfd-deny-writeable-mappings-when-implying-seal_write.patch new file mode 100644 index 0000000000..460eb57280 --- /dev/null +++ b/queue-7.0/memfd-deny-writeable-mappings-when-implying-seal_write.patch @@ -0,0 +1,67 @@ +From 3b041514cb6eae45869b020f743c14d983363222 Mon Sep 17 00:00:00 2001 +From: "Pratyush Yadav (Google)" +Date: Tue, 5 May 2026 15:39:20 +0200 +Subject: memfd: deny writeable mappings when implying SEAL_WRITE + +From: Pratyush Yadav (Google) + +commit 3b041514cb6eae45869b020f743c14d983363222 upstream. + +When SEAL_EXEC is added, SEAL_WRITE is implied to make W^X. But the +implied seal is set after the check that makes sure the memfd can not have +any writable mappings. This means one can use SEAL_EXEC to apply +SEAL_WRITE while having writeable mappings. + +This breaks the contract that SEAL_WRITE provides and can be used by an +attacker to pass a memfd that appears to be write sealed but can still be +modified arbitrarily. + +Fix this by adding the implied seals before the call for +mapping_deny_writable() is done. + +Link: https://lore.kernel.org/20260505133922.797635-1-pratyush@kernel.org +Fixes: c4f75bc8bd6b ("mm/memfd: add write seals when apply SEAL_EXEC to executable memfd") +Signed-off-by: Pratyush Yadav (Google) +Reviewed-by: Pasha Tatashin +Acked-by: Jeff Xu +Cc: Baolin Wang +Cc: Brendan Jackman +Cc: Greg Thelen +Cc: Hugh Dickins +Cc: Kees Cook +Cc: "David Hildenbrand (Arm)" +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/memfd.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/mm/memfd.c ++++ b/mm/memfd.c +@@ -283,6 +283,12 @@ static int memfd_add_seals(struct file * + goto unlock; + } + ++ /* ++ * SEAL_EXEC implies SEAL_WRITE, making W^X from the start. ++ */ ++ if (seals & F_SEAL_EXEC && inode->i_mode & 0111) ++ seals |= F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_FUTURE_WRITE; ++ + if ((seals & F_SEAL_WRITE) && !(*file_seals & F_SEAL_WRITE)) { + error = mapping_deny_writable(file->f_mapping); + if (error) +@@ -295,12 +301,6 @@ static int memfd_add_seals(struct file * + } + } + +- /* +- * SEAL_EXEC implies SEAL_WRITE, making W^X from the start. +- */ +- if (seals & F_SEAL_EXEC && inode->i_mode & 0111) +- seals |= F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_FUTURE_WRITE; +- + *file_seals |= seals; + error = 0; + diff --git a/queue-7.0/mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch b/queue-7.0/mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch new file mode 100644 index 0000000000..774aa3886c --- /dev/null +++ b/queue-7.0/mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch @@ -0,0 +1,90 @@ +From 441f92f7d386b85bad16de49db95a307cba048a2 Mon Sep 17 00:00:00 2001 +From: SeongJae Park +Date: Mon, 18 May 2026 08:25:58 -0700 +Subject: mm/damon/sysfs-schemes: delete tried region in regions_rmdirs() + +From: SeongJae Park + +commit 441f92f7d386b85bad16de49db95a307cba048a2 upstream. + +DAMON sysfs maintains the DAMOS tried region directory objects via a +linked list. When the user requests refresh of the directories, DAMON +sysfs removes all the region directories first, and then generate updated +regions directory on the empty space. The removal function +(damon_sysfs_scheme_regions_rm_dirs()) only puts the kobj objects. +Deletion of the container region object from the linked list is done +inside the kobj release callback function. + +If somehow the callback invocation is delayed, the list will contain +regions list that gonna be freed. If the updated region directories +creation is started in this situation, the list can be corrupted and +use-after-free can happen. + +Because the kobj objects are managed by only DAMON sysfs, the issue cannot +happen in normal situation. But, such delays can be made on kernels that +built with CONFIG_DEBUG_KOBJECT_RELEASE. On the kernel, the issue can +indeed be reproduced like below. + + # damo start --damos_action stat + # cd /sys/kernel/mm/damon/admin/kdamonds/0/ + # for i in {1..10}; do echo update_schemes_tried_regions > state; done + # dmesg | grep underflow + [ 89.296152] refcount_t: underflow; use-after-free. + +Fix the issue by removing the region object from the list when +decrementing the reference count. + +Also update damos_sysfs_populate_region_dir() to add the region object to +the list only after the kobject_init_and_add() is success, so that fail of +kobject_init_and_add() is not leaving the deallocated object on the list. + +The issue was discovered [1] by Sashiko. + +Link: https://lore.kernel.org/20260518152559.93038-1-sj@kernel.org +Link: https://lore.kernel.org/20260513011920.119183-1-sj@kernel.org [1] +Fixes: 9277d0367ba1 ("mm/damon/sysfs-schemes: implement scheme region directory") +Signed-off-by: SeongJae Park +Cc: # 6.2.x +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/damon/sysfs-schemes.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/mm/damon/sysfs-schemes.c ++++ b/mm/damon/sysfs-schemes.c +@@ -88,7 +88,6 @@ static void damon_sysfs_scheme_region_re + struct damon_sysfs_scheme_region *region = container_of(kobj, + struct damon_sysfs_scheme_region, kobj); + +- list_del(®ion->list); + kfree(region); + } + +@@ -164,7 +163,7 @@ static void damon_sysfs_scheme_regions_r + struct damon_sysfs_scheme_region *r, *next; + + list_for_each_entry_safe(r, next, ®ions->regions_list, list) { +- /* release function deletes it from the list */ ++ list_del(&r->list); + kobject_put(&r->kobj); + regions->nr_regions--; + } +@@ -2870,14 +2869,15 @@ void damos_sysfs_populate_region_dir(str + if (!region) + return; + region->sz_filter_passed = sz_filter_passed; +- list_add_tail(®ion->list, &sysfs_regions->regions_list); +- sysfs_regions->nr_regions++; + if (kobject_init_and_add(®ion->kobj, + &damon_sysfs_scheme_region_ktype, + &sysfs_regions->kobj, "%d", + sysfs_regions->nr_regions++)) { + kobject_put(®ion->kobj); ++ return; + } ++ list_add_tail(®ion->list, &sysfs_regions->regions_list); ++ sysfs_regions->nr_regions++; + } + + int damon_sysfs_schemes_clear_regions( diff --git a/queue-7.0/mm-memcontrol-propagate-nmi-slab-stats-to-memcg-vmstats.patch b/queue-7.0/mm-memcontrol-propagate-nmi-slab-stats-to-memcg-vmstats.patch new file mode 100644 index 0000000000..8cb85bf46e --- /dev/null +++ b/queue-7.0/mm-memcontrol-propagate-nmi-slab-stats-to-memcg-vmstats.patch @@ -0,0 +1,57 @@ +From e16f17a9c5af50221184d1ef4be4056bf3c4209e Mon Sep 17 00:00:00 2001 +From: Alexandre Ghiti +Date: Mon, 18 May 2026 10:28:19 +0200 +Subject: mm: memcontrol: propagate NMI slab stats to memcg vmstats + +From: Alexandre Ghiti + +commit e16f17a9c5af50221184d1ef4be4056bf3c4209e upstream. + +flush_nmi_stats() drains per-node NMI slab atomics into the per-node +lruvec_stats, but does not propagate them to the memcg-level vmstats. + +For non NMI case, account_slab_nmi_safe() calls mod_memcg_lruvec_state() +which updates both per-node lruvec_stats and memcg-level vmstats, so +flush_nmi_stats() needs to flush to per-node lruvec_stats as well as +memcg-level vmstats. + +So fix this by flushing to the memcg-level vmstats for NMI too. + +Link: https://lore.kernel.org/20260518082830.599102-1-alex@ghiti.fr +Fixes: 940b01fc8dc1 ("memcg: nmi safe memcg stats for specific archs") +Signed-off-by: Alexandre Ghiti +Acked-by: Shakeel Butt +Acked-by: Johannes Weiner +Reviewed-by: Harry Yoo (Oracle) +Cc: Michal Hocko +Cc: Muchun Song +Cc: Roman Gushchin +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/memcontrol.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4085,6 +4085,9 @@ static void flush_nmi_stats(struct mem_c + lstats->state[index] += slab; + if (plstats) + plstats->state_pending[index] += slab; ++ memcg->vmstats->state[index] += slab; ++ if (parent) ++ parent->vmstats->state_pending[index] += slab; + } + if (atomic_read(&pn->slab_unreclaimable)) { + int slab = atomic_xchg(&pn->slab_unreclaimable, 0); +@@ -4093,6 +4096,9 @@ static void flush_nmi_stats(struct mem_c + lstats->state[index] += slab; + if (plstats) + plstats->state_pending[index] += slab; ++ memcg->vmstats->state[index] += slab; ++ if (parent) ++ parent->vmstats->state_pending[index] += slab; + } + } + } diff --git a/queue-7.0/mm-migrate_device-fix-pgtable-leak-in-migrate_vma_insert_huge_pmd_page.patch b/queue-7.0/mm-migrate_device-fix-pgtable-leak-in-migrate_vma_insert_huge_pmd_page.patch new file mode 100644 index 0000000000..f4246aed4c --- /dev/null +++ b/queue-7.0/mm-migrate_device-fix-pgtable-leak-in-migrate_vma_insert_huge_pmd_page.patch @@ -0,0 +1,55 @@ +From 2c6f81d58741349298f51ff697d988cb42881453 Mon Sep 17 00:00:00 2001 +From: Sunny Patel +Date: Fri, 1 May 2026 17:21:16 +0530 +Subject: mm/migrate_device: fix pgtable leak in migrate_vma_insert_huge_pmd_page + +From: Sunny Patel + +commit 2c6f81d58741349298f51ff697d988cb42881453 upstream. + +When migrate_vma_insert_huge_pmd_page() jumps to unlock_abort due +to a PMD check failure, the pgtable allocated earlier via +pte_alloc_one() is never freed, causing a memory leak. + +Added free_abort label to release the pgtable in error path. + +Link: https://lore.kernel.org/20260501115122.23288-1-nueralspacetech@gmail.com +Fixes: a30b48bf1b24 ("mm/migrate_device: implement THP migration of zone device pages") +Signed-off-by: Sunny Patel +Acked-by: David Hildenbrand (Arm) +Reviewed-by: Huang Ying +Cc: Alistair Popple +Cc: Balbir Singh +Cc: Byungchul Park +Cc: Gregory Price +Cc: Joshua Hahn +Cc: Matthew Brost +Cc: Rakie Kim +Cc: Zi Yan +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/migrate_device.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/mm/migrate_device.c ++++ b/mm/migrate_device.c +@@ -846,7 +846,7 @@ static int migrate_vma_insert_huge_pmd_p + } else { + if (folio_is_zone_device(folio) && + !folio_is_device_coherent(folio)) { +- goto abort; ++ goto free_abort; + } + entry = folio_mk_pmd(folio, vma->vm_page_prot); + if (vma->vm_flags & VM_WRITE) +@@ -899,6 +899,8 @@ static int migrate_vma_insert_huge_pmd_p + + unlock_abort: + spin_unlock(ptl); ++free_abort: ++ pte_free(vma->vm_mm, pgtable); + abort: + for (i = 0; i < HPAGE_PMD_NR; i++) + src[i] &= ~MIGRATE_PFN_MIGRATE; diff --git a/queue-7.0/mm-rmap-initialize-nr_pages-to-1-at-loop-start-in-try_to_unmap_one.patch b/queue-7.0/mm-rmap-initialize-nr_pages-to-1-at-loop-start-in-try_to_unmap_one.patch new file mode 100644 index 0000000000..5b9bd397ac --- /dev/null +++ b/queue-7.0/mm-rmap-initialize-nr_pages-to-1-at-loop-start-in-try_to_unmap_one.patch @@ -0,0 +1,72 @@ +From 3f8968e9cbf95d5d87d32218906cab0b9b9eddbe Mon Sep 17 00:00:00 2001 +From: Dev Jain +Date: Mon, 18 May 2026 12:06:56 +0530 +Subject: mm/rmap: initialize nr_pages to 1 at loop start in try_to_unmap_one + +From: Dev Jain + +commit 3f8968e9cbf95d5d87d32218906cab0b9b9eddbe upstream. + +Initialize nr_pages to 1 at the start of each loop iteration, like +folio_referenced_one() does. + +Without this, nr_pages computed by a previous folio_unmap_pte_batch() call +can be reused on a later iteration that does not run +folio_unmap_pte_batch() again. + +mmap a 64K large folio with MAP_ANONYMOUS | MAP_DROPPABLE, then call +madvise(MADV_FREE), then make the last page device-exclusive via +HMM_DMIRROR_EXCLUSIVE. + +Trigger node reclaim through sysfs. Now, in try_to_unmap_one(), we will +first clear the first 15 out of 16 entries mapping the lazyfree folio. +This will set nr_pages to 15. In the next pvmw walk, this nr_pages gets +reused on a device-exclusive pte, thus potentially corrupting folio +refcount/mapcount. + +At the moment, I have a userspace program which can make the kernel spit +out a trace, but the blow up is in folio_referenced_one(), because there +are existing bugs in the interaction between device-private and rmap +(which too I am investigating). I did a one liner kernel change to avoid +going into folio_referenced_one(), and the kernel blows up at +folio_remove_rmap_ptes in try_to_unmap_one which is what I wanted. + +Note that the bug is there not since file folio batching but lazyfree +folio batching, since device-exclusive only works for anonymous folios. + +Userspace visible effect is simply kernel crashing somewhere due to +refcount/mapcount corruption. + +Link: https://lore.kernel.org/20260518063656.3721056-1-dev.jain@arm.com +Fixes: 354dffd29575 ("mm: support batched unmap for lazyfree large folios during reclamation") +Signed-off-by: Dev Jain +Acked-by: Barry Song +Acked-by: David Hildenbrand (Arm) +Reviewed-by: Lorenzo Stoakes +Cc: Anshuman Khandual +Cc: Barry Song +Cc: Dev Jain +Cc: Harry Yoo +Cc: Jann Horn +Cc: Liam R. Howlett +Cc: Rik van Riel +Cc: Ryan Roberts +Cc: Vlastimil Babka +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/rmap.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -2024,6 +2024,8 @@ static bool try_to_unmap_one(struct foli + mmu_notifier_invalidate_range_start(&range); + + while (page_vma_mapped_walk(&pvmw)) { ++ nr_pages = 1; ++ + /* + * If the folio is in an mlock()d vma, we must not swap it out. + */ diff --git a/queue-7.0/mm-vmalloc-do-not-trigger-bug-on-bh-disabled-context.patch b/queue-7.0/mm-vmalloc-do-not-trigger-bug-on-bh-disabled-context.patch new file mode 100644 index 0000000000..f4748b9934 --- /dev/null +++ b/queue-7.0/mm-vmalloc-do-not-trigger-bug-on-bh-disabled-context.patch @@ -0,0 +1,57 @@ +From 04aa71da5f35aacdc9ae9cb5150947daa624f641 Mon Sep 17 00:00:00 2001 +From: "Uladzislau Rezki (Sony)" +Date: Fri, 15 May 2026 17:30:09 +0200 +Subject: mm/vmalloc: do not trigger BUG() on BH disabled context + +From: Uladzislau Rezki (Sony) + +commit 04aa71da5f35aacdc9ae9cb5150947daa624f641 upstream. + +__get_vm_area_node() currently triggers a BUG() if in_interrupt() returns +true. However, in_interrupt() also reports true when BH are disabled. + +The bridge code can call rhashtable_lookup_insert_fast() with bottom +halves disabled: + +__vlan_add() + -> br_fdb_add_local() + spin_lock_bh(&br->hash_lock); <-- Disable BH + -> fdb_add_local() + -> fdb_create() + -> rhashtable_lookup_insert_fast() + -> kvmalloc() + -> vmalloc() + -> __get_vm_area_node() + -> BUG_ON(in_interrupt()) + spin_unlock_bh(&br->hash_lock) + +this triggers the BUG() despite the caller not being in NMI or +hard IRQ context. + +Replace the in_interrupt() check with in_nmi() || in_hardirq(). + +Link: https://lore.kernel.org/20260515153009.2296191-1-urezki@gmail.com +Fixes: c6307674ed82 ("mm: kvmalloc: add non-blocking support for vmalloc") +Signed-off-by: Uladzislau Rezki (Sony) +Cc: Ido Schimmel +Reported-by: syzbot+8b12fc6e0fb139765b58@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/69ff8c7c.050a0220.1036b8.000b.GAE@google.com/ +Reviewed-by: Baoquan He +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/vmalloc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -3209,7 +3209,7 @@ struct vm_struct *__get_vm_area_node(uns + struct vm_struct *area; + unsigned long requested_size = size; + +- BUG_ON(in_interrupt()); ++ BUG_ON(in_nmi() || in_hardirq()); + size = ALIGN(size, 1ul << shift); + if (unlikely(!size)) + return NULL; diff --git a/queue-7.0/parport-fix-race-between-port-and-client-registration.patch b/queue-7.0/parport-fix-race-between-port-and-client-registration.patch new file mode 100644 index 0000000000..cf3c6cad64 --- /dev/null +++ b/queue-7.0/parport-fix-race-between-port-and-client-registration.patch @@ -0,0 +1,109 @@ +From ef15ccbb3e8640a723c42ad90eaf81d66ae02017 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Tue, 5 May 2026 20:45:12 +0200 +Subject: parport: Fix race between port and client registration + +From: Ben Hutchings + +commit ef15ccbb3e8640a723c42ad90eaf81d66ae02017 upstream. + +The parport subsystem registers port devices before they are fully +initialised, resulting in a race condition where client drivers such +as lp can attach to ports that are not completely initialised or even +being torn down. + +When the port and client drivers are built as modules and loaded +around the same time during boot, this occasionally results in a +crash. I was able to make this happen reliably in a VM with a +PC-style parallel port by patching parport_pc to fail probing: + +> --- a/drivers/parport/parport_pc.c +> +++ b/drivers/parport/parport_pc.c +> @@ -2069,7 +2069,7 @@ static struct parport *__parport_pc_probe_port(unsigned long int base, +> if (!p) +> goto out3; +> +> - base_res = request_region(base, 3, p->name); +> + base_res = NULL; +> if (!base_res) +> goto out4; +> + +and then running: + + while true; do + modprobe lp & modprobe parport_pc + wait + rmmod lp parport_pc + done + +for a few seconds. + +In the long term I think port registration should be changed to put +the call to device_add() inside parport_announce_port(), but since the +latter currently cannot fail this will require changing all port +drivers. + +For now, add a flag to indicate whether a port has been "announced" +and only try to attach client drivers to ports when the flag is set. + +Fixes: 6fa45a226897 ("parport: add device-model to parport subsystem") +Closes: https://bugs.debian.org/1130365 +Closes: https://lore.kernel.org/all/6ba903ad-9897-42bb-8c2d-337385cc3746@molgen.mpg.de/ +Cc: stable +Signed-off-by: Ben Hutchings +Acked-by: Sudip Mukherjee +Link: https://patch.msgid.link/afo6uBv68GDevbMD@decadent.org.uk +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/parport/share.c | 11 +++++++++-- + include/linux/parport.h | 1 + + 2 files changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/parport/share.c ++++ b/drivers/parport/share.c +@@ -214,10 +214,14 @@ static void get_lowlevel_driver(void) + static int port_check(struct device *dev, void *dev_drv) + { + struct parport_driver *drv = dev_drv; ++ struct parport *port; + + /* only send ports, do not send other devices connected to bus */ +- if (is_parport(dev)) +- drv->match_port(to_parport_dev(dev)); ++ if (is_parport(dev)) { ++ port = to_parport_dev(dev); ++ if (test_bit(PARPORT_ANNOUNCED, &port->devflags)) ++ drv->match_port(port); ++ } + return 0; + } + +@@ -532,6 +536,7 @@ void parport_announce_port(struct parpor + if (slave) + attach_driver_chain(slave); + } ++ set_bit(PARPORT_ANNOUNCED, &port->devflags); + mutex_unlock(®istration_lock); + } + EXPORT_SYMBOL(parport_announce_port); +@@ -561,6 +566,8 @@ void parport_remove_port(struct parport + + mutex_lock(®istration_lock); + ++ clear_bit(PARPORT_ANNOUNCED, &port->devflags); ++ + /* Spread the word. */ + detach_driver_chain(port); + +--- a/include/linux/parport.h ++++ b/include/linux/parport.h +@@ -240,6 +240,7 @@ struct parport { + + unsigned long devflags; + #define PARPORT_DEVPROC_REGISTERED 0 ++#define PARPORT_ANNOUNCED 1 + struct pardevice *proc_device; /* Currently register proc device */ + + struct list_head full_list; diff --git a/queue-7.0/rust_binder-avoid-calling-pending_oneway_finished-on-tf_update_txn.patch b/queue-7.0/rust_binder-avoid-calling-pending_oneway_finished-on-tf_update_txn.patch new file mode 100644 index 0000000000..ece5f6ac20 --- /dev/null +++ b/queue-7.0/rust_binder-avoid-calling-pending_oneway_finished-on-tf_update_txn.patch @@ -0,0 +1,86 @@ +From 4c19719eb8b8df08c5bec7c499f73ddaea6f09fc Mon Sep 17 00:00:00 2001 +From: Alice Ryhl +Date: Tue, 14 Apr 2026 12:02:34 +0000 +Subject: rust_binder: avoid calling pending_oneway_finished() on TF_UPDATE_TXN + +From: Alice Ryhl + +commit 4c19719eb8b8df08c5bec7c499f73ddaea6f09fc upstream. + +When an outdated transaction is removed from `oneway_todo` due to +`TF_UPDATE_TXN`, its `Allocation` is dropped. The current implementation +of `Allocation::drop` calls `pending_oneway_finished()`, assuming the +transaction was executed. This leads to premature execution of the next +queued one-way transaction. + +Fix this by taking the `oneway_node` from the `Allocation` of the +outdated transaction before it is dropped. This prevents +`Allocation::drop` from signaling completion. + +We do not call `take_oneway_node()` from `Transaction::cancel` because +it's actually correct to call `pending_oneway_finished()` on cancel if +the transaction did not come from `oneway_todo`. This ensures that if +`BINDER_THREAD_EXIT` is invoked and cancels a oneway transaction, then +the next transaction is taken from `oneway_todo`. + +This bug does not lead to any issues in the kernel, but may lead to +Binder delivering transactions to userspace earlier than userspace +expected to receive them. + +Cc: stable +Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver") +Assisted-by: Antigravity:gemini +Signed-off-by: Alice Ryhl +Acked-by: Carlos Llamas +Link: https://patch.msgid.link/20260414-tf-update-txn-fix-v1-1-d2b83303acc9@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder/allocation.rs | 8 ++++++++ + drivers/android/binder/transaction.rs | 11 ++++++++++- + 2 files changed, 18 insertions(+), 1 deletion(-) + +--- a/drivers/android/binder/allocation.rs ++++ b/drivers/android/binder/allocation.rs +@@ -160,6 +160,14 @@ impl Allocation { + self.get_or_init_info().target_node = Some(target_node); + } + ++ pub(crate) fn take_oneway_node(&mut self) -> Option> { ++ if let Some(info) = self.allocation_info.as_mut() { ++ info.oneway_node.take() ++ } else { ++ None ++ } ++ } ++ + /// Reserve enough space to push at least `num_fds` fds. + pub(crate) fn info_add_fd_reserve(&mut self, num_fds: usize) -> Result { + self.get_or_init_info() +--- a/drivers/android/binder/transaction.rs ++++ b/drivers/android/binder/transaction.rs +@@ -250,7 +250,8 @@ impl Transaction { + /// Not used for replies. + pub(crate) fn submit(self: DLArc) -> BinderResult { + // Defined before `process_inner` so that the destructor runs after releasing the lock. +- let mut _t_outdated; ++ let _t_outdated; ++ let _oneway_node; + + let oneway = self.flags & TF_ONE_WAY != 0; + let process = self.to.clone(); +@@ -267,6 +268,14 @@ impl Transaction { + if let Some(t_outdated) = + target_node.take_outdated_transaction(&self, &mut process_inner) + { ++ let mut alloc_guard = t_outdated.allocation.lock(); ++ if let Some(alloc) = (*alloc_guard).as_mut() { ++ // Take the oneway node to prevent `Allocation::drop` from calling ++ // `pending_oneway_finished()`, which would be incorrect as this ++ // transaction is not being submitted. ++ _oneway_node = alloc.take_oneway_node(); ++ } ++ drop(alloc_guard); + // Save the transaction to be dropped after locks are released. + _t_outdated = t_outdated; + } diff --git a/queue-7.0/rust_binder-avoid-holding-lock-when-dropping-delivered_death.patch b/queue-7.0/rust_binder-avoid-holding-lock-when-dropping-delivered_death.patch new file mode 100644 index 0000000000..c0000280cd --- /dev/null +++ b/queue-7.0/rust_binder-avoid-holding-lock-when-dropping-delivered_death.patch @@ -0,0 +1,52 @@ +From f6d8fea9e3953151a4adb4f603503dc3dc9c69da Mon Sep 17 00:00:00 2001 +From: Matthew Maurer +Date: Fri, 3 Apr 2026 18:18:58 +0000 +Subject: rust_binder: Avoid holding lock when dropping delivered_death + +From: Matthew Maurer + +commit f6d8fea9e3953151a4adb4f603503dc3dc9c69da upstream. + +In 6c37bebd8c926, we switched to looping over the list and dropping each +individual node, ostensibly without the lock held in the loop body. + +If the kernel were using Rust Edition 2024, the comment would be +accurate, and the lock would not be held across the drop. However, the +kernel is currently using 2021, so tail expression lifetime extension +results in the lock being held across the drop. Explicitly binding the +expression result to a variable makes the lockguard no longer part of a +tail expression, causing the lock to be dropped before entering the loop +body. + +This was detected via `CONFIG_PROVE_LOCKING` identifying an invalid wait +context at the drop site. + +Reported-by: David Stevens +Signed-off-by: Matthew Maurer +Cc: stable +Fixes: 6c37bebd8c92 ("rust_binder: avoid mem::take on delivered_deaths") +Reviewed-by: Alice Ryhl +Acked-by: Carlos Llamas +Link: https://patch.msgid.link/20260403-lockhold-v1-1-c332b56cd8ae@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder/process.rs | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/android/binder/process.rs ++++ b/drivers/android/binder/process.rs +@@ -1402,7 +1402,12 @@ impl Process { + // Clear delivered_deaths list. + // + // Scope ensures that MutexGuard is dropped while executing the body. +- while let Some(delivered_death) = { self.inner.lock().delivered_deaths.pop_front() } { ++ while let Some(delivered_death) = { ++ // Explicitly bind to avoid tail expression lifetime extension of the lockguard ++ // Can be removed when the kernel moves to edition 2024 ++ let maybe_death = self.inner.lock().delivered_deaths.pop_front(); ++ maybe_death ++ } { + drop(delivered_death); + } + diff --git a/queue-7.0/series b/queue-7.0/series index d6b7d8e26e..7c14905f34 100644 --- a/queue-7.0/series +++ b/queue-7.0/series @@ -132,3 +132,76 @@ input-ims-pcu-fix-usb_free_coherent-size-in-ims_pcu_buffers_free.patch usb-serial-cypress_m8-fix-memory-corruption-with-small-endpoint.patch hid-quirks-add-always_poll-quirk-for-sigmachip-usb-mouse.patch bluetooth-btusb-allow-firmware-re-download-when-version-matches.patch +mm-vmalloc-do-not-trigger-bug-on-bh-disabled-context.patch +hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch +mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch +ipc-limit-next_id-allocation-to-the-valid-id-range.patch +mm-memcontrol-propagate-nmi-slab-stats-to-memcg-vmstats.patch +mm-migrate_device-fix-pgtable-leak-in-migrate_vma_insert_huge_pmd_page.patch +memfd-deny-writeable-mappings-when-implying-seal_write.patch +zram-fix-use-after-free-in-zram_writeback_endio.patch +mm-rmap-initialize-nr_pages-to-1-at-loop-start-in-try_to_unmap_one.patch +auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch +smb-client-fix-uninitialized-variable-in-smb2_writev_callback.patch +bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch +bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch +bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch +bluetooth-iso-fix-uaf-in-iso_recv_frame.patch +bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch +bluetooth-hci_conn-fix-memory-leak-in-hci_le_big_terminate.patch +bluetooth-hci_qca-use-100-ms-ssr-delay-for-rampatch-and-nvm-loading.patch +bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch +input-xpad-fix-out-of-bounds-access-for-share-button.patch +parport-fix-race-between-port-and-client-registration.patch +rust_binder-avoid-holding-lock-when-dropping-delivered_death.patch +rust_binder-avoid-calling-pending_oneway_finished-on-tf_update_txn.patch +usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch +kvm-arm64-correctly-cap-zcr_el2-provided-by-a-guest-hypervisor.patch +kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch +kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch +kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch +kvm-sev-ignore-port-i-o-requests-of-length-0.patch +kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch +kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch +kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch +kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch +kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch +kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch +gpio-shared-undo-the-vote-of-the-proxy-on-gpio-free.patch +gpio-shared-fix-deadlock-on-shared-proxy-s-parent-removal.patch +gpio-shared-fix-lockdep-false-positive-by-removing-unneeded-lock.patch +disable-wattribute-alias-for-clang-23-and-newer.patch +iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch +iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch +iio-dac-ad3530r-fix-ad3531-ad3531r-powerdown-mode-strings.patch +iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch +iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch +iio-dac-ad5686-fix-input-raw-value-check.patch +iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch +iio-dac-ad5686-fix-powerdown-control-on-dual-channel-devices.patch +iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch +iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch +iio-adc-ad4695-fix-call-ordering-in-offload-buffer-postenable.patch +iio-adc-nxp-sar-adc-fix-division-by-zero-in-write_raw.patch +iio-adc-nxp-sar-adc-avoid-division-by-zero.patch +iio-adc-nxp-sar-adc-zero-initialize-dma_slave_config.patch +iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch +iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch +iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch +iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch +iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch +iio-light-veml6070-fix-resource-leak-in-probe-error-path.patch +iio-fix-iio_multiply_value-use-in-iio_read_channel_processed_scale.patch +iio-chemical-mhz19b-reject-oversized-serial-replies.patch +iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch +iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch +iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch +iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch +usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch +usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch +usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch +usb-cdns3-plat-fix-unbalanced-pm_runtime_forbid-call-permanently-leaks-the-runtime-pm-usage-counter-across-bind-unbind-cycles.patch +usb-dwc2-fix-use-after-free-in-debug-code.patch +input-elan_i2c-validate-firmware-size-before-use.patch +i2c-davinci-fix-division-by-zero-on-missing-clock-frequency.patch +x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch diff --git a/queue-7.0/smb-client-fix-uninitialized-variable-in-smb2_writev_callback.patch b/queue-7.0/smb-client-fix-uninitialized-variable-in-smb2_writev_callback.patch new file mode 100644 index 0000000000..1a7a8a8ec6 --- /dev/null +++ b/queue-7.0/smb-client-fix-uninitialized-variable-in-smb2_writev_callback.patch @@ -0,0 +1,31 @@ +From 9d2491197a00acf8c423512078458c2855102b66 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Fri, 22 May 2026 18:28:49 -0500 +Subject: smb: client: fix uninitialized variable in smb2_writev_callback + +From: Steve French + +commit 9d2491197a00acf8c423512078458c2855102b66 upstream. + +compiling with W=2 pointed out that "written may be used uninitialized" + +Fixes: 20d72b00ca81 ("netfs: Fix the request's work item to not require a ref") +Cc: stable@vger.kernel.org +Reviewed-by: David Howells +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/smb2pdu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -4943,7 +4943,7 @@ smb2_writev_callback(struct TCP_Server_I + unsigned int rreq_debug_id = wdata->rreq->debug_id; + unsigned int subreq_debug_index = wdata->subreq.debug_index; + ssize_t result = 0; +- size_t written; ++ size_t written = 0; + + WARN_ONCE(wdata->server != server, + "wdata server %p != mid server %p", diff --git a/queue-7.0/usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch b/queue-7.0/usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch new file mode 100644 index 0000000000..3e4544d9ca --- /dev/null +++ b/queue-7.0/usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch @@ -0,0 +1,49 @@ +From 5eb070769ea5e18405535609d1d3f6886f3755bd Mon Sep 17 00:00:00 2001 +From: Wentao Guan +Date: Fri, 22 May 2026 17:13:58 +0800 +Subject: USB: cdc-acm: Fix bit overlap and move quirk definitions to header + +From: Wentao Guan + +commit 5eb070769ea5e18405535609d1d3f6886f3755bd upstream. + +The VENDOR_CLASS_DATA_IFACE and ALWAYS_POLL_CTRL quirk flags added in +commit f58752ebcb35 ("USB: cdc-acm: Add quirks for Yoga Book 9 14IAH10 +INGENIC touchscreen") were placed inside the acm_ctrl_msg() function +rather than in the header with the other quirk flags. Then, their +values (BIT(9) and BIT(10)) collided with NO_UNION_12 which is already +BIT(9). + +Move the definitions to drivers/usb/class/cdc-acm.h where they belong +and shift them to BIT(10) and BIT(11) to avoid the overlap. + +Fixes: f58752ebcb35 ("USB: cdc-acm: Add quirks for Yoga Book 9 14IAH10 INGENIC touchscreen") +Cc: stable +Signed-off-by: Wentao Guan +Link: https://patch.msgid.link/20260522091357.1301196-1-guanwentao@uniontech.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/cdc-acm.c | 2 -- + drivers/usb/class/cdc-acm.h | 2 ++ + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -114,8 +114,6 @@ static int acm_ctrl_msg(struct acm *acm, + int retval; + + retval = usb_autopm_get_interface(acm->control); +-#define VENDOR_CLASS_DATA_IFACE BIT(9) /* data interface uses vendor-specific class */ +-#define ALWAYS_POLL_CTRL BIT(10) /* keep ctrl URB active even without an open TTY */ + if (retval) + return retval; + +--- a/drivers/usb/class/cdc-acm.h ++++ b/drivers/usb/class/cdc-acm.h +@@ -115,3 +115,5 @@ struct acm { + #define DISABLE_ECHO BIT(7) + #define MISSING_CAP_BRK BIT(8) + #define NO_UNION_12 BIT(9) ++#define VENDOR_CLASS_DATA_IFACE BIT(10) /* data interface uses vendor-specific class */ ++#define ALWAYS_POLL_CTRL BIT(11) /* keep ctrl URB active even without an open TTY */ diff --git a/queue-7.0/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch b/queue-7.0/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch new file mode 100644 index 0000000000..30d05e5044 --- /dev/null +++ b/queue-7.0/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch @@ -0,0 +1,67 @@ +From c8778ff817a7047d6848fefba99dcb27b1bf01fe Mon Sep 17 00:00:00 2001 +From: Yongchao Wu +Date: Thu, 14 May 2026 00:00:12 +0800 +Subject: usb: cdns3: gadget: fix request skipping after clearing halt + +From: Yongchao Wu + +commit c8778ff817a7047d6848fefba99dcb27b1bf01fe upstream. + +According to the cdns3 datasheet, the EPRST (Endpoint Reset) command +causes the DMA engine to reposition its internal pointer to the next +Transfer Descriptor (TD) if it was already processing one. + +This issue is consistently observed during the ADB identification +process on macOS hosts, where the host issues a Clear_Halt. Although +commit 4bf2dd65135a ("usb: cdns3: gadget: toggle cycle bit before reset +endpoint") attempted to avoid DMA advance by toggling the cycle bit, +trace logs show that on certain hosts like macOS, the DMA pointer +(EP_TRADDR) still shifts after EPRST: + + cdns3_ctrl_req: Clear Endpoint Feature(Halt ep1out) + cdns3_doorbell_epx: ep1out, ep_trbaddr f9c04030 <-- Should be f9c04000 + cdns3_gadget_giveback: ep1out: req: ... length: 16384/16384 + +As shown above, the DMA pointer jumped to the next TD, causing +the controller to skip the initial TRBs of the request. This leads to +data misalignment and ADB protocol hangs on macOS. + +Fix this by manually restoring the EP_TRADDR register to the starting +physical address of the current request after the EPRST operation is +complete. + +Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") +Cc: stable +Cc: Peter Chen +Signed-off-by: Yongchao Wu +Acked-by: Peter Chen +Link: https://patch.msgid.link/20260513160012.2547894-1-yongchao.wu@autochips.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdns3-gadget.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/usb/cdns3/cdns3-gadget.c ++++ b/drivers/usb/cdns3/cdns3-gadget.c +@@ -2817,9 +2817,19 @@ int __cdns3_gadget_ep_clear_halt(struct + priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING); + + if (request) { +- if (trb) ++ if (trb) { + *trb = trb_tmp; + ++ /* ++ * Per datasheet, EPRST causes DMA to reposition to the next TD. ++ * Manually reset EP_TRADDR to the current TRB to prevent ++ * the hardware from skipping the interrupted request. ++ */ ++ writel(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma + ++ priv_req->start_trb * TRB_SIZE), ++ &priv_dev->regs->ep_traddr); ++ } ++ + cdns3_rearm_transfer(priv_ep, 1); + } + diff --git a/queue-7.0/usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch b/queue-7.0/usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch new file mode 100644 index 0000000000..9c9a30ddb0 --- /dev/null +++ b/queue-7.0/usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch @@ -0,0 +1,45 @@ +From e6970cda63fd4b4546aeed9d0e2f53a7c95cd09c Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Wed, 13 May 2026 16:53:09 +0800 +Subject: usb: cdns3: plat: fix leaked usb2_phy initialization on usb3_phy acquisition failure + +From: Peter Chen + +commit e6970cda63fd4b4546aeed9d0e2f53a7c95cd09c upstream. + +Move usb2_phy initialization after usb3_phy acquisition. + +Fixes: f738957277ba ("usb: cdns3: Split core.c into cdns3-plat and core.c file") +Cc: stable +Reported-by: sashiko-bot +Closes: https://lore.kernel.org/linux-devicetree/agKaEePSFknhDBg2@nchen-desktop/T/#m21e1d9c1574eb127ce03c0c2a1a49002ce435b52 +Signed-off-by: Peter Chen +Link: https://patch.msgid.link/20260513085310.2217547-2-peter.chen@cixtech.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdns3-plat.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/cdns3/cdns3-plat.c ++++ b/drivers/usb/cdns3/cdns3-plat.c +@@ -126,15 +126,15 @@ static int cdns3_plat_probe(struct platf + return dev_err_probe(dev, PTR_ERR(cdns->usb2_phy), + "Failed to get cdn3,usb2-phy\n"); + +- ret = phy_init(cdns->usb2_phy); +- if (ret) +- return ret; +- + cdns->usb3_phy = devm_phy_optional_get(dev, "cdns3,usb3-phy"); + if (IS_ERR(cdns->usb3_phy)) + return dev_err_probe(dev, PTR_ERR(cdns->usb3_phy), + "Failed to get cdn3,usb3-phy\n"); + ++ ret = phy_init(cdns->usb2_phy); ++ if (ret) ++ return ret; ++ + ret = phy_init(cdns->usb3_phy); + if (ret) + goto err_phy3_init; diff --git a/queue-7.0/usb-cdns3-plat-fix-unbalanced-pm_runtime_forbid-call-permanently-leaks-the-runtime-pm-usage-counter-across-bind-unbind-cycles.patch b/queue-7.0/usb-cdns3-plat-fix-unbalanced-pm_runtime_forbid-call-permanently-leaks-the-runtime-pm-usage-counter-across-bind-unbind-cycles.patch new file mode 100644 index 0000000000..ee60952018 --- /dev/null +++ b/queue-7.0/usb-cdns3-plat-fix-unbalanced-pm_runtime_forbid-call-permanently-leaks-the-runtime-pm-usage-counter-across-bind-unbind-cycles.patch @@ -0,0 +1,35 @@ +From ae6f3b82324e4f39ad8443c9020787e6fc889637 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Wed, 13 May 2026 16:53:10 +0800 +Subject: usb: cdns3: plat: fix unbalanced pm_runtime_forbid() call permanently leaks the runtime PM usage counter across bind/unbind cycles + +From: Peter Chen + +commit ae6f3b82324e4f39ad8443c9020787e6fc889637 upstream. + +Call pm_runtime_allow(dev) conditionally at cdns3_plat_remove. + +Fixes: f738957277ba ("usb: cdns3: Split core.c into cdns3-plat and core.c file") +Cc: stable +Reported-by: sashiko-bot +Closes: https://lore.kernel.org/linux-devicetree/agKaEePSFknhDBg2@nchen-desktop/T/#m21e1d9c1574eb127ce03c0c2a1a49002ce435b52 +Signed-off-by: Peter Chen +Link: https://patch.msgid.link/20260513085310.2217547-3-peter.chen@cixtech.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdns3-plat.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/cdns3/cdns3-plat.c ++++ b/drivers/usb/cdns3/cdns3-plat.c +@@ -186,6 +186,9 @@ static void cdns3_plat_remove(struct pla + struct device *dev = cdns->dev; + + pm_runtime_get_sync(dev); ++ if (!(cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW))) ++ pm_runtime_allow(dev); ++ + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); + cdns_remove(cdns); diff --git a/queue-7.0/usb-dwc2-fix-use-after-free-in-debug-code.patch b/queue-7.0/usb-dwc2-fix-use-after-free-in-debug-code.patch new file mode 100644 index 0000000000..400695d128 --- /dev/null +++ b/queue-7.0/usb-dwc2-fix-use-after-free-in-debug-code.patch @@ -0,0 +1,46 @@ +From 9ea06a3fbf9f16e0d98c52cb3b99642be15ec281 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 20 May 2026 08:59:28 +0300 +Subject: usb: dwc2: Fix use after free in debug code + +From: Dan Carpenter + +commit 9ea06a3fbf9f16e0d98c52cb3b99642be15ec281 upstream. + +We're not allowed to dereference "urb" after calling +usb_hcd_giveback_urb() so save the urb->status ahead of time. + +Fixes: 7359d482eb4d ("staging: HCD files for the DWC2 driver") +Cc: stable +Signed-off-by: Dan Carpenter +Link: https://patch.msgid.link/ag1NwBpqT4IEQcdJ@stanley.mountain +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/hcd.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -4804,6 +4804,7 @@ static int _dwc2_hcd_urb_dequeue(struct + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + int rc; + unsigned long flags; ++ int urb_status; + + dev_dbg(hsotg->dev, "DWC OTG HCD URB Dequeue\n"); + dwc2_dump_urb_info(hcd, urb, "urb_dequeue"); +@@ -4828,11 +4829,12 @@ static int _dwc2_hcd_urb_dequeue(struct + + /* Higher layer software sets URB status */ + spin_unlock(&hsotg->lock); ++ urb_status = urb->status; + usb_hcd_giveback_urb(hcd, urb, status); + spin_lock(&hsotg->lock); + + dev_dbg(hsotg->dev, "Called usb_hcd_giveback_urb()\n"); +- dev_dbg(hsotg->dev, " urb->status = %d\n", urb->status); ++ dev_dbg(hsotg->dev, " urb->status = %d\n", urb_status); + out: + spin_unlock_irqrestore(&hsotg->lock, flags); + diff --git a/queue-7.0/usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch b/queue-7.0/usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch new file mode 100644 index 0000000000..50a9be5a54 --- /dev/null +++ b/queue-7.0/usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch @@ -0,0 +1,55 @@ +From 60df93d30f9bdd27db17c4d80ed80ef718d7226b Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 22 May 2026 16:20:58 +0200 +Subject: USB: serial: omninet: fix memory corruption with small endpoint + +From: Johan Hovold + +commit 60df93d30f9bdd27db17c4d80ed80ef718d7226b upstream. + +Make sure that the bulk-out buffers are at least as large as the +hardcoded transfer size to avoid user-controlled slab corruption should +a malicious device report a smaller endpoint max packet size than +expected. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/omninet.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/omninet.c ++++ b/drivers/usb/serial/omninet.c +@@ -30,6 +30,10 @@ + /* This one seems to be a re-branded ZyXEL device */ + #define BT_IGNITIONPRO_ID 0x2000 + ++#define OMNINET_HEADERLEN 4 ++#define OMNINET_BULKOUTSIZE 64 ++#define OMNINET_PAYLOADSIZE (OMNINET_BULKOUTSIZE - OMNINET_HEADERLEN) ++ + /* function prototypes */ + static void omninet_process_read_urb(struct urb *urb); + static int omninet_prepare_write_buffer(struct usb_serial_port *port, +@@ -54,6 +58,7 @@ static struct usb_serial_driver zyxel_om + .description = "ZyXEL - omni.net usb", + .id_table = id_table, + .num_bulk_out = 2, ++ .bulk_out_size = OMNINET_BULKOUTSIZE, + .calc_num_ports = omninet_calc_num_ports, + .port_probe = omninet_port_probe, + .port_remove = omninet_port_remove, +@@ -130,10 +135,6 @@ static void omninet_port_remove(struct u + kfree(od); + } + +-#define OMNINET_HEADERLEN 4 +-#define OMNINET_BULKOUTSIZE 64 +-#define OMNINET_PAYLOADSIZE (OMNINET_BULKOUTSIZE - OMNINET_HEADERLEN) +- + static void omninet_process_read_urb(struct urb *urb) + { + struct usb_serial_port *port = urb->context; diff --git a/queue-7.0/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch b/queue-7.0/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch new file mode 100644 index 0000000000..55feb18ec6 --- /dev/null +++ b/queue-7.0/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch @@ -0,0 +1,102 @@ +From a17dc12bfed8868e6a86f3b45c16065a70641acb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alexis=20Lothor=C3=A9=20=28eBPF=20Foundation=29?= + +Date: Wed, 27 May 2026 21:12:31 +0200 +Subject: x86/ftrace: Relocate %rip-relative percpu refs in dynamic trampolines +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexis Lothoré (eBPF Foundation) + +commit a17dc12bfed8868e6a86f3b45c16065a70641acb upstream. + +With CONFIG_CALL_DEPTH_TRACKING enabled on an x86 retbleed-affected platform +(eg: Skylake), with retbleed=stuff, registering a dynamic ftrace trampoline +crashes on the first call into the traced function: + + BUG: unable to handle page fault for address: ffff88817ae18880 + #PF: supervisor write access in kernel mode + #PF: error_code(0x0002) - not-present page + PGD 4b53067 P4D 4b53067 PUD 0 + Oops: Oops: 0002 [#1] SMP PTI + CPU: 3 UID: 0 PID: 187 Comm: usleep Not tainted 7.0.10 #243 PREEMPT(full) + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.17.0-2-2 04/01/2014 + Code: 24 78 00 00 00 00 48 89 ea 48 89 54 24 20 48 8b b4 24 b8 00 00 00 48 8b bc 24 b0 00 00 00 48 89 bc 24 80 00 00 00 48 83 ef 05 <65> 48 c1 3d 1f a8 b6 02 05 48 8b 15 f6 00 00 00 4c 89 3c 24 4c 89 + Call Trace: + + ? find_held_lock + ? exc_page_fault + ? lock_release + ? __x64_sys_clock_nanosleep + ? lockdep_hardirqs_on_prepare + ? trace_hardirqs_on + __x64_sys_clock_nanosleep + do_syscall_64 + ? exc_page_fault + ? call_depth_return_thunk + entry_SYSCALL_64_after_hwframe + ... + Kernel panic - not syncing: Fatal exception + +This small reproducer allows to easily trigger the crash: + + # echo 'p __x64_sys_clock_nanosleep' > /sys/kernel/tracing/kprobe_events + # echo 1 > /sys/kernel/tracing/events/kprobes/p___x64_sys_clock_nanosleep_0/enable + # usleep 1 + +Monitoring the crash under GDB points to the exact instruction in charge of +incrementing the call depth: + + sarq $5, %gs:__x86_call_depth(%rip) + +This instruction matches the one inserted by the ftrace_regs_caller from +ftrace_64.S. This emitted code was likely working fine until the introduction +of + + 59bec00ace28 ("x86/percpu: Introduce %rip-relative addressing to PER_CPU_VAR()"): + +it has made the call depth accounting addressing relative to $rip, instead of +being based on an absolute address. + +As this code exact location depends on where the trampoline lives in memory, +the corresponding displacement needs to be adjusted at runtime to actually +correctly find the per-cpu __x86_call_depth value, otherwise the targeted +address is wrong, leading to the page fault seen above. + +Fix the %rip-relative displacement of the copied CALL_DEPTH_ACCOUNT +instruction (from ftrace_regs_caller) by calling text_poke_apply_relocation(), +as it is done for example by the x86 BPF JIT compiler through +x86_call_depth_emit_accounting(). This corrects both CALL_DEPTH_ACCOUNT slots, +in ftrace_caller and ftrace_regs_caller. + + [ bp: Massage. ] + +Fixes: 59bec00ace28 ("x86/percpu: Introduce %rip-relative addressing to PER_CPU_VAR()") +Signed-off-by: Alexis Lothoré (eBPF Foundation) +Signed-off-by: Borislav Petkov (AMD) +Acked-by: Peter Zijlstra (Intel) +Acked-by: Steven Rostedt +Cc: +Link: https://patch.msgid.link/20260527-fix_call_depth_in_trampoline-v1-1-1c1abc8ae310@bootlin.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/ftrace.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/x86/kernel/ftrace.c ++++ b/arch/x86/kernel/ftrace.c +@@ -376,6 +376,13 @@ create_trampoline(struct ftrace_ops *ops + } + + /* ++ * Generated trampoline may contain rIP-relative addressing which ++ * displacement needs to be fixed. ++ */ ++ text_poke_apply_relocation(trampoline, trampoline, size, ++ (void *)start_offset, size); ++ ++ /* + * The address of the ftrace_ops that is used for this trampoline + * is stored at the end of the trampoline. This will be used to + * load the third parameter for the callback. Basically, that diff --git a/queue-7.0/zram-fix-use-after-free-in-zram_writeback_endio.patch b/queue-7.0/zram-fix-use-after-free-in-zram_writeback_endio.patch new file mode 100644 index 0000000000..d09ffcc227 --- /dev/null +++ b/queue-7.0/zram-fix-use-after-free-in-zram_writeback_endio.patch @@ -0,0 +1,114 @@ +From bf62f69574b19720ae5fbbbcdf24a0c4e3e05e43 Mon Sep 17 00:00:00 2001 +From: Richard Chang +Date: Tue, 12 May 2026 07:49:18 +0000 +Subject: zram: fix use-after-free in zram_writeback_endio + +From: Richard Chang + +commit bf62f69574b19720ae5fbbbcdf24a0c4e3e05e43 upstream. + +A crash was observed in zram_writeback_endio due to a NULL pointer +dereference in wake_up. The root cause is a race condition between the +bio completion handler (zram_writeback_endio) and the writeback task. + +In zram_writeback_endio, wake_up() is called on &wb_ctl->done_wait after +releasing wb_ctl->done_lock. This creates a race window where the +writeback task can see num_inflight become 0, return, and free wb_ctl +before zram_writeback_endio calls wake_up(). + +CPU 0 (zram_writeback_endio) CPU 1 (writeback_store) +============================ ============================ + zram_writeback_slots + zram_submit_wb_request + zram_submit_wb_request + wait_event(wb_ctl->done_wait) +spin_lock(&wb_ctl->done_lock); +list_add(&req->entry, &wb_ctl->done_reqs); +spin_unlock(&wb_ctl->done_lock); +wake_up(&wb_ctl->done_wait); + zram_complete_done_reqs +spin_lock(&wb_ctl->done_lock); +list_add(&req->entry, &wb_ctl->done_reqs); +spin_unlock(&wb_ctl->done_lock); + while (num_inflight) > 0) + spin_lock(&wb_ctl->done_lock); + list_del(&req->entry); + spin_unlock(&wb_ctl->done_lock); + // num_inflight becomes 0 + atomic_dec(num_inflight); + + // Leave zram_writeback_slots + // Free wb_ctl + release_wb_ctl(wb_ctl); +// UAF crash! +wake_up(&wb_ctl->done_wait); + +This patch fixes this race by using RCU. By protecting wb_ctl with +rcu_read_lock() in zram_writeback_endio and using kfree_rcu() to free it, +we ensure that wb_ctl remains valid during the execution of +zram_writeback_endio. + +Link: https://lore.kernel.org/20260512074918.2606208-1-richardycc@google.com +Fixes: f405066a1f0d ("zram: introduce writeback bio batching") +Signed-off-by: Richard Chang +Suggested-by: Sergey Senozhatsky +Suggested-by: Minchan Kim +Acked-by: Sergey Senozhatsky +Acked-by: Minchan Kim +Cc: Brian Geffon +Cc: Jens Axboe +Cc: Martin Liu +Cc: wang wei +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/zram/zram_drv.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index aebc710f0d6a..07111455eecf 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #include "zram_drv.h" + +@@ -504,6 +505,7 @@ struct zram_wb_ctl { + wait_queue_head_t done_wait; + spinlock_t done_lock; + atomic_t num_inflight; ++ struct rcu_head rcu; + }; + + struct zram_wb_req { +@@ -847,7 +849,7 @@ static void release_wb_ctl(struct zram_wb_ctl *wb_ctl) + release_wb_req(req); + } + +- kfree(wb_ctl); ++ kfree_rcu(wb_ctl, rcu); + } + + static struct zram_wb_ctl *init_wb_ctl(struct zram *zram) +@@ -964,11 +966,13 @@ static void zram_writeback_endio(struct bio *bio) + struct zram_wb_ctl *wb_ctl = bio->bi_private; + unsigned long flags; + ++ rcu_read_lock(); + spin_lock_irqsave(&wb_ctl->done_lock, flags); + list_add(&req->entry, &wb_ctl->done_reqs); + spin_unlock_irqrestore(&wb_ctl->done_lock, flags); + + wake_up(&wb_ctl->done_wait); ++ rcu_read_unlock(); + } + + static void zram_submit_wb_request(struct zram *zram, +-- +2.54.0 + -- 2.47.3