From: Greg Kroah-Hartman Date: Thu, 4 Jun 2026 08:53:31 +0000 (+0200) Subject: 6.12-stable patches X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=55ed9d8727b22d937a2828c49e7da214beb3a476;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.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 hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.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-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch iio-dac-ad5686-fix-input-raw-value-check.patch iio-dac-max5821-fix-return-value-check-in-powerdown-sync.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-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-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-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 parport-fix-race-between-port-and-client-registration.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 --- diff --git a/queue-6.12/auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch b/queue-6.12/auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch new file mode 100644 index 0000000000..43851f392b --- /dev/null +++ b/queue-6.12/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 +@@ -90,7 +90,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-6.12/bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch b/queue-6.12/bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch new file mode 100644 index 0000000000..f461e0526b --- /dev/null +++ b/queue-6.12/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 +@@ -6626,6 +6626,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 +@@ -6696,6 +6697,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) +@@ -6715,7 +6717,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-6.12/bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch b/queue-6.12/bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch new file mode 100644 index 0000000000..22b9ac5b9b --- /dev/null +++ b/queue-6.12/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-6.12/bluetooth-iso-fix-uaf-in-iso_recv_frame.patch b/queue-6.12/bluetooth-iso-fix-uaf-in-iso_recv_frame.patch new file mode 100644 index 0000000000..5d47cc2328 --- /dev/null +++ b/queue-6.12/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 +@@ -553,7 +553,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) +@@ -562,11 +562,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-6.12/bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch b/queue-6.12/bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch new file mode 100644 index 0000000000..a7280d3eb5 --- /dev/null +++ b/queue-6.12/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 +@@ -835,8 +835,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-6.12/bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch b/queue-6.12/bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch new file mode 100644 index 0000000000..a88d8a0e35 --- /dev/null +++ b/queue-6.12/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-6.12/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch b/queue-6.12/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch new file mode 100644 index 0000000000..cd1ca5189b --- /dev/null +++ b/queue-6.12/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 +@@ -1468,6 +1468,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; +@@ -1485,14 +1489,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-6.12/disable-wattribute-alias-for-clang-23-and-newer.patch b/queue-6.12/disable-wattribute-alias-for-clang-23-and-newer.patch new file mode 100644 index 0000000000..8c22663d8c --- /dev/null +++ b/queue-6.12/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 +@@ -133,6 +133,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 +@@ -569,6 +569,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 +@@ -245,6 +245,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-6.12/hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch b/queue-6.12/hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch new file mode 100644 index 0000000000..772c2de40a --- /dev/null +++ b/queue-6.12/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-6.12/iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch b/queue-6.12/iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch new file mode 100644 index 0000000000..d3707ad5d3 --- /dev/null +++ b/queue-6.12/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 +@@ -347,6 +347,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-6.12/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch b/queue-6.12/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch new file mode 100644 index 0000000000..2c7eed6fd3 --- /dev/null +++ b/queue-6.12/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-6.12/iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch b/queue-6.12/iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch new file mode 100644 index 0000000000..4621c0024b --- /dev/null +++ b/queue-6.12/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-6.12/iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch b/queue-6.12/iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch new file mode 100644 index 0000000000..1994512c99 --- /dev/null +++ b/queue-6.12/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-6.12/iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch b/queue-6.12/iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch new file mode 100644 index 0000000000..7613b27203 --- /dev/null +++ b/queue-6.12/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 +@@ -1911,6 +1911,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-6.12/iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch b/queue-6.12/iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch new file mode 100644 index 0000000000..5f811ee3d1 --- /dev/null +++ b/queue-6.12/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-6.12/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch b/queue-6.12/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch new file mode 100644 index 0000000000..2bf66782e8 --- /dev/null +++ b/queue-6.12/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-6.12/iio-dac-ad5686-fix-input-raw-value-check.patch b/queue-6.12/iio-dac-ad5686-fix-input-raw-value-check.patch new file mode 100644 index 0000000000..eb1037ea39 --- /dev/null +++ b/queue-6.12/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-6.12/iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch b/queue-6.12/iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch new file mode 100644 index 0000000000..b167f53f54 --- /dev/null +++ b/queue-6.12/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 +@@ -91,6 +91,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; + +@@ -104,7 +105,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-6.12/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch b/queue-6.12/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch new file mode 100644 index 0000000000..11367a1372 --- /dev/null +++ b/queue-6.12/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-6.12/iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch b/queue-6.12/iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch new file mode 100644 index 0000000000..b9a66a4e6f --- /dev/null +++ b/queue-6.12/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-6.12/iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch b/queue-6.12/iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch new file mode 100644 index 0000000000..5395af029f --- /dev/null +++ b/queue-6.12/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-6.12/iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch b/queue-6.12/iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch new file mode 100644 index 0000000000..6d54dc35aa --- /dev/null +++ b/queue-6.12/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-6.12/iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch b/queue-6.12/iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch new file mode 100644 index 0000000000..310453319a --- /dev/null +++ b/queue-6.12/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); + + del_timer_sync(&data->wdt_timer); + cancel_work_sync(&data->work_wdt); diff --git a/queue-6.12/iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch b/queue-6.12/iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch new file mode 100644 index 0000000000..c105712276 --- /dev/null +++ b/queue-6.12/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-6.12/input-elan_i2c-validate-firmware-size-before-use.patch b/queue-6.12/input-elan_i2c-validate-firmware-size-before-use.patch new file mode 100644 index 0000000000..e1c12b7a28 --- /dev/null +++ b/queue-6.12/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-6.12/input-xpad-fix-out-of-bounds-access-for-share-button.patch b/queue-6.12/input-xpad-fix-out-of-bounds-access-for-share-button.patch new file mode 100644 index 0000000000..1b1942ece3 --- /dev/null +++ b/queue-6.12/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 +@@ -1081,10 +1081,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-6.12/ipc-limit-next_id-allocation-to-the-valid-id-range.patch b/queue-6.12/ipc-limit-next_id-allocation-to-the-valid-id-range.patch new file mode 100644 index 0000000000..adf55d3525 --- /dev/null +++ b/queue-6.12/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-6.12/kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch b/queue-6.12/kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch new file mode 100644 index 0000000000..dc604feb6f --- /dev/null +++ b/queue-6.12/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 +@@ -163,8 +163,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_sys_reg(vcpu, reg) = val; diff --git a/queue-6.12/kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch b/queue-6.12/kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch new file mode 100644 index 0000000000..d91b884ac1 --- /dev/null +++ b/queue-6.12/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 +@@ -3729,7 +3729,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; +@@ -3739,6 +3739,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)) { +@@ -3754,7 +3767,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-6.12/kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch b/queue-6.12/kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch new file mode 100644 index 0000000000..50a0bb207e --- /dev/null +++ b/queue-6.12/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 +@@ -3502,7 +3502,7 @@ void pre_sev_run(struct vcpu_svm *svm, i + } + + #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; +@@ -3518,10 +3518,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; + } + +@@ -3545,6 +3545,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) +@@ -3554,16 +3556,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"); + +@@ -3579,11 +3581,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-6.12/kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch b/queue-6.12/kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch new file mode 100644 index 0000000000..77e43256b9 --- /dev/null +++ b/queue-6.12/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 +@@ -3675,7 +3675,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) + { +@@ -3710,7 +3710,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); +@@ -3720,11 +3719,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; +@@ -4414,7 +4415,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-6.12/kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch b/queue-6.12/kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch new file mode 100644 index 0000000000..2d1530bf18 --- /dev/null +++ b/queue-6.12/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 +@@ -3543,6 +3543,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-6.12/kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch b/queue-6.12/kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch new file mode 100644 index 0000000000..fb99da28eb --- /dev/null +++ b/queue-6.12/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 +@@ -3699,9 +3699,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; +@@ -3764,8 +3764,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); +@@ -3774,7 +3774,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; +@@ -3818,7 +3818,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-6.12/kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch b/queue-6.12/kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch new file mode 100644 index 0000000000..ac44d55ef3 --- /dev/null +++ b/queue-6.12/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 +@@ -4393,7 +4393,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-6.12/kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch b/queue-6.12/kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch new file mode 100644 index 0000000000..852d4f4a0b --- /dev/null +++ b/queue-6.12/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 +@@ -3509,6 +3509,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-6.12/kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch b/queue-6.12/kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch new file mode 100644 index 0000000000..c2093dc48d --- /dev/null +++ b/queue-6.12/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 +@@ -111,6 +111,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 +@@ -123,12 +152,6 @@ static void avic_activate_vmcb(struct vc + /* Disabling MSR intercept for x2APIC registers */ + svm_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 */ + svm_set_x2apic_msr_interception(svm, true); + } diff --git a/queue-6.12/parport-fix-race-between-port-and-client-registration.patch b/queue-6.12/parport-fix-race-between-port-and-client-registration.patch new file mode 100644 index 0000000000..cf3c6cad64 --- /dev/null +++ b/queue-6.12/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-6.12/series b/queue-6.12/series index 413ee40af5..f7663ab8ae 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -137,3 +137,47 @@ media-rc-igorplugusb-fix-control-request-setup-packet.patch input-ims-pcu-fix-usb_free_coherent-size-in-ims_pcu_buffers_free.patch hid-quirks-add-always_poll-quirk-for-sigmachip-usb-mouse.patch bluetooth-btusb-allow-firmware-re-download-when-version-matches.patch +hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch +ipc-limit-next_id-allocation-to-the-valid-id-range.patch +auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.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_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 +usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.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-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 +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-max5821-fix-return-value-check-in-powerdown-sync.patch +iio-dac-ad5686-fix-input-raw-value-check.patch +iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.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-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-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 +x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch diff --git a/queue-6.12/usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch b/queue-6.12/usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch new file mode 100644 index 0000000000..3e4544d9ca --- /dev/null +++ b/queue-6.12/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-6.12/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch b/queue-6.12/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch new file mode 100644 index 0000000000..30d05e5044 --- /dev/null +++ b/queue-6.12/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-6.12/usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch b/queue-6.12/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-6.12/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-6.12/usb-cdns3-plat-fix-unbalanced-pm_runtime_forbid-call-permanently-leaks-the-runtime-pm-usage-counter-across-bind-unbind-cycles.patch b/queue-6.12/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..2708956484 --- /dev/null +++ b/queue-6.12/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 +@@ -188,6 +188,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-6.12/usb-dwc2-fix-use-after-free-in-debug-code.patch b/queue-6.12/usb-dwc2-fix-use-after-free-in-debug-code.patch new file mode 100644 index 0000000000..400695d128 --- /dev/null +++ b/queue-6.12/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-6.12/usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch b/queue-6.12/usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch new file mode 100644 index 0000000000..50a9be5a54 --- /dev/null +++ b/queue-6.12/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-6.12/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch b/queue-6.12/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch new file mode 100644 index 0000000000..c417927482 --- /dev/null +++ b/queue-6.12/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 +@@ -371,6 +371,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