--- /dev/null
+From 1720db928e5a58ca7d75ac1d514c3b73fd7061a7 Mon Sep 17 00:00:00 2001
+From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+Date: Tue, 9 Jun 2026 16:00:52 +0800
+Subject: 6lowpan: fix NHC entry use-after-free on error path
+
+From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+
+commit 1720db928e5a58ca7d75ac1d514c3b73fd7061a7 upstream.
+
+lowpan_nhc_do_uncompression() looks up an NHC descriptor while holding
+lowpan_nhc_lock. If the descriptor has no uncompress callback, the error
+path drops the lock before printing nhc->name.
+
+lowpan_nhc_del() removes descriptors under the same lock and then relies
+on synchronize_net() before the owning module can be unloaded. That only
+waits for net RX RCU readers. lowpan_header_decompress() is also exported
+and can be reached from callers that are not necessarily covered by the net
+core RX critical section, for example the Bluetooth 6LoWPAN L2CAP receive
+path.
+
+This leaves a race where one task drops lowpan_nhc_lock in the error path,
+another task unregisters and frees the matching descriptor after
+synchronize_net() returns, and the first task then dereferences nhc->name
+for the warning.
+
+With the post-unlock window widened, KASAN reports:
+
+ BUG: KASAN: slab-use-after-free in lowpan_nhc_do_uncompression+0x1f4/0x220
+ Read of size 8
+ lowpan_nhc_do_uncompression
+ lowpan_header_decompress
+
+Fix this by printing the warning before dropping lowpan_nhc_lock, so the
+descriptor name is read while unregister is still excluded. The malformed
+packet is still rejected with -ENOTSUPP.
+
+Fixes: 92aa7c65d295 ("6lowpan: add generic nhc layer interface")
+Cc: stable@vger.kernel.org
+Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
+Reported-by: Ao Wang <wangao@seu.edu.cn>
+Reported-by: Xuewei Feng <fengxw06@126.com>
+Reported-by: Qi Li <qli01@tsinghua.edu.cn>
+Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
+Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+Acked-by: Alexander Aring <aahringo@redhat.com>
+Link: https://patch.msgid.link/20260609080054.4541-1-zhaoyz24@mails.tsinghua.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/6lowpan/nhc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/6lowpan/nhc.c
++++ b/net/6lowpan/nhc.c
+@@ -117,9 +117,9 @@ int lowpan_nhc_do_uncompression(struct s
+ return ret;
+ }
+ } else {
+- spin_unlock_bh(&lowpan_nhc_lock);
+ netdev_warn(dev, "received nhc id for %s which is not implemented.\n",
+ nhc->name);
++ spin_unlock_bh(&lowpan_nhc_lock);
+ return -ENOTSUPP;
+ }
+ } else {
--- /dev/null
+From c9a71daaecb2fb1d8c704545cc0b1c920b9bf5d7 Mon Sep 17 00:00:00 2001
+From: Chi Wang <wangchi@kylinos.cn>
+Date: Fri, 19 Jun 2026 15:42:44 +0800
+Subject: audit: Fix data races of skb_queue_len() readers on audit_queue
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chi Wang <wangchi@kylinos.cn>
+
+commit c9a71daaecb2fb1d8c704545cc0b1c920b9bf5d7 upstream.
+
+Multiple readers access audit_queue.qlen via skb_queue_len() without
+holding the queue lock or using READ_ONCE(), while kauditd writes to
+this field via the skb_dequeue() → __skb_unlink() path with WRITE_ONCE()
+protected by a spinlock. This constitutes data races.
+
+All affected skb_queue_len(&audit_queue) call sites:
+ - kauditd_thread() wait_event_freezable() condition
+ - audit_receive_msg() AUDIT_GET handler (s.backlog assignment)
+ - audit_receive() backlog check
+ - audit_log_start() backlog check and pr_warn()
+
+KCSAN reports the following conflicting access pattern (one example):
+==================================================================
+BUG: KCSAN: data-race in audit_log_start / skb_dequeue
+
+write (marked) to 0xffffffff8512ee20 of 4 bytes by task 661 on cpu 57:
+ skb_dequeue+0x70/0xf0
+ kauditd_send_queue+0x71/0x220
+ kauditd_thread+0x1cb/0x430
+ kthread+0x1c2/0x210
+ ret_from_fork+0x162/0x1a0
+ ret_from_fork_asm+0x1a/0x30
+
+read to 0xffffffff8512ee20 of 4 bytes by task 36586 on cpu 1:
+ audit_log_start+0x2a0/0x6b0
+ audit_core_dumps+0x64/0xa0
+ do_coredump+0x14b/0x1260
+ get_signal+0xeb2/0xf70
+ arch_do_signal_or_restart+0x41/0x170
+ exit_to_user_mode_loop+0xa2/0x1c0
+ do_syscall_64+0x1a3/0x1c0
+ entry_SYSCALL_64_after_hwframe+0x76/0xe0
+
+value changed: 0x00000001 -> 0x00000000
+==================================================================
+
+Resolve the race by switching to lockless helper skb_queue_len_lockless(),
+which internally uses READ_ONCE() and properly pairs with the WRITE_ONCE()
+write accesses already present on the writer side.
+
+Cc: stable@vger.kernel.org
+Fixes: 3197542482df ("audit: rework audit_log_start()")
+Signed-off-by: Chi Wang <wangchi@kylinos.cn>
+Reviewed-by: Ricardo Robaina <rrobaina@redhat.com>
+[PM: line length tweak]
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/audit.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -950,7 +950,7 @@ main_queue:
+ * do the multicast send and rotate records from the
+ * main queue to the retry/hold queues */
+ wait_event_freezable(kauditd_wait,
+- (skb_queue_len(&audit_queue) ? 1 : 0));
++ (skb_queue_len_lockless(&audit_queue) ? 1 : 0));
+ }
+
+ return 0;
+@@ -1283,7 +1283,7 @@ static int audit_receive_msg(struct sk_b
+ s.rate_limit = audit_rate_limit;
+ s.backlog_limit = audit_backlog_limit;
+ s.lost = atomic_read(&audit_lost);
+- s.backlog = skb_queue_len(&audit_queue);
++ s.backlog = skb_queue_len_lockless(&audit_queue);
+ s.feature_bitmap = AUDIT_FEATURE_BITMAP_ALL;
+ s.backlog_wait_time = audit_backlog_wait_time;
+ s.backlog_wait_time_actual = atomic_read(&audit_backlog_wait_time_actual);
+@@ -1627,7 +1627,7 @@ static void audit_receive(struct sk_buff
+
+ /* can't block with the ctrl lock, so penalize the sender now */
+ if (audit_backlog_limit &&
+- (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
++ (skb_queue_len_lockless(&audit_queue) > audit_backlog_limit)) {
+ DECLARE_WAITQUEUE(wait, current);
+
+ /* wake kauditd to try and flush the queue */
+@@ -1933,7 +1933,7 @@ struct audit_buffer *audit_log_start(str
+ long stime = audit_backlog_wait_time;
+
+ while (audit_backlog_limit &&
+- (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
++ (skb_queue_len_lockless(&audit_queue) > audit_backlog_limit)) {
+ /* wake kauditd to try and flush the queue */
+ wake_up_interruptible(&kauditd_wait);
+
+@@ -1953,7 +1953,7 @@ struct audit_buffer *audit_log_start(str
+ } else {
+ if (audit_rate_check() && printk_ratelimit())
+ pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",
+- skb_queue_len(&audit_queue),
++ skb_queue_len_lockless(&audit_queue),
+ audit_backlog_limit);
+ audit_log_lost("backlog limit exceeded");
+ return NULL;
--- /dev/null
+From b66774b48dd98f07254951f74ea6f513efe7ff8b Mon Sep 17 00:00:00 2001
+From: Marco Elver <elver@google.com>
+Date: Fri, 5 Jun 2026 16:23:35 +0200
+Subject: Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref
+
+From: Marco Elver <elver@google.com>
+
+commit b66774b48dd98f07254951f74ea6f513efe7ff8b upstream.
+
+l2cap_chan_timeout() runs asynchronously and accesses chan->conn. If
+the connection is torn down while the timer is running or pending,
+chan->conn can be freed, leading to a use-after-free when the timer
+worker attempts to lock conn->lock:
+
+| BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112 [inline]
+| BUG: KASAN: slab-use-after-free in atomic_long_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:4456 [inline]
+| BUG: KASAN: slab-use-after-free in __mutex_trylock_fast kernel/locking/mutex.c:161 [inline]
+| BUG: KASAN: slab-use-after-free in mutex_lock+0x4f/0xa0 kernel/locking/mutex.c:318
+| Write of size 8 at addr ffff8881298d9550 by task kworker/2:1/83
+|
+| CPU: 2 UID: 0 PID: 83 Comm: kworker/2:1 Not tainted 7.1.0-rc6-next-20260601-dirty #6 PREEMPT(full)
+| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
+| Workqueue: events l2cap_chan_timeout
+| Call Trace:
+| <TASK>
+| instrument_atomic_read_write include/linux/instrumented.h:112 [inline]
+| atomic_long_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:4456 [inline]
+| __mutex_trylock_fast kernel/locking/mutex.c:161 [inline]
+| mutex_lock+0x4f/0xa0 kernel/locking/mutex.c:318
+| l2cap_chan_timeout+0x5d/0x1b0 net/bluetooth/l2cap_core.c:422
+| process_one_work kernel/workqueue.c:3326 [inline]
+| process_scheduled_works+0x7c8/0xfb0 kernel/workqueue.c:3409
+| worker_thread+0x8a9/0xcf0 kernel/workqueue.c:3490
+| kthread+0x346/0x430 kernel/kthread.c:436
+| ret_from_fork+0x1a3/0x470 arch/x86/kernel/process.c:158
+| ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+| </TASK>
+|
+| Allocated by task 320:
+| l2cap_conn_add+0xa7/0x820 net/bluetooth/l2cap_core.c:7075
+| l2cap_connect_cfm+0xdb/0xd70 net/bluetooth/l2cap_core.c:7452
+| hci_connect_cfm include/net/bluetooth/hci_core.h:2139 [inline]
+| hci_remote_features_evt+0x52f/0x9f0 net/bluetooth/hci_event.c:3760
+| hci_event_func net/bluetooth/hci_event.c:7796 [inline]
+| hci_event_packet+0x561/0xa70 net/bluetooth/hci_event.c:7847
+| hci_rx_work+0x370/0x890 net/bluetooth/hci_core.c:4040
+| process_one_work kernel/workqueue.c:3326 [inline]
+| process_scheduled_works+0x7c8/0xfb0 kernel/workqueue.c:3409
+| worker_thread+0x8a9/0xcf0 kernel/workqueue.c:3490
+| kthread+0x346/0x430 kernel/kthread.c:436
+| ret_from_fork+0x1a3/0x470 arch/x86/kernel/process.c:158
+| ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+|
+| Freed by task 322:
+| hci_disconn_cfm include/net/bluetooth/hci_core.h:2154 [inline]
+| hci_conn_hash_flush+0x101/0x1f0 net/bluetooth/hci_conn.c:2736
+| hci_dev_close_sync+0x889/0xde0 net/bluetooth/hci_sync.c:5405
+| hci_dev_do_close net/bluetooth/hci_core.c:502 [inline]
+| hci_unregister_dev+0x1f7/0x370 net/bluetooth/hci_core.c:2679
+| vhci_release+0x12a/0x180 drivers/bluetooth/hci_vhci.c:690
+| __fput+0x369/0x890 fs/file_table.c:510
+| task_work_run+0x160/0x1d0 kernel/task_work.c:233
+| get_signal+0xf5b/0x1120 kernel/signal.c:2810
+| arch_do_signal_or_restart+0x4d/0x600 arch/x86/kernel/signal.c:337
+| __exit_to_user_mode_loop kernel/entry/common.c:64 [inline]
+| exit_to_user_mode_loop+0x85/0x510 kernel/entry/common.c:98
+| do_syscall_64+0x263/0x3d0 arch/x86/entry/syscall_64.c:100
+| entry_SYSCALL_64_after_hwframe+0x77/0x7f
+|
+| The buggy address belongs to the object at ffff8881298d9400
+| which belongs to the cache kmalloc-512 of size 512
+| The buggy address is located 336 bytes inside of
+| freed 512-byte region [ffff8881298d9400, ffff8881298d9600)
+
+Fix it by having chan->conn hold a reference to l2cap_conn (via
+l2cap_conn_get) when the channel is added to the connection, and
+releasing it in the channel destructor. This ensures the l2cap_conn
+remains alive as long as the channel exists.
+
+A new FLAG_DEL channel flag is introduced to indicate that the channel
+has been deleted from its connection. l2cap_chan_del() atomically sets
+this flag using test_and_set_bit() instead of setting chan->conn to
+NULL. All asynchronous workers (l2cap_chan_timeout, l2cap_ack_timeout,
+l2cap_monitor_timeout, l2cap_retrans_timeout) and l2cap_chan_send()
+check FLAG_DEL to determine whether the channel has been torn down,
+rather than testing chan->conn for NULL.
+
+Fixes: 8c8e620467a7 ("Bluetooth: L2CAP: use chan timer to close channels in cleanup_listen()")
+Cc: <stable@vger.kernel.org>
+Cc: Siwei Zhang <oss@fourdim.xyz>
+Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Assisted-by: Gemini:gemini-3.1-pro-preview
+Reported-by: https://sashiko.dev/#/patchset/20260521021249.3258069-1-oss%40fourdim.xyz
+Signed-off-by: Marco Elver <elver@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/bluetooth/l2cap.h | 1 +
+ net/bluetooth/l2cap_core.c | 34 ++++++++++++++++++++--------------
+ 2 files changed, 21 insertions(+), 14 deletions(-)
+
+--- a/include/net/bluetooth/l2cap.h
++++ b/include/net/bluetooth/l2cap.h
+@@ -748,6 +748,7 @@ enum {
+ FLAG_ECRED_CONN_REQ_SENT,
+ FLAG_PENDING_SECURITY,
+ FLAG_HOLD_HCI_CONN,
++ FLAG_DEL,
+ };
+
+ /* Lock nesting levels for L2CAP channels. We need these because lockdep
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -411,7 +411,7 @@ static void l2cap_chan_timeout(struct wo
+
+ BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
+
+- if (!conn) {
++ if (test_bit(FLAG_DEL, &chan->flags)) {
+ l2cap_chan_put(chan);
+ return;
+ }
+@@ -422,6 +422,9 @@ static void l2cap_chan_timeout(struct wo
+ */
+ l2cap_chan_lock(chan);
+
++ if (test_bit(FLAG_DEL, &chan->flags))
++ goto unlock;
++
+ if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
+ reason = ECONNREFUSED;
+ else if (chan->state == BT_CONNECT &&
+@@ -434,10 +437,10 @@ static void l2cap_chan_timeout(struct wo
+
+ chan->ops->close(chan);
+
++unlock:
+ l2cap_chan_unlock(chan);
+- l2cap_chan_put(chan);
+-
+ mutex_unlock(&conn->lock);
++ l2cap_chan_put(chan);
+ }
+
+ struct l2cap_chan *l2cap_chan_create(void)
+@@ -490,6 +493,9 @@ static void l2cap_chan_destroy(struct kr
+ list_del(&chan->global_l);
+ write_unlock(&chan_list_lock);
+
++ if (chan->conn)
++ l2cap_conn_put(chan->conn);
++
+ kfree(chan);
+ }
+
+@@ -593,7 +599,7 @@ void __l2cap_chan_add(struct l2cap_conn
+
+ conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
+
+- chan->conn = conn;
++ chan->conn = l2cap_conn_get(conn);
+
+ switch (chan->chan_type) {
+ case L2CAP_CHAN_CONN_ORIENTED:
+@@ -648,30 +654,26 @@ void l2cap_chan_add(struct l2cap_conn *c
+
+ void l2cap_chan_del(struct l2cap_chan *chan, int err)
+ {
+- struct l2cap_conn *conn = chan->conn;
+-
+ __clear_chan_timer(chan);
+
+- BT_DBG("chan %p, conn %p, err %d, state %s", chan, conn, err,
++ BT_DBG("chan %p, err %d, state %s", chan, err,
+ state_to_string(chan->state));
+
+ chan->ops->teardown(chan, err);
+
+- if (conn) {
++ if (!test_and_set_bit(FLAG_DEL, &chan->flags)) {
+ /* Delete from channel list */
+ list_del(&chan->list);
+
+ l2cap_chan_put(chan);
+
+- chan->conn = NULL;
+-
+ /* Reference was only held for non-fixed channels or
+ * fixed channels that explicitly requested it using the
+ * FLAG_HOLD_HCI_CONN flag.
+ */
+ if (chan->chan_type != L2CAP_CHAN_FIXED ||
+ test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
+- hci_conn_drop(conn->hcon);
++ hci_conn_drop(chan->conn->hcon);
+ }
+
+ if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
+@@ -1903,7 +1905,7 @@ static void l2cap_monitor_timeout(struct
+
+ l2cap_chan_lock(chan);
+
+- if (!chan->conn) {
++ if (test_bit(FLAG_DEL, &chan->flags)) {
+ l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
+ return;
+@@ -1924,7 +1926,7 @@ static void l2cap_retrans_timeout(struct
+
+ l2cap_chan_lock(chan);
+
+- if (!chan->conn) {
++ if (test_bit(FLAG_DEL, &chan->flags)) {
+ l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
+ return;
+@@ -2565,7 +2567,7 @@ int l2cap_chan_send(struct l2cap_chan *c
+ int err;
+ struct sk_buff_head seg_queue;
+
+- if (!chan->conn)
++ if (test_bit(FLAG_DEL, &chan->flags))
+ return -ENOTCONN;
+
+ /* Connectionless channel */
+@@ -3160,12 +3162,16 @@ static void l2cap_ack_timeout(struct wor
+
+ l2cap_chan_lock(chan);
+
++ if (test_bit(FLAG_DEL, &chan->flags))
++ goto unlock;
++
+ frames_to_ack = __seq_offset(chan, chan->buffer_seq,
+ chan->last_acked_seq);
+
+ if (frames_to_ack)
+ l2cap_send_rr_or_rnr(chan, 0);
+
++unlock:
+ l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
+ }
--- /dev/null
+From fa85d985f614bc3feb343000f14a1072e99b0df1 Mon Sep 17 00:00:00 2001
+From: Samuel Page <sam@bynar.io>
+Date: Mon, 15 Jun 2026 16:09:22 +0100
+Subject: Bluetooth: MGMT: Fix UAF of hci_conn_params in add_device_complete
+
+From: Samuel Page <sam@bynar.io>
+
+commit fa85d985f614bc3feb343000f14a1072e99b0df1 upstream.
+
+add_device_complete() runs from the hci_cmd_sync_work kworker, which
+holds only hci_req_sync_lock and *not* hci_dev_lock. It calls
+hci_conn_params_lookup() and then dereferences the returned object
+(params->flags) without taking hci_dev_lock:
+
+ params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+ ...
+ device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
+ cp->addr.type, hdev->conn_flags,
+ params ? params->flags : 0);
+
+hci_conn_params_lookup() walks hdev->le_conn_params and is documented to
+require hdev->lock. A concurrent MGMT_OP_REMOVE_DEVICE
+(remove_device()), which does run under hci_dev_lock, can call
+hci_conn_params_free() to list_del() and kfree() the very object the
+lookup returned, so the subsequent params->flags read touches freed
+memory [0].
+
+Hold hci_dev_lock() across the hci_conn_params_lookup() and the read of
+params->flags (and the matching event emission) so the lookup result
+cannot be freed by a concurrent remove_device() before it is used,
+honouring the locking contract of hci_conn_params_lookup().
+
+[0]: (trailing page/memory-state dump trimmed)
+BUG: KASAN: slab-use-after-free in add_device_complete+0x358/0x3d8 net/bluetooth/mgmt.c:7671
+Read of size 1 at addr ffff000017ab26c1 by task kworker/u9:8/388
+
+CPU: 1 UID: 0 PID: 388 Comm: kworker/u9:8 Not tainted 7.0.11 #20 PREEMPT
+Hardware name: linux,dummy-virt (DT)
+Workqueue: hci0 hci_cmd_sync_work
+Call trace:
+ show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:499 (C)
+ __dump_stack lib/dump_stack.c:94 [inline]
+ dump_stack_lvl+0xb4/0xd4 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0x118/0x5d8 mm/kasan/report.c:482
+ kasan_report+0xb0/0xf4 mm/kasan/report.c:595
+ __asan_report_load1_noabort+0x20/0x2c mm/kasan/report_generic.c:378
+ add_device_complete+0x358/0x3d8 net/bluetooth/mgmt.c:7671
+ hci_cmd_sync_work+0x14c/0x240 net/bluetooth/hci_sync.c:334
+ process_one_work+0x628/0xd38 kernel/workqueue.c:3289
+ process_scheduled_works kernel/workqueue.c:3372 [inline]
+ worker_thread+0x7a8/0xac0 kernel/workqueue.c:3453
+ kthread+0x39c/0x444 kernel/kthread.c:436
+ ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860
+
+Allocated by task 3401:
+ kasan_save_stack+0x3c/0x64 mm/kasan/common.c:57
+ kasan_save_track+0x20/0x3c mm/kasan/common.c:78
+ kasan_save_alloc_info+0x40/0x54 mm/kasan/generic.c:570
+ poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
+ __kasan_kmalloc+0xd4/0xd8 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263 [inline]
+ __kmalloc_cache_noprof+0x1b0/0x458 mm/slub.c:5385
+ kmalloc_noprof include/linux/slab.h:950 [inline]
+ kzalloc_noprof include/linux/slab.h:1188 [inline]
+ hci_conn_params_add+0x10c/0x4b0 net/bluetooth/hci_core.c:2279
+ hci_conn_params_set net/bluetooth/mgmt.c:5162 [inline]
+ add_device+0x5b4/0xa54 net/bluetooth/mgmt.c:7755
+ hci_mgmt_cmd net/bluetooth/hci_sock.c:1721 [inline]
+ hci_sock_sendmsg+0x10b4/0x1dd0 net/bluetooth/hci_sock.c:1841
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg+0xe0/0x128 net/socket.c:742
+ sock_write_iter+0x250/0x390 net/socket.c:1195
+ new_sync_write fs/read_write.c:595 [inline]
+ vfs_write+0x66c/0xab0 fs/read_write.c:688
+ ksys_write+0x1fc/0x24c fs/read_write.c:740
+ __do_sys_write fs/read_write.c:751 [inline]
+ __se_sys_write fs/read_write.c:748 [inline]
+ __arm64_sys_write+0x70/0xa4 fs/read_write.c:748
+ __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
+ invoke_syscall+0x84/0x2a8 arch/arm64/kernel/syscall.c:49
+ el0_svc_common.constprop.0+0xe4/0x294 arch/arm64/kernel/syscall.c:132
+ do_el0_svc+0x44/0x5c arch/arm64/kernel/syscall.c:151
+ el0_svc+0x38/0xac arch/arm64/kernel/entry-common.c:724
+ el0t_64_sync_handler+0xa0/0xe4 arch/arm64/kernel/entry-common.c:743
+ el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596
+
+Freed by task 3740:
+ kasan_save_stack+0x3c/0x64 mm/kasan/common.c:57
+ kasan_save_track+0x20/0x3c mm/kasan/common.c:78
+ kasan_save_free_info+0x4c/0x74 mm/kasan/generic.c:584
+ poison_slab_object mm/kasan/common.c:253 [inline]
+ __kasan_slab_free+0x88/0xb8 mm/kasan/common.c:285
+ kasan_slab_free include/linux/kasan.h:235 [inline]
+ slab_free_hook mm/slub.c:2685 [inline]
+ slab_free mm/slub.c:6170 [inline]
+ kfree+0x14c/0x458 mm/slub.c:6488
+ hci_conn_params_free+0x288/0x484 net/bluetooth/hci_core.c:2312
+ remove_device+0x4b0/0x968 net/bluetooth/mgmt.c:7919
+ hci_mgmt_cmd net/bluetooth/hci_sock.c:1721 [inline]
+ hci_sock_sendmsg+0x10b4/0x1dd0 net/bluetooth/hci_sock.c:1841
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg+0xe0/0x128 net/socket.c:742
+ sock_write_iter+0x250/0x390 net/socket.c:1195
+ new_sync_write fs/read_write.c:595 [inline]
+ vfs_write+0x66c/0xab0 fs/read_write.c:688
+ ksys_write+0x1fc/0x24c fs/read_write.c:740
+ __do_sys_write fs/read_write.c:751 [inline]
+ __se_sys_write fs/read_write.c:748 [inline]
+ __arm64_sys_write+0x70/0xa4 fs/read_write.c:748
+ __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
+ invoke_syscall+0x84/0x2a8 arch/arm64/kernel/syscall.c:49
+ el0_svc_common.constprop.0+0xe4/0x294 arch/arm64/kernel/syscall.c:132
+ do_el0_svc+0x44/0x5c arch/arm64/kernel/syscall.c:151
+ el0_svc+0x38/0xac arch/arm64/kernel/entry-common.c:724
+ el0t_64_sync_handler+0xa0/0xe4 arch/arm64/kernel/entry-common.c:743
+ el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596
+
+Fixes: 1e2e3044c1bc ("Bluetooth: MGMT: Fix MGMT_OP_ADD_DEVICE invalid device flags")
+Cc: stable@vger.kernel.org
+Assisted-by: Bynario AI
+Signed-off-by: Samuel Page <sam@bynar.io>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/mgmt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7661,6 +7661,8 @@ static void add_device_complete(struct h
+ if (!err) {
+ struct hci_conn_params *params;
+
++ hci_dev_lock(hdev);
++
+ params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
+@@ -7669,6 +7671,7 @@ static void add_device_complete(struct h
+ device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
+ cp->addr.type, hdev->conn_flags,
+ params ? params->flags : 0);
++ hci_dev_unlock(hdev);
+ }
+
+ mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE,
--- /dev/null
+From fa09f08ede3db3050ae16ae1ed92c902d0cada23 Mon Sep 17 00:00:00 2001
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Date: Fri, 29 May 2026 00:52:01 +0800
+Subject: coresight: etb10: restore atomic_t for shared reading state
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+commit fa09f08ede3db3050ae16ae1ed92c902d0cada23 upstream.
+
+The etb10 miscdevice uses drvdata->reading as a shared exclusivity gate
+for userspace buffer access. etb_open() claims that gate with
+local_cmpxchg(), and etb_release() clears it with local_set().
+
+That gate is shared per-device state rather than CPU-local state. A
+running system can reach it whenever /dev/<etb> is opened, closed, and
+reopened by different tasks while the device remains registered, so the
+same drvdata->reading variable may be claimed on one CPU and later
+cleared on another.
+
+This code used to use atomic_t for the same gate, but commit
+27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
+changed it to local_t even though the access pattern remained cross-task
+and cross-CPU. Restore atomic_t together with atomic_cmpxchg() and
+atomic_set() so the exclusivity gate again uses a primitive intended
+for shared state.
+
+The issue was found on Linux v6.18.21 by our static analysis tool while
+scanning surviving local_t-on-shared-state sites, and then manually
+reviewed against the live etb10 file-op path.
+
+It was runtime-validated with a reproducible QEMU no-device KCSAN PoC
+that kept the same report-local contract:
+
+ 1. use one shared struct etb_drvdata carrier and its
+ drvdata->reading gate;
+ 2. call etb_open() and etb_release() sequentially on that gate to
+ confirm the original claim/clear path;
+ 3. bind the open side to CPU0 and the release side to CPU1 for the
+ same gate to show cross-CPU ownership;
+ 4. run bound workers that repeatedly race etb_open() and
+ etb_release() on the same gate until KCSAN reports a target hit.
+
+The harness recorded:
+
+ L1 passed open=1 release=1
+ reading_after_open=1 reading_after_release=0
+ L2 passed open_cpu=0 release_cpu=1
+ cross_cpu_release=1 reading_after=0 open_ret=0
+
+Representative KCSAN excerpt from the no-device validation run:
+
+ BUG: KCSAN: data-race in etb_open.constprop.0.isra.0 [vuln_msv]
+
+ write to 0xffffffffc0003810 of 4 bytes by task 216 on cpu 1:
+ etb_open.constprop.0.isra.0+0x38/0x80 [vuln_msv]
+ l3_worker_thread_fn+0x4f/0xf0 [vuln_msv]
+ kthread+0x17e/0x1c0
+ ret_from_fork+0x22/0x30
+
+ read to 0xffffffffc0003810 of 4 bytes by task 215 on cpu 0:
+ etb_open.constprop.0.isra.0+0x18/0x80 [vuln_msv]
+ l3_worker_thread_fn+0x4f/0xf0 [vuln_msv]
+ kthread+0x17e/0x1c0
+ ret_from_fork+0x22/0x30
+
+ value changed: 0x00000000 -> 0x00000001
+
+ Reported by Kernel Concurrency Sanitizer on:
+ CPU: 0 PID: 215 Comm: etb10_l3_a Tainted: G O 6.1.66 #2
+
+This no-device harness is not a real ETB10 hardware end-to-end run, but
+it preserves the same shared drvdata->reading gate and the same
+etb_open()/etb_release() claim/clear contract. No real ETB10 hardware
+was available for runtime testing.
+
+Build-tested with:
+ make olddefconfig
+ make -j"$(nproc)" drivers/hwtracing/coresight/coresight-etb10.o
+
+Fixes: 27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20260528165201.319452-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hwtracing/coresight/coresight-etb10.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/hwtracing/coresight/coresight-etb10.c
++++ b/drivers/hwtracing/coresight/coresight-etb10.c
+@@ -83,7 +83,7 @@ struct etb_drvdata {
+ struct coresight_device *csdev;
+ struct miscdevice miscdev;
+ raw_spinlock_t spinlock;
+- local_t reading;
++ atomic_t reading;
+ pid_t pid;
+ u8 *buf;
+ u32 buffer_depth;
+@@ -601,7 +601,7 @@ static int etb_open(struct inode *inode,
+ struct etb_drvdata *drvdata = container_of(file->private_data,
+ struct etb_drvdata, miscdev);
+
+- if (local_cmpxchg(&drvdata->reading, 0, 1))
++ if (atomic_cmpxchg(&drvdata->reading, 0, 1))
+ return -EBUSY;
+
+ dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__);
+@@ -639,7 +639,7 @@ static int etb_release(struct inode *ino
+ {
+ struct etb_drvdata *drvdata = container_of(file->private_data,
+ struct etb_drvdata, miscdev);
+- local_set(&drvdata->reading, 0);
++ atomic_set(&drvdata->reading, 0);
+
+ dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__);
+ return 0;
--- /dev/null
+From 6d827ade51a24e18d81afb9f32756d339520a14c Mon Sep 17 00:00:00 2001
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+Date: Fri, 8 May 2026 12:24:16 +0800
+Subject: crypto: amlogic - avoid double cleanup in meson_crypto_probe()
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+commit 6d827ade51a24e18d81afb9f32756d339520a14c upstream.
+
+When meson_allocate_chanlist() fails after a partial allocation, it already
+unwinds the allocated chanlist state through its local error path.
+meson_crypto_probe() then jump to error_flow and calls
+meson_free_chanlist() again, causing the same per-flow resources to be torn
+down twice. In the reproduced failure path, the second teardown
+re-entered crypto_engine_exit() on an already destroyed worker and KASAN
+reported a slab-use-after-free in kthread_destroy_worker().
+
+Prevent double-free by handling partial allocation failures locally within
+meson_allocate_chanlist() and skipping the outer cleanup path.
+
+The bug was first flagged by an experimental analysis tool we are
+developing for kernel memory-management bugs while analyzing
+v6.13-rc1. The tool is still under development and is not yet publicly
+available.
+
+The bug was reproduced in a QEMU x86_64 guest booted with KASAN on v7.1,
+using the reproducer under tools/testing/meson_crypto_probe. The reproducer
+forces the second dma_alloc_attrs() call in the gxl-crypto probe path to
+return NULL, making meson_allocate_chanlist() fail after partial
+initialization. On the unpatched kernel this reliably triggered a
+slab-use-after-free. With this fix applied, the same reproducer no longer
+emits any KASAN report and the probe fails cleanly with -ENOMEM.
+
+ ==================================================================
+ BUG: KASAN: slab-use-after-free in kthread_destroy_worker+0xb2/0xd0
+ Read of size 8 at addr ff1100010c057a68 by task insmod/265
+
+ CPU: 1 UID: 0 PID: 265 Comm: insmod Tainted: G O 7.1.0-rc2-00376-g810af9adc907-dirty #10 PREEMPT(lazy)
+ Tainted: [O]=OOT_MODULE
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x68/0xa0
+ print_report+0xcb/0x5e0
+ ? __virt_addr_valid+0x21d/0x3f0
+ ? kthread_destroy_worker+0xb2/0xd0
+ ? kthread_destroy_worker+0xb2/0xd0
+ kasan_report+0xca/0x100
+ ? kthread_destroy_worker+0xb2/0xd0
+ kthread_destroy_worker+0xb2/0xd0
+ meson_crypto_probe+0x4d0/0xc10 [amlogic_gxl_crypto]
+ platform_probe+0x99/0x140
+ really_probe+0x1c6/0x6a0
+ ? __pfx___device_attach_driver+0x10/0x10
+ __driver_probe_device+0x248/0x310
+ ? acpi_driver_match_device+0xb0/0x100
+ driver_probe_device+0x48/0x210
+ ? __pfx___device_attach_driver+0x10/0x10
+ __device_attach_driver+0x160/0x320
+ bus_for_each_drv+0x104/0x190
+ ? __pfx_bus_for_each_drv+0x10/0x10
+ ? _raw_spin_unlock_irqrestore+0x2c/0x50
+ __device_attach+0x19d/0x3b0
+ ? __pfx___device_attach+0x10/0x10
+ ? do_raw_spin_unlock+0x53/0x220
+ device_initial_probe+0x78/0xa0
+ bus_probe_device+0x5b/0x130
+ device_add+0xcfd/0x1430
+ ? __pfx_device_add+0x10/0x10
+ ? insert_resource+0x34/0x50
+ ? lock_release+0xc9/0x290
+ platform_device_add+0x24e/0x590
+ ? __pfx_meson_crypto_probe_repro_init+0x10/0x10 [meson_crypto_probe_repro]
+ meson_crypto_probe_repro_init+0x330/0xff0 [meson_crypto_probe_repro]
+ do_one_initcall+0xc0/0x450
+ ? __pfx_do_one_initcall+0x10/0x10
+ ? _raw_spin_unlock_irqrestore+0x2c/0x50
+ ? __create_object+0x59/0x80
+ ? kasan_unpoison+0x27/0x60
+ do_init_module+0x27b/0x7d0
+ ? __pfx_do_init_module+0x10/0x10
+ ? kasan_quarantine_put+0x84/0x1d0
+ ? kfree+0x32c/0x510
+ ? load_module+0x561e/0x5ff0
+ load_module+0x54fe/0x5ff0
+ ? __pfx_load_module+0x10/0x10
+ ? security_file_permission+0x20/0x40
+ ? kernel_read_file+0x23d/0x6e0
+ ? mmap_region+0x235/0x4a0
+ ? __pfx_kernel_read_file+0x10/0x10
+ ? __file_has_perm+0x2c0/0x3e0
+ init_module_from_file+0x158/0x180
+ ? __pfx_init_module_from_file+0x10/0x10
+ ? __lock_acquire+0x45a/0x1ba0
+ ? idempotent_init_module+0x315/0x610
+ ? lock_release+0xc9/0x290
+ ? lockdep_init_map_type+0x4b/0x220
+ ? do_raw_spin_unlock+0x53/0x220
+ idempotent_init_module+0x330/0x610
+ ? __pfx_idempotent_init_module+0x10/0x10
+ ? __pfx_cred_has_capability.isra.0+0x10/0x10
+ ? ksys_mmap_pgoff+0x385/0x520
+ __x64_sys_finit_module+0xbe/0x120
+ do_syscall_64+0x115/0x690
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ RIP: 0033:0x7f7d6d31690d
+ Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d f3 b4 0f 00 f7 d8 >
+ RSP: 002b:00007fffc027ac68 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
+ RAX: ffffffffffffffda RBX: 000055f7b81967c0 RCX: 00007f7d6d31690d
+ RDX: 0000000000000000 RSI: 000055f79a0d6cd2 RDI: 0000000000000003
+ RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000003 R11: 0000000000000246 R12: 000055f79a0d6cd2
+ R13: 000055f7b8196790 R14: 000055f79a0d5888 R15: 000055f7b81968e0
+ </TASK>
+
+Fixes: 48fe583fe541 ("crypto: amlogic - Add crypto accelerator for amlogic GXL")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/amlogic/amlogic-gxl-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
++++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
+@@ -291,8 +291,8 @@ static int meson_crypto_probe(struct pla
+ return 0;
+ error_alg:
+ meson_unregister_algs(mc);
+-error_flow:
+ meson_free_chanlist(mc, MAXFLOW - 1);
++error_flow:
+ clk_disable_unprepare(mc->busclk);
+ return err;
+ }
--- /dev/null
+From 6c9dddeb582fde005360f4fe02c760d45ca05fb5 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Sun, 10 May 2026 19:24:55 -0400
+Subject: crypto: krb5 - filter out async aead implementations at alloc
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 6c9dddeb582fde005360f4fe02c760d45ca05fb5 upstream.
+
+krb5_aead_encrypt(), krb5_aead_decrypt() in rfc3961_simplified.c and
+rfc8009_encrypt(), rfc8009_decrypt() in rfc8009_aes2.c set a NULL
+completion callback and treat any negative return from
+crypto_aead_{encrypt,decrypt}() as terminal, falling through to
+kfree_sensitive(buffer). When the encrypt_name resolves to an
+async AEAD instance the request returns -EINPROGRESS, the buffer
+is freed while the backend's worker still holds a pointer, and the
+worker dereferences the freed slab on completion.
+
+KASAN report under UML+SLUB with a synthetic async aead backend
+bound to krb5->encrypt_name:
+
+ BUG: KASAN: slab-use-after-free in t5_stub_complete+0x7d/0xc7
+
+The helpers were written synchronously, so filter the async
+instances out at allocation time instead of plumbing
+crypto_wait_req() through every call site.
+
+Reachable via net/rxrpc/rxgk.c, fs/afs/cm_security.c and
+net/ceph/crypto.c on systems with an async AEAD provider bound to
+the krb5 enctype name.
+
+Fixes: 00244da40f78 ("crypto/krb5: Implement the Kerberos5 rfc3961 encrypt and decrypt functions")
+Fixes: 6c3c0e86c2ac ("crypto/krb5: Implement the AES enctypes from rfc8009")
+Cc: stable@vger.kernel.org
+Suggested-by: Herbert Xu <herbert@gondor.apana.org.au>
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/krb5/krb5_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/crypto/krb5/krb5_api.c
++++ b/crypto/krb5/krb5_api.c
+@@ -207,7 +207,7 @@ struct crypto_aead *krb5_prepare_encrypt
+ struct crypto_aead *ci = NULL;
+ int ret = -ENOMEM;
+
+- ci = crypto_alloc_aead(krb5->encrypt_name, 0, 0);
++ ci = crypto_alloc_aead(krb5->encrypt_name, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(ci)) {
+ ret = PTR_ERR(ci);
+ if (ret == -ENOENT)
--- /dev/null
+From 277281c10c63791067d24d421f7c43a15faa9096 Mon Sep 17 00:00:00 2001
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Date: Wed, 13 May 2026 15:47:32 +0100
+Subject: crypto: qat - fix VF2PF work teardown race in adf_disable_sriov()
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+commit 277281c10c63791067d24d421f7c43a15faa9096 upstream.
+
+The VF2PF interrupt handler queues PF-side response work that stores a
+raw pointer to per-VF state (struct adf_accel_vf_info). Currently,
+adf_disable_sriov() destroys per-VF mutexes and frees vf_info without
+stopping new VF2PF work or waiting for in-flight workers to complete. A
+concurrently scheduled or already queued worker can then dereference
+freed memory.
+
+This manifests as a use-after-free when KASAN is enabled:
+
+ BUG: KASAN: null-ptr-deref in mutex_lock+0x76/0xe0
+ Write of size 8 at addr 0000000000000260 by task kworker/24:2/...
+ Workqueue: qat_pf2vf_resp_wq adf_iov_send_resp [intel_qat]
+ Call Trace:
+ kasan_report+0x119/0x140
+ mutex_lock+0x76/0xe0
+ adf_gen4_pfvf_send+0xd4/0x1f0 [intel_qat]
+ adf_recv_and_handle_vf2pf_msg+0x290/0x360 [intel_qat]
+ adf_iov_send_resp+0x8c/0xe0 [intel_qat]
+ process_one_work+0x6ac/0xfd0
+ worker_thread+0x4dd/0xd30
+ kthread+0x326/0x410
+ ret_from_fork+0x33b/0x670
+
+Add a PF-local flag, vf2pf_disabled, that gates work queueing, worker
+processing, and interrupt re-enabling during teardown. Set this flag
+atomically with the hardware interrupt mask inside
+adf_disable_all_vf2pf_interrupts(). After masking, synchronize the AE
+cluster MSI-X interrupt and flush the PF response workqueue before
+tearing down per-VF locks and state so all in-flight work completes
+before vf_info is destroyed.
+
+Introduce adf_enable_all_vf2pf_interrupts() to clear the flag and
+unmask all VF2PF interrupts under the same lock when SR-IOV is
+re-enabled. This ensures the software flag and hardware state transition
+atomically on both the enable and disable paths.
+
+Cc: stable@vger.kernel.org
+Fixes: ed8ccaef52fa ("crypto: qat - Add support for SRIOV")
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/intel/qat/qat_common/adf_accel_devices.h | 2
+ drivers/crypto/intel/qat/qat_common/adf_common_drv.h | 2
+ drivers/crypto/intel/qat/qat_common/adf_isr.c | 39 ++++++++++++++++
+ drivers/crypto/intel/qat/qat_common/adf_sriov.c | 20 +++++++-
+ 4 files changed, 61 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h
++++ b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h
+@@ -475,6 +475,8 @@ struct adf_accel_dev {
+ struct {
+ /* protects VF2PF interrupts access */
+ spinlock_t vf2pf_ints_lock;
++ /* prevents VF2PF handling from racing with VF state teardown */
++ bool vf2pf_disabled;
+ /* vf_info is non-zero when SR-IOV is init'ed */
+ struct adf_accel_vf_info *vf_info;
+ } pf;
+--- a/drivers/crypto/intel/qat/qat_common/adf_common_drv.h
++++ b/drivers/crypto/intel/qat/qat_common/adf_common_drv.h
+@@ -118,6 +118,7 @@ void qat_comp_alg_callback(void *resp);
+
+ int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev);
+ void adf_isr_resource_free(struct adf_accel_dev *accel_dev);
++void adf_isr_sync_ae_cluster(struct adf_accel_dev *accel_dev);
+ int adf_vf_isr_resource_alloc(struct adf_accel_dev *accel_dev);
+ void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev);
+
+@@ -191,6 +192,7 @@ int adf_sriov_configure(struct pci_dev *
+ void adf_disable_sriov(struct adf_accel_dev *accel_dev);
+ void adf_reenable_sriov(struct adf_accel_dev *accel_dev);
+ void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask);
++void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 num_vfs);
+ void adf_disable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev);
+ bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev);
+ bool adf_recv_and_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr);
+--- a/drivers/crypto/intel/qat/qat_common/adf_isr.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_isr.c
+@@ -62,6 +62,23 @@ void adf_enable_vf2pf_interrupts(struct
+ unsigned long flags;
+
+ spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags);
++ if (!READ_ONCE(accel_dev->pf.vf2pf_disabled))
++ GET_PFVF_OPS(accel_dev)->enable_vf2pf_interrupts(pmisc_addr, vf_mask);
++ spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags);
++}
++
++void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 num_vfs)
++{
++ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
++ unsigned long flags;
++ u32 vf_mask;
++
++ vf_mask = BIT_ULL(num_vfs) - 1;
++ if (!vf_mask)
++ return;
++
++ spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags);
++ WRITE_ONCE(accel_dev->pf.vf2pf_disabled, false);
+ GET_PFVF_OPS(accel_dev)->enable_vf2pf_interrupts(pmisc_addr, vf_mask);
+ spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags);
+ }
+@@ -72,6 +89,7 @@ void adf_disable_all_vf2pf_interrupts(st
+ unsigned long flags;
+
+ spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags);
++ WRITE_ONCE(accel_dev->pf.vf2pf_disabled, true);
+ GET_PFVF_OPS(accel_dev)->disable_all_vf2pf_interrupts(pmisc_addr);
+ spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags);
+ }
+@@ -174,6 +192,27 @@ static irqreturn_t adf_msix_isr_ae(int i
+ return IRQ_NONE;
+ }
+
++void adf_isr_sync_ae_cluster(struct adf_accel_dev *accel_dev)
++{
++ struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
++ struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
++ u32 num_entries = pci_dev_info->msix_entries.num_entries;
++ struct adf_irq *irqs = pci_dev_info->msix_entries.irqs;
++ u32 irq_idx;
++ int irq;
++
++ if (!test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status) || !irqs)
++ return;
++
++ irq_idx = num_entries > 1 ? hw_data->num_banks : 0;
++ if (irq_idx >= num_entries || !irqs[irq_idx].enabled)
++ return;
++
++ irq = pci_irq_vector(pci_dev_info->pci_dev, hw_data->num_banks);
++ if (irq > 0)
++ synchronize_irq(irq);
++}
++
+ static void adf_free_irqs(struct adf_accel_dev *accel_dev)
+ {
+ struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
+--- a/drivers/crypto/intel/qat/qat_common/adf_sriov.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_sriov.c
+@@ -26,6 +26,9 @@ static void adf_iov_send_resp(struct wor
+ u32 vf_nr = vf_info->vf_nr;
+ bool ret;
+
++ if (READ_ONCE(accel_dev->pf.vf2pf_disabled))
++ goto out;
++
+ mutex_lock(&vf_info->pfvf_mig_lock);
+ ret = adf_recv_and_handle_vf2pf_msg(accel_dev, vf_nr);
+ if (ret)
+@@ -33,13 +36,18 @@ static void adf_iov_send_resp(struct wor
+ adf_enable_vf2pf_interrupts(accel_dev, 1 << vf_nr);
+ mutex_unlock(&vf_info->pfvf_mig_lock);
+
++out:
+ kfree(pf2vf_resp);
+ }
+
+ void adf_schedule_vf2pf_handler(struct adf_accel_vf_info *vf_info)
+ {
++ struct adf_accel_dev *accel_dev = vf_info->accel_dev;
+ struct adf_pf2vf_resp *pf2vf_resp;
+
++ if (READ_ONCE(accel_dev->pf.vf2pf_disabled))
++ return;
++
+ pf2vf_resp = kzalloc_obj(*pf2vf_resp, GFP_ATOMIC);
+ if (!pf2vf_resp)
+ return;
+@@ -49,6 +57,12 @@ void adf_schedule_vf2pf_handler(struct a
+ queue_work(pf2vf_resp_wq, &pf2vf_resp->pf2vf_resp_work);
+ }
+
++static void adf_flush_pf2vf_resp_wq(void)
++{
++ if (pf2vf_resp_wq)
++ flush_workqueue(pf2vf_resp_wq);
++}
++
+ static int adf_enable_sriov(struct adf_accel_dev *accel_dev)
+ {
+ struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
+@@ -75,7 +89,7 @@ static int adf_enable_sriov(struct adf_a
+ hw_data->configure_iov_threads(accel_dev, true);
+
+ /* Enable VF to PF interrupts for all VFs */
+- adf_enable_vf2pf_interrupts(accel_dev, BIT_ULL(totalvfs) - 1);
++ adf_enable_all_vf2pf_interrupts(accel_dev, totalvfs);
+
+ /*
+ * Due to the hardware design, when SR-IOV and the ring arbiter
+@@ -248,8 +262,10 @@ void adf_disable_sriov(struct adf_accel_
+ adf_pf2vf_wait_for_restarting_complete(accel_dev);
+ pci_disable_sriov(accel_to_pci_dev(accel_dev));
+
+- /* Disable VF to PF interrupts */
++ /* Block VF2PF work and disable VF to PF interrupts */
+ adf_disable_all_vf2pf_interrupts(accel_dev);
++ adf_isr_sync_ae_cluster(accel_dev);
++ adf_flush_pf2vf_resp_wq();
+
+ /* Clear Valid bits in AE Thread to PCIe Function Mapping */
+ if (hw_data->configure_iov_threads)
--- /dev/null
+From b81dde13cc163450dcb402dcc915ef13ba241e01 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@kernel.org>
+Date: Sun, 21 Jun 2026 16:47:44 +0200
+Subject: debugobjects: Plug race against a concurrent OOM disable
+
+From: Thomas Gleixner <tglx@kernel.org>
+
+commit b81dde13cc163450dcb402dcc915ef13ba241e01 upstream.
+
+syzbot reported a puzzling splat:
+
+ WARNING: kernel/time/hrtimer.c:443 at stub_timer+0xa/0x20
+
+stub_timer() is installed as timer callback function in
+hrtimer_fixup_assert_init(), which is invoked when
+debug_object_assert_init() can't find a shadow object. In that case debug
+objects emits a warning about it before invoking the fixup.
+
+Though the provided console log lacks this warning and instead has the
+following a few seconds before the splat:
+
+ ODEBUG: Out of memory. ODEBUG disabled
+
+So the object was looked up in debug_object_assert_init() and the lookup
+failed due a concurrent out of memory situation which disabled debug
+objects and freed the shadow objects:
+
+debug_object_assert_init()
+ if (!debug_objects_enabled)
+ return; obj = alloc();
+ if (!obj) {
+ // Out of memory
+ debug_objects_enabled = false;
+ free_objects();
+ obj = lookup_or_alloc();
+
+ // The lookup failed because the other side
+ // removed the objects, so this returns
+ // an error code as the object in question
+ // is not statically initialized
+
+ if (!IS_ERR_OR_NULL(obj))
+ return;
+ if (!obj) {
+ debug_oom();
+ return;
+ }
+
+ print(...)
+ if (!debug_objects_enabled)
+ return;
+
+ fixup(...)
+
+The debug object splat is skipped because debug_objects_enabled is false,
+but the fixup callback is invoked unconditionally, which makes the timer
+disfunctional.
+
+This is only a problem in debug_object_assert_init() and
+debug_object_activate() as both have to handle statically initialized
+objects and therefore must handle the error pointer return case
+gracefully. All other places only handle the found/not found case and the
+NULL pointer return is a signal for OOM. Otherwise they get a valid shadow
+object.
+
+Plug the hole by checking whether debug objects are still enabled before
+invoking the print and fixup function in those two places.
+
+Fixes: b84d435cc228 ("debugobjects: Extend to assert that an object is initialized")
+Reported-by: syzbot+5e8dda76ca21dae314b6@syzkaller.appspotmail.com
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/874iiwlzlb.ffs@fw13
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/debugobjects.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/lib/debugobjects.c
++++ b/lib/debugobjects.c
+@@ -894,6 +894,14 @@ int debug_object_activate(void *addr, co
+ }
+
+ raw_spin_unlock_irqrestore(&db->lock, flags);
++
++ /*
++ * lookup_object_or_alloc() might have raced with a concurrent
++ * allocation failure which disabled debug objects.
++ */
++ if (!debug_objects_enabled)
++ return 0;
++
+ debug_print_object(&o, "activate");
+
+ switch (o.state) {
+@@ -1071,6 +1079,15 @@ void debug_object_assert_init(void *addr
+ return;
+ }
+
++ /*
++ * lookup_object_or_alloc() might have raced with a concurrent
++ * allocation failure which disabled debug objects. Don't run the fixup
++ * as it might turn a valid object useless. See for example
++ * hrtimer_fixup_assert_init().
++ */
++ if (!debug_objects_enabled)
++ return;
++
+ /* Object is neither tracked nor static. It's not initialized. */
+ debug_print_object(&o, "assert_init");
+ debug_object_fixup(descr->fixup_assert_init, addr, ODEBUG_STATE_NOTAVAILABLE);
--- /dev/null
+From 57382ec6ac63b63dce2789e835fded28b698ae79 Mon Sep 17 00:00:00 2001
+From: Yunpeng Tian <shionthanatos@gmail.com>
+Date: Mon, 4 May 2026 07:19:43 -0700
+Subject: fs/ntfs3: validate Dirty Page Table capacity in log_replay copy_lcns
+
+From: Yunpeng Tian <shionthanatos@gmail.com>
+
+commit 57382ec6ac63b63dce2789e835fded28b698ae79 upstream.
+
+In the analysis pass of $LogFile journal replay, log_replay() copies
+LCNs from each action log record into an existing Dirty Page Table
+(DPT) entry without bounding the destination index. A crafted NTFS
+image with DPT entry lcns_follow=1 and an action log record with
+lcns_follow=2 produces a kernel slab out-of-bounds write at mount
+time:
+
+ BUG: KASAN: slab-out-of-bounds in log_replay+0x654c/0xdb60
+ Write of size 8 at addr ffff8880095e1040 by task mount
+
+Two attacker-controlled fields can drive j+i past the allocated
+page_lcns[] array:
+
+ 1. dp->lcns_follow (capacity) can be smaller than lrh->lcns_follow.
+ 2. lrh->target_vcn may be smaller than dp->vcn, making the u64
+ subtraction wrap to a huge size_t.
+
+Validate target VCN delta and per-record LCN count against the
+DPT entry capacity, bail via the existing out: cleanup label with
+-EINVAL.
+
+This mirrors the bounds-check pattern added in commit b2bc7c44ed17
+("fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot")
+and commit 0ca0485e4b2e ("fs/ntfs3: validate rec->used in
+journal-replay file record check").
+
+Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
+Reported-by: Yunpeng Tian <shionthanatos@gmail.com>
+Reported-by: Mingda Zhang <npczmd@qq.com>
+Reported-by: Gongming Wang <gmwgg05@gmail.com>
+Reported-by: Peiyuan Xu <paulbucket12@gmail.com>
+Reported-by: Qinrun Dai <jupmouse@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Yunpeng Tian <shionthanatos@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ntfs3/fslog.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -4547,11 +4547,21 @@ copy_lcns:
+ * whole routine a loop, case Lcns do not fit below.
+ */
+ t16 = le16_to_cpu(lrh->lcns_follow);
+- for (i = 0; i < t16; i++) {
+- size_t j = (size_t)(le64_to_cpu(lrh->target_vcn) -
+- le64_to_cpu(dp->vcn));
+- dp->page_lcns[j + i] = lrh->page_lcns[i];
+- }
++ t32 = le32_to_cpu(dp->lcns_follow);
++ if (le64_to_cpu(lrh->target_vcn) < le64_to_cpu(dp->vcn)) {
++ err = -EINVAL;
++ goto out;
++ }
++
++ for (i = 0; i < t16; i++) {
++ size_t j = (size_t)(le64_to_cpu(lrh->target_vcn) -
++ le64_to_cpu(dp->vcn));
++ if (j >= t32 || i >= t32 - j) {
++ err = -EINVAL;
++ goto out;
++ }
++ dp->page_lcns[j + i] = lrh->page_lcns[i];
++ }
+
+ goto next_log_record_analyze;
+
--- /dev/null
+From 90f0109019e6817eb40a486671b7722d1544ae29 Mon Sep 17 00:00:00 2001
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Date: Wed, 17 Jun 2026 23:40:35 +0800
+Subject: gpio: eic-sprd: use raw_spinlock_t in the irq startup path
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+commit 90f0109019e6817eb40a486671b7722d1544ae29 upstream.
+
+sprd_eic_irq_unmask() enables the GPIO IRQ and then updates controller
+state through sprd_eic_update(), which takes sprd_eic->lock with
+spin_lock_irqsave(). The callback can be reached from irq_startup()
+while setting up a requested IRQ. That path is not sleepable, but on
+PREEMPT_RT a regular spinlock_t becomes a sleeping lock.
+
+This issue was found by our static analysis tool and then manually
+reviewed against the current tree.
+
+The grounded PoC kept the request_threaded_irq() -> __setup_irq() ->
+irq_startup() -> sprd_eic_irq_unmask() -> sprd_eic_update() carrier and
+used the original spin_lock_irqsave(&sprd_eic->lock) edge. Lockdep
+reported:
+
+ BUG: sleeping function called from invalid context
+ hardirqs last disabled at ... __setup_irq.constprop.0 ... [vuln_msv]
+ sprd_rt_spin_lock_irqsave+0x1c/0x30 [vuln_msv]
+ sprd_eic_update.constprop.0+0x48/0x90 [vuln_msv]
+ sprd_eic_irq_unmask.constprop.0+0x35/0x50 [vuln_msv]
+ __setup_irq.constprop.0+0xd/0x30 [vuln_msv]
+
+Convert the Spreadtrum EIC controller lock to raw_spinlock_t. The
+locked section only serializes MMIO register updates and does not contain
+sleepable operations, so keeping it non-sleeping is appropriate for the
+irqchip callbacks.
+
+Fixes: 25518e024e3a ("gpio: Add Spreadtrum EIC driver support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://patch.msgid.link/20260617154035.1199948-3-runyu.xiao@seu.edu.cn
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpio-eic-sprd.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpio/gpio-eic-sprd.c
++++ b/drivers/gpio/gpio-eic-sprd.c
+@@ -95,7 +95,7 @@ struct sprd_eic {
+ struct notifier_block irq_nb;
+ void __iomem *base[SPRD_EIC_MAX_BANK];
+ enum sprd_eic_type type;
+- spinlock_t lock;
++ raw_spinlock_t lock;
+ int irq;
+ };
+
+@@ -149,7 +149,7 @@ static void sprd_eic_update(struct gpio_
+ unsigned long flags;
+ u32 tmp;
+
+- spin_lock_irqsave(&sprd_eic->lock, flags);
++ raw_spin_lock_irqsave(&sprd_eic->lock, flags);
+ tmp = readl_relaxed(base + reg);
+
+ if (val)
+@@ -158,7 +158,7 @@ static void sprd_eic_update(struct gpio_
+ tmp &= ~BIT(SPRD_EIC_BIT(offset));
+
+ writel_relaxed(tmp, base + reg);
+- spin_unlock_irqrestore(&sprd_eic->lock, flags);
++ raw_spin_unlock_irqrestore(&sprd_eic->lock, flags);
+ }
+
+ static int sprd_eic_read(struct gpio_chip *chip, unsigned int offset, u16 reg)
+@@ -628,7 +628,7 @@ static int sprd_eic_probe(struct platfor
+ if (!sprd_eic)
+ return -ENOMEM;
+
+- spin_lock_init(&sprd_eic->lock);
++ raw_spin_lock_init(&sprd_eic->lock);
+ sprd_eic->type = pdata->type;
+
+ sprd_eic->irq = platform_get_irq(pdev, 0);
--- /dev/null
+From 286533cb14a3c8a8bd39ff64ea2fc8e1aa0f638b Mon Sep 17 00:00:00 2001
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Date: Wed, 17 Jun 2026 23:40:34 +0800
+Subject: gpio: sch: use raw_spinlock_t in the irq startup path
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+commit 286533cb14a3c8a8bd39ff64ea2fc8e1aa0f638b upstream.
+
+sch_irq_unmask() enables the GPIO IRQ and then updates the controller
+state through sch_irq_mask_unmask(), which takes sch->lock with
+spin_lock_irqsave(). The callback can be reached from irq_startup()
+while setting up a requested IRQ. That path is not sleepable, but on
+PREEMPT_RT a regular spinlock_t becomes a sleeping lock.
+
+This issue was found by our static analysis tool and then manually
+reviewed against the current tree.
+
+The grounded PoC kept the request_threaded_irq() -> __setup_irq() ->
+irq_startup() -> sch_irq_unmask() -> sch_irq_mask_unmask() carrier and
+used the original spin_lock_irqsave(&sch->lock) edge. Lockdep reported:
+
+ BUG: sleeping function called from invalid context
+ hardirqs last disabled at ... __setup_irq.constprop.0 ... [vuln_msv]
+ sch_rt_spin_lock_irqsave+0x1c/0x30 [vuln_msv]
+ sch_irq_mask_unmask.constprop.0+0x31/0x70 [vuln_msv]
+ __setup_irq.constprop.0+0xd/0x30 [vuln_msv]
+
+Convert the SCH controller lock to raw_spinlock_t. The same lock is
+also used by the GPIO direction and value callbacks, but those critical
+sections only update MMIO-backed GPIO registers and do not contain
+sleepable operations. Keeping this register lock non-sleeping is
+therefore appropriate for the irqchip callbacks and does not change the
+GPIO-side locking contract.
+
+Fixes: 7a81638485c1 ("gpio: sch: Add edge event support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Link: https://patch.msgid.link/20260617154035.1199948-2-runyu.xiao@seu.edu.cn
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpio-sch.c | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+--- a/drivers/gpio/gpio-sch.c
++++ b/drivers/gpio/gpio-sch.c
+@@ -39,7 +39,7 @@
+ struct sch_gpio {
+ struct gpio_chip chip;
+ void __iomem *regs;
+- spinlock_t lock;
++ raw_spinlock_t lock;
+ unsigned short resume_base;
+
+ /* GPE handling */
+@@ -104,9 +104,9 @@ static int sch_gpio_direction_in(struct
+ struct sch_gpio *sch = gpiochip_get_data(gc);
+ unsigned long flags;
+
+- spin_lock_irqsave(&sch->lock, flags);
++ raw_spin_lock_irqsave(&sch->lock, flags);
+ sch_gpio_reg_set(sch, gpio_num, GIO, 1);
+- spin_unlock_irqrestore(&sch->lock, flags);
++ raw_spin_unlock_irqrestore(&sch->lock, flags);
+ return 0;
+ }
+
+@@ -122,9 +122,9 @@ static int sch_gpio_set(struct gpio_chip
+ struct sch_gpio *sch = gpiochip_get_data(gc);
+ unsigned long flags;
+
+- spin_lock_irqsave(&sch->lock, flags);
++ raw_spin_lock_irqsave(&sch->lock, flags);
+ sch_gpio_reg_set(sch, gpio_num, GLV, val);
+- spin_unlock_irqrestore(&sch->lock, flags);
++ raw_spin_unlock_irqrestore(&sch->lock, flags);
+
+ return 0;
+ }
+@@ -135,9 +135,9 @@ static int sch_gpio_direction_out(struct
+ struct sch_gpio *sch = gpiochip_get_data(gc);
+ unsigned long flags;
+
+- spin_lock_irqsave(&sch->lock, flags);
++ raw_spin_lock_irqsave(&sch->lock, flags);
+ sch_gpio_reg_set(sch, gpio_num, GIO, 0);
+- spin_unlock_irqrestore(&sch->lock, flags);
++ raw_spin_unlock_irqrestore(&sch->lock, flags);
+
+ /*
+ * according to the datasheet, writing to the level register has no
+@@ -196,14 +196,14 @@ static int sch_irq_type(struct irq_data
+ return -EINVAL;
+ }
+
+- spin_lock_irqsave(&sch->lock, flags);
++ raw_spin_lock_irqsave(&sch->lock, flags);
+
+ sch_gpio_reg_set(sch, gpio_num, GTPE, rising);
+ sch_gpio_reg_set(sch, gpio_num, GTNE, falling);
+
+ irq_set_handler_locked(d, handle_edge_irq);
+
+- spin_unlock_irqrestore(&sch->lock, flags);
++ raw_spin_unlock_irqrestore(&sch->lock, flags);
+
+ return 0;
+ }
+@@ -215,9 +215,9 @@ static void sch_irq_ack(struct irq_data
+ irq_hw_number_t gpio_num = irqd_to_hwirq(d);
+ unsigned long flags;
+
+- spin_lock_irqsave(&sch->lock, flags);
++ raw_spin_lock_irqsave(&sch->lock, flags);
+ sch_gpio_reg_set(sch, gpio_num, GTS, 1);
+- spin_unlock_irqrestore(&sch->lock, flags);
++ raw_spin_unlock_irqrestore(&sch->lock, flags);
+ }
+
+ static void sch_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t gpio_num, int val)
+@@ -225,9 +225,9 @@ static void sch_irq_mask_unmask(struct g
+ struct sch_gpio *sch = gpiochip_get_data(gc);
+ unsigned long flags;
+
+- spin_lock_irqsave(&sch->lock, flags);
++ raw_spin_lock_irqsave(&sch->lock, flags);
+ sch_gpio_reg_set(sch, gpio_num, GGPE, val);
+- spin_unlock_irqrestore(&sch->lock, flags);
++ raw_spin_unlock_irqrestore(&sch->lock, flags);
+ }
+
+ static void sch_irq_mask(struct irq_data *d)
+@@ -268,12 +268,12 @@ static u32 sch_gpio_gpe_handler(acpi_han
+ int offset;
+ u32 ret;
+
+- spin_lock_irqsave(&sch->lock, flags);
++ raw_spin_lock_irqsave(&sch->lock, flags);
+
+ core_status = ioread32(sch->regs + CORE_BANK_OFFSET + GTS);
+ resume_status = ioread32(sch->regs + RESUME_BANK_OFFSET + GTS);
+
+- spin_unlock_irqrestore(&sch->lock, flags);
++ raw_spin_unlock_irqrestore(&sch->lock, flags);
+
+ pending = (resume_status << sch->resume_base) | core_status;
+ for_each_set_bit(offset, &pending, sch->chip.ngpio)
+@@ -343,7 +343,7 @@ static int sch_gpio_probe(struct platfor
+
+ sch->regs = regs;
+
+- spin_lock_init(&sch->lock);
++ raw_spin_lock_init(&sch->lock);
+ sch->chip = sch_gpio_chip;
+ sch->chip.label = dev_name(dev);
+ sch->chip.parent = dev;
--- /dev/null
+From 590cc4d782487632a52f37c2171bee1eeea29627 Mon Sep 17 00:00:00 2001
+From: HyeongJun An <sammiee5311@gmail.com>
+Date: Thu, 18 Jun 2026 15:37:37 +0900
+Subject: HID: logitech-dj: Fix maxfield check in DJ short report validation
+
+From: HyeongJun An <sammiee5311@gmail.com>
+
+commit 590cc4d782487632a52f37c2171bee1eeea29627 upstream.
+
+Commit b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT
+related user initiated OOB write") added validation for the DJ short
+output report, but the error path dereferences rep->field[0] even when
+rep->maxfield is zero.
+
+Commit 8b9a097eb2fc ("HID: logitech-dj: fix wrong detection of bad
+DJ_SHORT output report") made the check conditional on rep being present,
+but a crafted descriptor can still create report ID 0x20 with only padding
+output items. hid-core registers the report, ignores the padding field,
+and leaves rep->maxfield as zero.
+
+In that case the validation enters the rep->maxfield < 1 branch and then
+dereferences rep->field[0]->report_count while printing the error message,
+causing a NULL pointer dereference during probe. This is reproducible with
+uhid by emulating a Logitech receiver with a padding-only DJ short output
+report:
+
+ BUG: KASAN: null-ptr-deref in logi_dj_probe+0xb1/0x754 [hid_logitech_dj]
+ Read of size 4 at addr 0000000000000028 by task kworker/4:1/129
+ ...
+ Call Trace:
+ logi_dj_probe+0xb1/0x754 [hid_logitech_dj]
+ hid_device_probe+0x329/0x3f0 [hid]
+ really_probe+0x162/0x570
+ __device_attach+0x137/0x2c0
+ bus_probe_device+0x38/0xc0
+ device_add+0xa56/0xce0
+ hid_add_device+0x19c/0x280 [hid]
+ uhid_device_add_worker+0x2c/0xb0 [uhid]
+
+Reject the zero-field report before printing the field report_count.
+
+Fixes: b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-logitech-dj.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 381e4dc5aba7..9c574ab8b60b 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1907,8 +1907,13 @@ static int logi_dj_probe(struct hid_device *hdev,
+ output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+ rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+
+- if (rep && (rep->maxfield < 1 ||
+- rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1)) {
++ if (rep && rep->maxfield < 1) {
++ hid_err(hdev, "Expected size of DJ short report is %d, but got 0",
++ DJREPORT_SHORT_LENGTH - 1);
++ return -EINVAL;
++ }
++
++ if (rep && rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
+ hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
+ DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
+ return -EINVAL;
+--
+2.55.0
+
--- /dev/null
+From e3046eeada299f917a8ad883af4434bfb86556b1 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Sun, 31 May 2026 10:22:51 -0400
+Subject: hwrng: virtio: clamp device-reported used.len at copy_data()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit e3046eeada299f917a8ad883af4434bfb86556b1 upstream.
+
+random_recv_done() stores the device-reported used.len directly into
+vi->data_avail. copy_data() then indexes vi->data[] using
+vi->data_idx (advanced by previous copy_data() calls) and issues a
+memcpy() without re-validating either value against the posted
+buffer size sizeof(vi->data) (SMP_CACHE_BYTES bytes, typically 32
+or 64).
+
+A malicious or buggy virtio-rng backend can set used.len beyond
+sizeof(vi->data), steering the memcpy() past the end of the inline
+array into adjacent kmalloc-1k slab bytes. hwrng_fillfn() mixes
+those bytes into the guest RNG, and guest root can also observe
+them directly via /dev/hwrng.
+
+Concrete impact is inside the guest:
+
+ - Memory-safety / hardening: any virtio-rng backend that
+ over-reports used.len causes the driver to read past vi->data
+ into unrelated slab contents. hwrng_fillfn() is a kernel thread
+ that runs as soon as the device is probed; no guest userspace
+ interaction is required to first-trigger the OOB.
+
+ - Cross-boundary leak (confidential-compute threat model): a
+ malicious hypervisor cooperating with a malicious or compromised
+ guest root userspace can use /dev/hwrng as a leak channel for
+ guest-kernel heap data. The host sets a large used.len, guest
+ root reads /dev/hwrng, and the returned bytes contain guest
+ kernel slab contents that were adjacent to vi->data. In
+ practice, confidential-compute guests (SEV-SNP, TDX) usually
+ disable virtio-rng entirely, so this path is narrow, but the
+ fix is still worth carrying because the underlying
+ memory-safety bug contaminates the guest RNG on any host.
+
+KASAN confirms the OOB on a 7.1-rc4 guest whose virtio-rng backend
+has been patched to report used.len = 0x10000:
+
+ BUG: KASAN: slab-out-of-bounds in virtio_read+0x394/0x5d0
+ Read of size 64 at addr ffff88800ae0ba20 by task hwrng/52
+ Call Trace:
+ __asan_memcpy+0x23/0x60
+ virtio_read+0x394/0x5d0
+ hwrng_fillfn+0xb2/0x470
+ kthread+0x2cc/0x3a0
+ Allocated by task 1:
+ probe_common+0xa5/0x660
+ virtio_dev_probe+0x549/0xbc0
+ The buggy address belongs to the object at ffff88800ae0b800
+ which belongs to the cache kmalloc-1k of size 1024
+ The buggy address is located 0 bytes to the right of
+ allocated 544-byte region [ffff88800ae0b800, ffff88800ae0ba20)
+
+Same class of bug as commit c04db81cd028 ("net/9p: Fix buffer
+overflow in USB transport layer"), which hardened
+usb9pfs_rx_complete() against unchecked device-reported length in
+the USB 9p transport.
+
+With the clamp at point of use and array_index_nospec() in place,
+the same harness boots cleanly: copy_data() returns zero for the
+bogus report, the device-supplied bytes after data_idx are
+discarded, and the driver issues a fresh request.
+
+Fixes: f7f510ec1957 ("virtio: An entropy device, as suggested by hpa.")
+Cc: stable@vger.kernel.org
+Suggested-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-ID: <20260531142251.2792061-1-michael.bommarito@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/hw_random/virtio-rng.c | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/hw_random/virtio-rng.c
++++ b/drivers/char/hw_random/virtio-rng.c
+@@ -7,6 +7,7 @@
+ #include <asm/barrier.h>
+ #include <linux/err.h>
+ #include <linux/hw_random.h>
++#include <linux/nospec.h>
+ #include <linux/scatterlist.h>
+ #include <linux/spinlock.h>
+ #include <linux/virtio.h>
+@@ -69,8 +70,26 @@ static void request_entropy(struct virtr
+ static unsigned int copy_data(struct virtrng_info *vi, void *buf,
+ unsigned int size)
+ {
+- size = min_t(unsigned int, size, vi->data_avail);
+- memcpy(buf, vi->data + vi->data_idx, size);
++ unsigned int idx, avail;
++
++ /*
++ * vi->data_avail was set from the device-reported used.len and
++ * vi->data_idx was advanced by previous copy_data() calls. A
++ * malicious or buggy virtio-rng backend can drive either past
++ * sizeof(vi->data). Clamp at point of use and harden the index
++ * with array_index_nospec() so the memcpy() below cannot be
++ * steered into adjacent slab memory, including under
++ * speculation.
++ */
++ avail = min_t(unsigned int, vi->data_avail, sizeof(vi->data));
++ if (vi->data_idx >= avail) {
++ vi->data_avail = 0;
++ request_entropy(vi);
++ return 0;
++ }
++ size = min_t(unsigned int, size, avail - vi->data_idx);
++ idx = array_index_nospec(vi->data_idx, sizeof(vi->data));
++ memcpy(buf, vi->data + idx, size);
+ vi->data_idx += size;
+ vi->data_avail -= size;
+ if (vi->data_avail == 0)
--- /dev/null
+From 29bef9934b2521f787bb15dd1985d4c0d12ae02a Mon Sep 17 00:00:00 2001
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Date: Thu, 28 May 2026 01:22:03 +0800
+Subject: io_uring/io-wq: re-check IO_WQ_BIT_EXIT for each linked work item
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+commit 29bef9934b2521f787bb15dd1985d4c0d12ae02a upstream.
+
+commit 10dc95939817 ("io_uring/io-wq: check IO_WQ_BIT_EXIT inside work
+run loop") fixed the obvious case where io_worker_handle_work() took one
+exit-bit snapshot before draining pending work, but the fix stops one
+level too early.
+
+io_worker_handle_work() now re-checks IO_WQ_BIT_EXIT in its outer work
+run loop, yet it still snapshots that bit once before processing a whole
+dependent linked-work chain. If io_wq_exit_start() sets IO_WQ_BIT_EXIT
+after the first linked item has started, the remaining linked items can
+still reuse stale do_kill = false, skip IO_WQ_WORK_CANCEL, and continue
+running after exit has begun.
+
+Move the check further inside, so it covers linked items too. Note: this
+is a syzbot special as it loves setting up tons of slow linked work on
+weird devices like msr that take forever to read, and immediately close
+the ring. Exit then takes a long time.
+
+Fixes: 10dc95939817 ("io_uring/io-wq: check IO_WQ_BIT_EXIT inside work run loop")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Link: https://patch.msgid.link/20260527172203.2043962-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/io-wq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -602,7 +602,6 @@ static void io_worker_handle_work(struct
+ struct io_wq *wq = worker->wq;
+
+ do {
+- bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
+ struct io_wq_work *work;
+
+ /*
+@@ -638,6 +637,7 @@ static void io_worker_handle_work(struct
+
+ /* handle a whole dependent link */
+ do {
++ bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
+ struct io_wq_work *next_hashed, *linked;
+ unsigned int work_flags = atomic_read(&work->flags);
+ unsigned int hash = __io_wq_is_hashed(work_flags)
--- /dev/null
+From 2564ca2e31bd8ee8348362941af2ee4671e487ca Mon Sep 17 00:00:00 2001
+From: Vasileios Almpanis <vasilisalmpanis@gmail.com>
+Date: Mon, 15 Jun 2026 16:45:57 +0200
+Subject: io_uring/nop: fix file reference leak with IOSQE_FIXED_FILE
+
+From: Vasileios Almpanis <vasilisalmpanis@gmail.com>
+
+commit 2564ca2e31bd8ee8348362941af2ee4671e487ca upstream.
+
+NOP file-acquisition support choses between a fixed (registered) file and
+a normal fget()'d file based on its own IORING_NOP_FIXED_FILE flag in
+sqe->nop_flags. However, a request's REQ_F_FIXED_FILE is set
+independently from the generic IOSQE_FIXED_FILE sqe flag during request
+init, before the issue handler runs.
+
+If a NOP is submitted with IOSQE_FIXED_FILE set (so REQ_F_FIXED_FILE is
+set) but without IORING_NOP_FIXED_FILE, io_nop() takes the normal path
+and grabs a real reference via io_file_get_normal(). On completion,
+io_put_file() only drops the reference when REQ_F_FIXED_FILE is clear,
+so the fget()'d file is never released and leaks:
+
+ BUG: memory leak
+ unreferenced object 0xffff88800f42c240 (size 176):
+ kmem_cache_alloc_noprof+0x358/0x440
+ alloc_empty_file+0x57/0x180
+ path_openat+0x44/0x1e50
+ do_file_open+0x121/0x200
+ do_sys_openat2+0xa7/0x150
+ __x64_sys_openat+0x82/0xf0
+
+Decide between fixed and normal file acquisition from REQ_F_FIXED_FILE,
+the same way io_assign_file() does for every other opcode, and fold
+IORING_NOP_FIXED_FILE into REQ_F_FIXED_FILE at prep time.
+
+Cc: stable@vger.kernel.org
+Fixes: a85f31052bce ("io_uring/nop: add support for testing registered files and buffers")
+Reported-by: syzbot+2cd473471e77bda12b0e@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?id=879092631b98f73a28ea405adacfa5bb34a14a25
+Signed-off-by: Vasileios Almpanis <vasilisalmpanis@gmail.com>
+Link: https://patch.msgid.link/20260615144619.482749-1-vasilisalmpanis@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/nop.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/io_uring/nop.c
++++ b/io_uring/nop.c
+@@ -41,6 +41,8 @@ int io_nop_prep(struct io_kiocb *req, co
+ nop->fd = READ_ONCE(sqe->fd);
+ else
+ nop->fd = -1;
++ if (nop->flags & IORING_NOP_FIXED_FILE)
++ req->flags |= REQ_F_FIXED_FILE;
+ if (nop->flags & IORING_NOP_FIXED_BUFFER)
+ req->buf_index = READ_ONCE(sqe->buf_index);
+ if (nop->flags & IORING_NOP_CQE32) {
+@@ -60,12 +62,10 @@ int io_nop(struct io_kiocb *req, unsigne
+ int ret = nop->result;
+
+ if (nop->flags & IORING_NOP_FILE) {
+- if (nop->flags & IORING_NOP_FIXED_FILE) {
++ if (req->flags & REQ_F_FIXED_FILE)
+ req->file = io_file_get_fixed(req, nop->fd, issue_flags);
+- req->flags |= REQ_F_FIXED_FILE;
+- } else {
++ else
+ req->file = io_file_get_normal(req, nop->fd);
+- }
+ if (!req->file) {
+ ret = -EBADF;
+ goto done;
--- /dev/null
+From c554246ff4c68abf71b61a89c6e39d3cf94f523e Mon Sep 17 00:00:00 2001
+From: Michael Wigham <michael@wigham.net>
+Date: Sat, 13 Jun 2026 23:52:16 +0100
+Subject: io_uring/rw: preserve partial result for iopoll
+
+From: Michael Wigham <michael@wigham.net>
+
+commit c554246ff4c68abf71b61a89c6e39d3cf94f523e upstream.
+
+A partial read will store the completed byte count in io->bytes_done.
+The regular completion path applies io_fixup_rw_res() so that, when the
+following operation reaches EOF, the number of bytes already read is
+returned.
+
+The iopoll completion path does not apply this fixup to the return value
+and can return zero instead.
+
+Use the fixup result when updating the CQE, and the raw result for the
+reissue check.
+
+Cc: stable@vger.kernel.org
+Fixes: 4d9cb92ca41d ("io_uring/rw: fix short rw error handling")
+Signed-off-by: Michael Wigham <michael@wigham.net>
+Link: https://patch.msgid.link/20260613225240.34032-1-michael@wigham.net
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/rw.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/io_uring/rw.c
++++ b/io_uring/rw.c
+@@ -601,15 +601,15 @@ static void io_complete_rw_iopoll(struct
+ {
+ struct io_rw *rw = container_of(kiocb, struct io_rw, kiocb);
+ struct io_kiocb *req = cmd_to_io_kiocb(rw);
++ int final_res = io_fixup_rw_res(req, res);
+
+ if (kiocb->ki_flags & IOCB_WRITE)
+ io_req_end_write(req);
+- if (unlikely(res != req->cqe.res)) {
+- if (res == -EAGAIN && io_rw_should_reissue(req))
+- req->flags |= REQ_F_REISSUE | REQ_F_BL_NO_RECYCLE;
+- else
+- req->cqe.res = res;
+- }
++
++ if (res == -EAGAIN && io_rw_should_reissue(req))
++ req->flags |= REQ_F_REISSUE | REQ_F_BL_NO_RECYCLE;
++ else if (unlikely(final_res != req->cqe.res))
++ req->cqe.res = final_res;
+
+ /* order with io_iopoll_complete() checking ->iopoll_completed */
+ smp_store_release(&req->iopoll_completed, 1);
--- /dev/null
+From 7993211bde166471dffac074dc965489f86531f8 Mon Sep 17 00:00:00 2001
+From: Yuyang Huang <yuyanghuang@google.com>
+Date: Thu, 2 Jul 2026 08:50:14 +0900
+Subject: ipv4: igmp: remove multicast group from hash table on device destruction
+
+From: Yuyang Huang <yuyanghuang@google.com>
+
+commit 7993211bde166471dffac074dc965489f86531f8 upstream.
+
+When a device is destroyed under RTNL, ip_mc_destroy_dev() iterates through
+the multicast list and calls ip_ma_put() on each membership, scheduling
+them for RCU reclamation. However, they are not unlinked from the device's
+multicast hash table (mc_hash).
+
+Since the device remains published in dev->ip_ptr until after
+ip_mc_destroy_dev() completes, concurrent RCU readers traversing mc_hash
+can still locate and access the multicast group after its refcount is
+decremented. If the RCU callback runs and frees the group while a reader is
+accessing it, a use-after-free occurs.
+
+Fix this by unlinking the multicast group from mc_hash using
+ip_mc_hash_remove() before scheduling it for reclamation.
+
+BUG: KASAN: slab-use-after-free in ip_check_mc_rcu+0x149/0x3f0
+Read of size 4 at addr ffff888009bf1408 by task mausezahn/2276
+
+Call Trace:
+ <IRQ>
+ dump_stack_lvl+0x67/0x90
+ print_report+0x175/0x7c0
+ kasan_report+0x147/0x180
+ ip_check_mc_rcu+0x149/0x3f0
+ udp_v4_early_demux+0x36d/0x12d0
+ ip_rcv_finish_core+0xb8b/0x1390
+ ip_rcv_finish+0x54/0x120
+ NF_HOOK+0x213/0x2b0
+ __netif_receive_skb+0x126/0x340
+ process_backlog+0x4f2/0xf00
+ __napi_poll+0x92/0x2c0
+ net_rx_action+0x583/0xc60
+ handle_softirqs+0x236/0x7f0
+ do_softirq+0x57/0x80
+ </IRQ>
+
+Allocated by task 2239:
+ kasan_save_track+0x3e/0x80
+ __kasan_kmalloc+0x72/0x90
+ ____ip_mc_inc_group+0x31a/0xa40
+ __ip_mc_join_group+0x334/0x3f0
+ do_ip_setsockopt+0x16fa/0x2010
+ ip_setsockopt+0x3f/0x90
+ do_sock_setsockopt+0x1ad/0x300
+
+Freed by task 0:
+ kasan_save_track+0x3e/0x80
+ kasan_save_free_info+0x40/0x50
+ __kasan_slab_free+0x3a/0x60
+ __rcu_free_sheaf_prepare+0xd4/0x220
+ rcu_free_sheaf+0x36/0x190
+ rcu_core+0x8d9/0x12f0
+ handle_softirqs+0x236/0x7f0
+
+Fixes: e9897071350b ("igmp: hash a hash table to speedup ip_check_mc_rcu()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260701235014.73505-1-yuyanghuang@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/igmp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -1918,6 +1918,7 @@ void ip_mc_destroy_dev(struct in_device
+ #endif
+
+ while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) {
++ ip_mc_hash_remove(in_dev, i);
+ in_dev->mc_list = i->next_rcu;
+ in_dev->mc_count--;
+ ip_mc_clear_src(i);
--- /dev/null
+From 10f293a07f9e10e988b0ae44e2e99c631f5a68e0 Mon Sep 17 00:00:00 2001
+From: Gil Portnoy <dddhkts1@gmail.com>
+Date: Wed, 10 Jun 2026 19:53:14 +0900
+Subject: ksmbd: fix use-after-free of a deferred file_lock on SMB2_CLOSE then SMB2_CANCEL
+
+From: Gil Portnoy <dddhkts1@gmail.com>
+
+commit 10f293a07f9e10e988b0ae44e2e99c631f5a68e0 upstream.
+
+Commit f580d27e8928 ("ksmbd: fix use-after-free of a deferred file_lock on
+double SMB2_CANCEL") made smb2_cancel() skip a work whose state is
+KSMBD_WORK_CANCELLED, so its cancel_fn cannot be fired a second time. But
+KSMBD_WORK has three states (ACTIVE, CANCELLED, CLOSED), and the same
+freeing producer path is reached for CLOSED too:
+
+ SMB2_CLOSE on the locking handle -> set_close_state_blocked_works() sets
+ the deferred work's state to KSMBD_WORK_CLOSED and wakes the smb2_lock()
+ worker. The worker takes the non-ACTIVE early-exit, locks_free_lock()s
+ the file_lock and, because the state is not KSMBD_WORK_CANCELLED, takes
+ the STATUS_RANGE_NOT_LOCKED branch with "goto out2" -- which, like the
+ cancelled branch, skips release_async_work(). The work stays on
+ conn->async_requests with a live cancel_fn = smb2_remove_blocked_lock
+ pointing at the freed file_lock.
+
+A subsequent SMB2_CANCEL for the same AsyncId then passes the
+KSMBD_WORK_CANCELLED-only guard (its state is KSMBD_WORK_CLOSED), so
+smb2_cancel() fires cancel_fn again over the freed file_lock -- the same
+use-after-free fixed, via SMB2_CLOSE instead of a first SMB2_CANCEL:
+
+ BUG: KASAN: slab-use-after-free in __locks_delete_block
+ __locks_delete_block
+ locks_delete_block
+ ksmbd_vfs_posix_lock_unblock
+ smb2_remove_blocked_lock
+ smb2_cancel <- 2nd SMB2_CANCEL fires cancel_fn
+ handle_ksmbd_work
+ Allocated by ...: locks_alloc_lock <- smb2_lock
+ Freed by ...: locks_free_lock <- smb2_lock (non-ACTIVE early-exit)
+ ... cache file_lock_cache of size 192
+
+Reproduced on mainline 7.1-rc7 (which already contains f580d27e8928) with
+KASAN by an authenticated SMB client; the double-SMB2_CANCEL control is
+silent on that kernel, so the splat is attributable to the CLOSE trigger.
+
+Only an ACTIVE deferred work may have its cancel_fn fired: both terminal
+states (CANCELLED and CLOSED) reach the smb2_lock() early-exit that frees
+the file_lock and skips release_async_work(). Guard on KSMBD_WORK_ACTIVE
+so any non-active work is skipped.
+
+Fixes: f580d27e8928 ("ksmbd: fix use-after-free of a deferred file_lock on double SMB2_CANCEL")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gil Portnoy <dddhkts1@gmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/smb2pdu.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -7328,14 +7328,14 @@ int smb2_cancel(struct ksmbd_work *work)
+ continue;
+
+ /*
+- * A cancelled deferred byte-range lock frees its
+- * file_lock and takes the smb2_lock() early-exit that
+- * skips release_async_work(), so the work stays on
+- * conn->async_requests with a live cancel_fn pointing
+- * at the freed file_lock. Re-firing it on a second
+- * SMB2_CANCEL is a use-after-free.
++ * Only an ACTIVE deferred work may have its cancel_fn
++ * fired. A CANCELLED or CLOSED work already took the
++ * smb2_lock() non-ACTIVE early-exit that frees the
++ * file_lock and skips release_async_work(), so it is
++ * still on conn->async_requests with a live cancel_fn
++ * pointing at the freed file_lock.
+ */
+- if (iter->state == KSMBD_WORK_CANCELLED)
++ if (iter->state != KSMBD_WORK_ACTIVE)
+ break;
+
+ ksmbd_debug(SMB,
--- /dev/null
+From b670bf89824ede5d07d20bb9bfbafb754846081d Mon Sep 17 00:00:00 2001
+From: Xiaolei Wang <xiaolei.wang@windriver.com>
+Date: Thu, 7 May 2026 12:13:15 +0800
+Subject: media: nxp: imx8-isi: Fix use-after-free on remove
+
+From: Xiaolei Wang <xiaolei.wang@windriver.com>
+
+commit b670bf89824ede5d07d20bb9bfbafb754846081d upstream.
+
+KASAN reports a slab-use-after-free in __media_entity_remove_link()
+during rmmod of imx8_isi:
+
+ BUG: KASAN: slab-use-after-free in __media_entity_remove_link+0x608/0x650
+ Read of size 2 at addr ffff0000d47cb02a by task rmmod/724
+
+ Call trace:
+ __media_entity_remove_link+0x608/0x650
+ __media_entity_remove_links+0x78/0x144
+ __media_device_unregister_entity+0x150/0x280
+ media_device_unregister_entity+0x48/0x68
+ v4l2_device_unregister_subdev+0x158/0x300
+ v4l2_async_unbind_subdev_one+0x22c/0x358
+ v4l2_async_nf_unbind_all_subdevs+0xfc/0x1c0
+ v4l2_async_nf_unregister+0x5c/0x14c
+ mxc_isi_remove+0x124/0x2a0 [imx8_isi]
+
+ Allocated by task 249:
+ __kmalloc_noprof+0x27c/0x690
+ mxc_isi_crossbar_init+0x22c/0x560 [imx8_isi]
+
+ Freed by task 724:
+ kfree+0x1e4/0x5b0
+ mxc_isi_crossbar_cleanup+0x34/0x80 [imx8_isi]
+ mxc_isi_remove+0x11c/0x2a0 [imx8_isi]
+
+The problem is that mxc_isi_remove() calls mxc_isi_crossbar_cleanup()
+before mxc_isi_v4l2_cleanup(). The crossbar cleanup frees the media
+entity pads, but the subsequent v4l2 cleanup still tries to remove
+media links that reference those pads.
+
+Fix this by calling mxc_isi_v4l2_cleanup() before
+mxc_isi_crossbar_cleanup() to ensure all media entities are properly
+unregistered while the pads are still valid.
+
+Fixes: cf21f328fcaf ("media: nxp: Add i.MX8 ISI driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Link: https://patch.msgid.link/20260507041318.491594-2-xiaolei.wang@windriver.com
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
++++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
+@@ -556,8 +556,8 @@ static void mxc_isi_remove(struct platfo
+ mxc_isi_pipe_cleanup(pipe);
+ }
+
+- mxc_isi_crossbar_cleanup(&isi->crossbar);
+ mxc_isi_v4l2_cleanup(isi);
++ mxc_isi_crossbar_cleanup(&isi->crossbar);
+ }
+
+ static const struct of_device_id mxc_isi_of_match[] = {
--- /dev/null
+From c32fe4c4918c9aa49f61359e3b42619c4d8686de Mon Sep 17 00:00:00 2001
+From: Ricardo Ribalda <ribalda@chromium.org>
+Date: Thu, 7 May 2026 20:58:10 +0000
+Subject: media: staging: ipu3-imgu: Add range check for imgu_css_cfg_acc_stripe
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+commit c32fe4c4918c9aa49f61359e3b42619c4d8686de upstream.
+
+If the driver's stripe information is invalid it can result in an integer
+underflow. Add a range check to avoid this kind of error.
+
+This patch fixes the following smatch error:
+drivers/staging/media/ipu3/ipu3-css-params.c:1792 imgu_css_cfg_acc_stripe() warn: 'acc->stripe.bds_out_stripes[0]->width - 2 * f' 4294967168 can't fit into 65535 'acc->stripe.bds_out_stripes[1]->offset'
+
+Cc: stable@vger.kernel.org
+Fixes: e11110a5b744 ("media: staging/intel-ipu3: css: Compute and program ccs")
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/ipu3/ipu3-css-params.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/media/ipu3/ipu3-css-params.c
++++ b/drivers/staging/media/ipu3/ipu3-css-params.c
+@@ -1770,6 +1770,8 @@ static int imgu_css_cfg_acc_stripe(struc
+ acc->stripe.bds_out_stripes[0].width =
+ ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width, f);
+ } else {
++ u32 offset;
++
+ /* Image processing is divided into two stripes */
+ acc->stripe.bds_out_stripes[0].width =
+ acc->stripe.bds_out_stripes[1].width =
+@@ -1788,8 +1790,10 @@ static int imgu_css_cfg_acc_stripe(struc
+ acc->stripe.bds_out_stripes[1].width += f;
+ }
+ /* Overlap between stripes is IPU3_UAPI_ISP_VEC_ELEMS * 4 */
+- acc->stripe.bds_out_stripes[1].offset =
+- acc->stripe.bds_out_stripes[0].width - 2 * f;
++ offset = acc->stripe.bds_out_stripes[0].width - 2 * f;
++ if (offset > 65535)
++ return -EINVAL;
++ acc->stripe.bds_out_stripes[1].offset = offset;
+ }
+
+ acc->stripe.effective_stripes[0].height =
--- /dev/null
+From 8b2c1d41bc36c100b38ce5ee6def246c527eaf8a Mon Sep 17 00:00:00 2001
+From: Andrei Kuchynski <akuchynski@chromium.org>
+Date: Mon, 27 Apr 2026 13:17:21 +0000
+Subject: mfd: cros_ec: Delay dev_set_drvdata() until probe success
+
+From: Andrei Kuchynski <akuchynski@chromium.org>
+
+commit 8b2c1d41bc36c100b38ce5ee6def246c527eaf8a upstream.
+
+If ec_device_probe() fails, cros_ec_class_release releases memory for the
+cros_ec_dev structure. However, because the drvdata was already set,
+sub-drivers like cros_ec_typec can still retrieve the stale pointer via the
+platform device. This leads to a use-after-free when cros_ec_typec attempts
+to access &typec->ec->ec->dev on a device that has already been released.
+Move dev_set_drvdata() to ensure that the pointer is only made available
+once all initialization steps have succeeded.
+
+ sysfs: cannot create duplicate filename '/class/chromeos/cros_ec'
+ Call trace:
+ sysfs_do_create_link_sd+0x94/0xdc
+ sysfs_create_link+0x30/0x44
+ device_add_class_symlinks+0x90/0x13c
+ device_add+0xf0/0x50c
+ ec_device_probe+0x150/0x4f0
+ platform_probe+0xa0/0xe0
+ ...
+ BUG: KASAN: invalid-access in __memcpy+0x44/0x230
+ Write at addr f5ffff809e2d33ac by task kworker/u32:5/125
+ Pointer tag: [f5], memory tag: [fe]
+ Tainted : [W]=WARN, [O]=OOT_MODULE
+ Hardware name: Google Navi unprovisioned 0x7FFFFFFF/sku0 board/sku3
+ Workqueue: events_unbound deferred_probe_work_func
+ Call trace:
+ __memcpy+0x44/0x230
+ cros_ec_check_features+0x60/0xcc [cros_ec_proto]
+ cros_typec_probe+0xe8/0x6e0 [cros_ec_typec]
+ platform_probe+0xa0/0xe0
+
+Cc: stable@vger.kernel.org
+Fixes: 1c1d152cc5ac ("platform/chrome: cros_ec_dev - utilize new cdev_device_add helper function")
+Co-developed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Link: https://patch.msgid.link/20260427131721.1165078-1-akuchynski@chromium.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mfd/cros_ec_dev.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/mfd/cros_ec_dev.c
++++ b/drivers/mfd/cros_ec_dev.c
+@@ -195,7 +195,6 @@ static int ec_device_probe(struct platfo
+ if (!ec)
+ return retval;
+
+- dev_set_drvdata(dev, ec);
+ ec->ec_dev = dev_get_drvdata(dev->parent);
+ ec->dev = dev;
+ ec->cmd_offset = ec_platform->cmd_offset;
+@@ -237,6 +236,8 @@ static int ec_device_probe(struct platfo
+ if (retval)
+ goto failed;
+
++ dev_set_drvdata(dev, ec);
++
+ /* check whether this EC is a sensor hub. */
+ if (cros_ec_get_sensor_count(ec) > 0) {
+ retval = mfd_add_hotplug_devices(ec->dev,
--- /dev/null
+From 35d4a3cf70a855b50e53189ac2f8463e20a02046 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sj@kernel.org>
+Date: Tue, 23 Jun 2026 06:58:31 -0700
+Subject: mm/damon/ops-common: handle extreme intervals in damon_hot_score()
+
+From: SeongJae Park <sj@kernel.org>
+
+commit 35d4a3cf70a855b50e53189ac2f8463e20a02046 upstream.
+
+Fix three issues in damon_hot_score() that comes from wrong handling of
+extreme (zero or too high) monitoring intervals user setup.
+
+When the user sets sampling interval zero, damon_max_nr_accesses(), which
+is called from damon_hot_score(), causes a divide-by-zero. Needless to
+say, it is a problem.
+
+When the user sets the aggregation interval zero, the function returns
+zero. It is wrong, since the real maximum nr_acceses in the setup should
+be one. Worse yet, it can cause another divide-by-zero from its caller,
+damon_hot_score(), since it uses damon_max_nr_accesses() return value as a
+denominator.
+
+When the user sets the aggregation interval very high, damon_hot_score()
+could return a value out of [0, DAMOS_MAX_SCORE] range. Since the return
+value is used as an index to the regions_score_histogram array, which is
+DAMOS_MAX_SCORE+1 size, it causes out of bounds array access.
+
+The issues can be relatively easily reproduced like below. The sysfs
+write permission is required, though.
+
+ # ./damo start --damos_action lru_prio --damos_quota_space 100M \
+ --damos_quota_interval 1s
+ # cd /sys/kernel/mm/damon/admin/kdamonds/0
+ # echo 0 > contexts/0/monitoring_attrs/intervals/sample_us
+ # echo 0 > contexts/0/monitoring_attrs/intervals/aggr_us
+ # echo commit > state
+ # dmesg
+ [...]
+ [ 131.329762] Oops: divide error: 0000 [#1] SMP NOPTI
+ [...]
+ [ 131.336089] RIP: 0010:damon_hot_score+0x27/0xd0
+ [...]
+
+Fix the divide-by-zero intervals problems by explicitly handling the zero
+intervals in damon_max_nr_accesses(). Fix the out-of-bound array access
+by applying [0, DAMOS_MAX_SCORE] bounds before returning from
+damon_hot_score().
+
+The issue was discovered [1] by Sashiko.
+
+Link: https://lore.kernel.org/20260623135834.67189-1-sj@kernel.org
+Link: https://lore.kernel.org/20260619202459.145010-1-sj@kernel.org [1]
+Fixes: 198f0f4c58b9 ("mm/damon/vaddr,paddr: support pageout prioritization")
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 5.16.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/damon.h | 8 ++++++--
+ mm/damon/ops-common.c | 1 +
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/include/linux/damon.h
++++ b/include/linux/damon.h
+@@ -979,9 +979,13 @@ static inline bool damon_target_has_pid(
+
+ static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs)
+ {
+- /* {aggr,sample}_interval are unsigned long, hence could overflow */
+- return min(attrs->aggr_interval / attrs->sample_interval,
++ unsigned long sample_interval;
++ unsigned long max_nr_accesses;
++
++ sample_interval = attrs->sample_interval ? : 1;
++ max_nr_accesses = min(attrs->aggr_interval / sample_interval,
+ (unsigned long)UINT_MAX);
++ return max_nr_accesses ? : 1;
+ }
+
+
+--- a/mm/damon/ops-common.c
++++ b/mm/damon/ops-common.c
+@@ -140,6 +140,7 @@ int damon_hot_score(struct damon_ctx *c,
+ * Transform it to fit in [0, DAMOS_MAX_SCORE]
+ */
+ hotness = hotness * DAMOS_MAX_SCORE / DAMON_MAX_SUBSCORE;
++ hotness = max(min(hotness, DAMOS_MAX_SCORE), 0);
+
+ return hotness;
+ }
--- /dev/null
+From b902890c62d200b3509cb5e09cf1e0a66553c128 Mon Sep 17 00:00:00 2001
+From: Shakeel Butt <shakeel.butt@linux.dev>
+Date: Wed, 10 Jun 2026 16:20:48 -0700
+Subject: mm/shrinker: do not hold RCU lock in shrinker_debugfs_count_show()
+
+From: Shakeel Butt <shakeel.butt@linux.dev>
+
+commit b902890c62d200b3509cb5e09cf1e0a66553c128 upstream.
+
+Reading the debugfs "count" file of a memcg-aware shrinker can sleep
+inside an RCU read-side critical section:
+
+ BUG: sleeping function called from invalid context at kernel/cgroup/rstat.c:421
+ RCU nest depth: 1, expected: 0
+ css_rstat_flush
+ mem_cgroup_flush_stats
+ zswap_shrinker_count
+ shrinker_debugfs_count_show
+
+shrinker_debugfs_count_show() invokes the ->count_objects() callback under
+rcu_read_lock(). The zswap callback flushes memcg stats via
+css_rstat_flush(), which may sleep, so it must not run under RCU.
+
+The RCU lock is not needed here. mem_cgroup_iter() takes RCU internally
+and returns a memcg holding a css reference (dropped on the next iteration
+or by mem_cgroup_iter_break()), so the memcg stays alive without it. The
+shrinker is kept alive by the open debugfs file: shrinker_free() removes
+the debugfs entries via debugfs_remove_recursive(), which waits for
+in-flight readers to drain, before call_rcu(..., shrinker_free_rcu_cb).
+The sibling "scan" handler already invokes the sleeping ->scan_objects()
+callback with no RCU section.
+
+Drop the rcu_read_lock()/rcu_read_unlock().
+
+Link: https://lore.kernel.org/20260610232048.62930-1-shakeel.butt@linux.dev
+Fixes: 5035ebc644ae ("mm: shrinkers: introduce debugfs interface for memory shrinkers")
+Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
+Reported-by: Zenghui Yu <zenghui.yu@linux.dev>
+Closes: https://lore.kernel.org/all/c052a064-cddb-494f-a0d8-f8a10b4b1c4d@linux.dev/
+Suggested-by: Nhat Pham <nphamcs@gmail.com>
+Reviewed-by: SeongJae Park <sj@kernel.org>
+Reviewed-by: Qi Zheng <qi.zheng@linux.dev>
+Tested-by: Zenghui Yu (Huawei) <zenghui.yu@linux.dev>
+Reviewed-by: Nhat Pham <nphamcs@gmail.com>
+Acked-by: Muchun Song <muchun.song@linux.dev>
+Reviewed-by: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/shrinker_debug.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/mm/shrinker_debug.c
++++ b/mm/shrinker_debug.c
+@@ -57,8 +57,6 @@ static int shrinker_debugfs_count_show(s
+ if (!count_per_node)
+ return -ENOMEM;
+
+- rcu_read_lock();
+-
+ memcg_aware = shrinker->flags & SHRINKER_MEMCG_AWARE;
+
+ memcg = mem_cgroup_iter(NULL, NULL, NULL);
+@@ -88,8 +86,6 @@ static int shrinker_debugfs_count_show(s
+ }
+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
+
+- rcu_read_unlock();
+-
+ kfree(count_per_node);
+ return ret;
+ }
--- /dev/null
+From e30453c61e185e914fde83c650e268067b140218 Mon Sep 17 00:00:00 2001
+From: Qi Zheng <zhengqi.arch@bytedance.com>
+Date: Wed, 17 Jun 2026 17:00:52 +0800
+Subject: mm: shrinker: fix NULL pointer dereference in debugfs
+
+From: Qi Zheng <zhengqi.arch@bytedance.com>
+
+commit e30453c61e185e914fde83c650e268067b140218 upstream.
+
+shrinker_debugfs_add() creates both "count" and "scan" debugfs files
+unconditionally.
+
+That assumes every shrinker implements both count_objects() and
+scan_objects(), which is not guaranteed. For example, the xen-backend
+shrinker sets count_objects() but leaves scan_objects() NULL, so writing
+to its scan file calls through a NULL function pointer and panics the
+kernel:
+
+BUG: kernel NULL pointer dereference, address: 0000000000000000
+RIP: 0010:0x0
+Code: Unable to access opcode bytes at 0xffffffffffffffd6.
+Call Trace:
+ <TASK>
+ shrinker_debugfs_scan_write+0x12e/0x270
+ full_proxy_write+0x5f/0x90
+ vfs_write+0xde/0x420
+ ? filp_flush+0x75/0x90
+ ? filp_close+0x1d/0x30
+ ? do_dup2+0xb8/0x120
+ ksys_write+0x68/0xf0
+ ? filp_flush+0x75/0x90
+ do_syscall_64+0xb3/0x5b0
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+The count path has the same issue in principle if a shrinker omits
+count_objects().
+
+To fix it, only create "count" and "scan" debugfs files when the
+corresponding callbacks are present.
+
+Link: https://lore.kernel.org/20260617090052.27325-1-qi.zheng@linux.dev
+Fixes: bbf535fd6f06 ("mm: shrinkers: add scan interface for shrinker debugfs")
+Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
+Reviewed-by: Muchun Song <muchun.song@linux.dev>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Qi Zheng <zhengqi.arch@bytedance.com>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/shrinker_debug.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/mm/shrinker_debug.c
++++ b/mm/shrinker_debug.c
+@@ -183,10 +183,12 @@ int shrinker_debugfs_add(struct shrinker
+ }
+ shrinker->debugfs_entry = entry;
+
+- debugfs_create_file("count", 0440, entry, shrinker,
+- &shrinker_debugfs_count_fops);
+- debugfs_create_file("scan", 0220, entry, shrinker,
+- &shrinker_debugfs_scan_fops);
++ if (shrinker->count_objects)
++ debugfs_create_file("count", 0440, entry, shrinker,
++ &shrinker_debugfs_count_fops);
++ if (shrinker->scan_objects)
++ debugfs_create_file("scan", 0220, entry, shrinker,
++ &shrinker_debugfs_scan_fops);
+ return 0;
+ }
+
--- /dev/null
+From 65476d31d8056e859c48580f82295ce159196ffe Mon Sep 17 00:00:00 2001
+From: Qi Zheng <zhengqi.arch@bytedance.com>
+Date: Wed, 17 Jun 2026 16:56:58 +0800
+Subject: mm: shrinker: fix shrinker_info teardown race with expansion
+
+From: Qi Zheng <zhengqi.arch@bytedance.com>
+
+commit 65476d31d8056e859c48580f82295ce159196ffe upstream.
+
+expand_shrinker_info() iterates all visible memcgs under shrinker_mutex,
+including memcgs that have not finished ->css_online() yet.
+
+Once pn->shrinker_info has been published, teardown must stay serialized
+with expand_shrinker_info() until that memcg is either fully online or no
+longer visible to iteration. Today alloc_shrinker_info() breaks that rule
+by dropping shrinker_mutex before freeing a partially initialized
+shrinker_info array, which may cause the following race:
+
+CPU0 CPU1
+==== ====
+
+css_create
+--> list_add_tail_rcu(&css->sibling, &parent_css->children);
+ online_css
+ --> mem_cgroup_css_online
+ --> alloc_shrinker_info
+ --> alloc node0 info
+ rcu_assign_pointer(C->node0->shrinker_info, old0)
+ alloc node1 info -> FAIL -> goto err
+ mutex_unlock(shrinker_mutex)
+
+ shrinker_alloc()
+ --> shrinker_memcg_alloc
+ --> mutex_lock(shrinker_mutex)
+ expand_shrinker_info
+ --> mem_cgroup_iter see the memcg
+ expand_one_shrinker_info
+ --> old0 = C->node0->shrinker_info
+ memcpy(new->unit, old0->unit, ...);
+
+ free_shrinker_info
+ --> kvfree(old0);
+
+ /* double free !! */
+ kvfree_rcu(old0, rcu);
+
+The same problem exists later in mem_cgroup_css_online(). If
+alloc_shrinker_info() succeeds but a subsequent objcg allocation fails,
+the free_objcg -> free_shrinker_info() unwind path tears down the already
+published pn->shrinker_info arrays without shrinker_mutex. The
+expand_one_shrinker_info() can race with that teardown in the same way,
+leading to use-after-free or double-free of the old shrinker_info.
+
+Fix this by serializing shrinker_info teardown with shrinker_mutex, and by
+keeping alloc_shrinker_info() error cleanup inside the locked section.
+
+Link: https://lore.kernel.org/20260617085658.27096-1-qi.zheng@linux.dev
+Fixes: 307bececcd12 ("mm: shrinker: add a secondary array for shrinker_info::{map, nr_deferred}")
+Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
+Acked-by: Muchun Song <muchun.song@linux.dev>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Qi Zheng <zhengqi.arch@bytedance.com>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/shrinker.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/mm/shrinker.c
++++ b/mm/shrinker.c
+@@ -59,12 +59,14 @@ static inline int shrinker_unit_alloc(st
+ return 0;
+ }
+
+-void free_shrinker_info(struct mem_cgroup *memcg)
++static void __free_shrinker_info(struct mem_cgroup *memcg)
+ {
+ struct mem_cgroup_per_node *pn;
+ struct shrinker_info *info;
+ int nid;
+
++ lockdep_assert_held(&shrinker_mutex);
++
+ for_each_node(nid) {
+ pn = memcg->nodeinfo[nid];
+ info = rcu_dereference_protected(pn->shrinker_info, true);
+@@ -74,6 +76,13 @@ void free_shrinker_info(struct mem_cgrou
+ }
+ }
+
++void free_shrinker_info(struct mem_cgroup *memcg)
++{
++ mutex_lock(&shrinker_mutex);
++ __free_shrinker_info(memcg);
++ mutex_unlock(&shrinker_mutex);
++}
++
+ int alloc_shrinker_info(struct mem_cgroup *memcg)
+ {
+ int nid, ret = 0;
+@@ -98,8 +107,8 @@ int alloc_shrinker_info(struct mem_cgrou
+ return ret;
+
+ err:
++ __free_shrinker_info(memcg);
+ mutex_unlock(&shrinker_mutex);
+- free_shrinker_info(memcg);
+ return -ENOMEM;
+ }
+
--- /dev/null
+From 66366d291f666ddeda5f8c84f253e308de3e6b55 Mon Sep 17 00:00:00 2001
+From: Zijiang Huang <huangzjsmile@gmail.com>
+Date: Wed, 6 May 2026 21:09:19 +0800
+Subject: mm/swap: add cond_resched() in swap_reclaim_full_clusters to prevent softlockup
+
+From: Zijiang Huang <huangzjsmile@gmail.com>
+
+commit 66366d291f666ddeda5f8c84f253e308de3e6b55 upstream.
+
+We hit a real softlockup in an internal stress test environment. The
+workload was LTP memory/swap stress on a large arm64 machine, with 320
+CPUs, about 1TB memory and an 8.6GB swap device. The system was under
+heavy load and the swap device had a large number of full clusters. The
+softlockup was triggered during a stress test after about 3 days.
+
+So, add periodic cond_resched() calls during large full_clusters
+reclaim operations to prevent softlockup issues.
+
+Detailed call trace as follow:
+
+PID: 3817773 TASK: ffff0883bb28b780 CPU: 48 COMMAND: "kworker/48:7"
+ #0 [ffff800080183d10] __crash_kexec at ffffa4c1361e5de4
+ #1 [ffff800080183d90] panic at ffffa4c1360d5e9c
+ #2 [ffff800080183e20] watchdog_timer_fn at ffffa4c136231fa8
+ ...
+ #16 [ffff8000c4ad3cb0] swap_cache_del_folio at ffffa4c1363e1614
+ #17 [ffff8000c4ad3ce0] __try_to_reclaim_swap at ffffa4c1363e4bfc
+ #18 [ffff8000c4ad3d40] swap_reclaim_full_clusters at ffffa4c1363e5474
+ #19 [ffff8000c4ad3da0] swap_reclaim_work at ffffa4c1363e550c
+ #20 [ffff8000c4ad3dc0] process_one_work at ffffa4c136102edc
+ #21 [ffff8000c4ad3e10] worker_thread at ffffa4c136103398
+ #22 [ffff8000c4ad3e70] kthread at ffffa4c13610d95c
+
+Link: https://lore.kernel.org/20260506130919.2298807-1-kerayhuang@tencent.com
+Fixes: 5168a68eb78f ("mm, swap: avoid over reclaim of full clusters")
+Signed-off-by: Zijiang Huang <kerayhuang@tencent.com>
+Reviewed-by: Kairui Song <kasong@tencent.com>
+Reviewed-by: Hao Peng <flyingpeng@tencent.com>
+Reviewed-by: albinwyang <albinwyang@tencent.com>
+Reviewed-by: Baoquan He <baoquan.he@linux.dev>
+Acked-by: Chris Li <chrisl@kernel.org>
+Cc: Barry Song <baohua@kernel.org>
+Cc: Kairui Song <kasong@tencent.com>
+Cc: Kemeng Shi <shikemeng@huaweicloud.com>
+Cc: Nhat Pham <nphamcs@gmail.com>
+Cc: Youngjun Park <youngjun.park@lge.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/swapfile.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -1054,6 +1054,7 @@ static void swap_reclaim_full_clusters(s
+ swap_cluster_unlock(ci);
+ if (to_scan <= 0)
+ break;
++ cond_resched();
+ }
+ }
+
--- /dev/null
+From 63b02a9409cb5180398491b093e48bcb5315f5fb Mon Sep 17 00:00:00 2001
+From: "Jose Fernandez (Anthropic)" <jose.fernandez@linux.dev>
+Date: Mon, 4 May 2026 12:55:17 +0000
+Subject: mm: swap_cgroup: fix NULL deref in lookup_swap_cgroup_id on swapless host
+
+From: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
+
+commit 63b02a9409cb5180398491b093e48bcb5315f5fb upstream.
+
+lookup_swap_cgroup_id() passes swap_cgroup_ctrl[type].map to
+__swap_cgroup_id_lookup() without checking that the type was ever
+registered via swap_cgroup_swapon(). On a swapless host every ctrl->map
+is NULL, so __swap_cgroup_id_lookup() dereferences NULL + a scaled
+swp_offset().
+
+Since commit bea67dcc5eea ("mm: attempt to batch free swap entries for
+zap_pte_range()"), zap_pte_range() -> swap_pte_batch() calls
+lookup_swap_cgroup_id() on any non-present, non-none PTE that decodes as a
+real swap entry, without first validating it against swap_info[]. A
+single PTE corrupted into a type-0 swap entry takes the host down at
+process exit.
+
+We hit this in production on a swapless 6.12.58 host: ~1s of
+"get_swap_device: Bad swap file entry 3f800204222bb" (do_swap_page() being
+correctly defensive about the same entry) followed by
+
+ BUG: unable to handle page fault for address: 000003f800204220
+ RIP: 0010:lookup_swap_cgroup_id+0x2b/0x60
+ Call Trace:
+ swap_pte_batch+0xbf/0x230
+ zap_pte_range+0x4c8/0x780
+ unmap_page_range+0x190/0x3e0
+ exit_mmap+0xd9/0x3c0
+ do_exit+0x20c/0x4b0
+
+syzbot has reported the identical stack.
+
+The source of the PTE corruption is a separate bug; this change makes the
+teardown path as robust as the fault path already is. Every other caller
+of lookup_swap_cgroup_id() is downstream of a get_swap_device() that has
+already validated the entry, so the new branch is cold.
+
+Link: https://lore.kernel.org/20260504-swap-cgroup-fix-7-0-v1-1-f53ff41ee553@linux.dev
+Fixes: bea67dcc5eea ("mm: attempt to batch free swap entries for zap_pte_range()")
+Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
+Reported-by: syzbot+e12bd9ca48157add237a@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/r/69859728.050a0220.3b3015.0033.GAE@google.com
+Assisted-by: Claude:unspecified
+Cc: Barry Song <baohua@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Kairui Song <ryncsn@gmail.com>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: Shakeel Butt <shakeel.butt@linux.dev>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/swap_cgroup.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/mm/swap_cgroup.c
++++ b/mm/swap_cgroup.c
+@@ -124,6 +124,8 @@ unsigned short lookup_swap_cgroup_id(swp
+ return 0;
+
+ ctrl = &swap_cgroup_ctrl[swp_type(ent)];
++ if (unlikely(!ctrl->map))
++ return 0;
+ return __swap_cgroup_id_lookup(ctrl->map, swp_offset(ent));
+ }
+
--- /dev/null
+From d129c3177d7b1138fd5066fcc63a698b3ba415b0 Mon Sep 17 00:00:00 2001
+From: Zijing Yin <yzjaurora@gmail.com>
+Date: Mon, 8 Jun 2026 07:44:41 -0700
+Subject: net: af_key: initialize alg_key_len for IPComp states
+
+From: Zijing Yin <yzjaurora@gmail.com>
+
+commit d129c3177d7b1138fd5066fcc63a698b3ba415b0 upstream.
+
+pfkey_msg2xfrm_state() handles the IPComp (SADB_X_SATYPE_IPCOMP) case by
+allocating x->calg and copying only the algorithm name:
+
+ x->calg = kmalloc_obj(*x->calg);
+ if (!x->calg) {
+ err = -ENOMEM;
+ goto out;
+ }
+ strcpy(x->calg->alg_name, a->name);
+ x->props.calgo = sa->sadb_sa_encrypt;
+
+Unlike the authentication (x->aalg) and encryption (x->ealg) branches of
+the same function, the compression branch never initializes
+calg->alg_key_len. IPComp carries no key and the allocation only
+reserves sizeof(struct xfrm_algo) (i.e. no room for a key), so the field
+is left containing uninitialized slab data.
+
+calg->alg_key_len is later used as a length by xfrm_algo_clone() when an
+IPComp state is cloned during XFRM_MSG_MIGRATE:
+
+ xfrm_state_migrate()
+ xfrm_state_clone_and_setup()
+ x->calg = xfrm_algo_clone(orig->calg);
+ kmemdup(orig, xfrm_alg_len(orig));
+
+where xfrm_alg_len() returns sizeof(*alg) + (alg_key_len + 7) / 8. With
+a non-zero garbage alg_key_len, kmemdup() reads past the end of the
+68-byte calg object. Adding an IPComp SA via PF_KEY and then migrating
+it triggers (net-next, KASAN, init_on_alloc=0):
+
+ BUG: KASAN: slab-out-of-bounds in kmemdup_noprof+0x44/0x60
+ Read of size 4164 at addr ff11000025a74980 by task diag2/9287
+ CPU: 3 UID: 0 PID: 9287 Comm: diag2 7.1.0-rc6-g903db046d557 #1
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x10e/0x1f0
+ print_report+0xf7/0x600
+ kasan_report+0xe4/0x120
+ kasan_check_range+0x105/0x1b0
+ __asan_memcpy+0x23/0x60
+ kmemdup_noprof+0x44/0x60
+ xfrm_state_migrate+0x70a/0x1da0
+ xfrm_migrate+0x753/0x18a0
+ xfrm_do_migrate+0xb47/0xf10
+ xfrm_user_rcv_msg+0x411/0xb50
+ netlink_rcv_skb+0x158/0x420
+ xfrm_netlink_rcv+0x71/0x90
+ netlink_unicast+0x584/0x850
+ netlink_sendmsg+0x8b0/0xdc0
+ ____sys_sendmsg+0x9f7/0xb90
+ ___sys_sendmsg+0x134/0x1d0
+ __sys_sendmsg+0x16d/0x220
+ do_syscall_64+0x116/0x7d0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ </TASK>
+
+ Allocated by task 9287:
+ kasan_save_stack+0x33/0x60
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0xaa/0xb0
+ pfkey_add+0x2652/0x2ea0
+ pfkey_process+0x6d0/0x830
+ pfkey_sendmsg+0x42c/0x850
+ __sys_sendto+0x461/0x4b0
+ __x64_sys_sendto+0xe0/0x1c0
+ do_syscall_64+0x116/0x7d0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+ The buggy address belongs to the object at ff11000025a74980
+ which belongs to the cache kmalloc-96 of size 96
+ The buggy address is located 0 bytes inside of
+ allocated 68-byte region [ff11000025a74980, ff11000025a749c4)
+
+Depending on the uninitialized value the same field can instead request
+an oversized kmemdup() allocation and make the migration clone fail.
+
+The XFRM netlink path is not affected: verify_one_alg() rejects an
+XFRMA_ALG_COMP attribute shorter than xfrm_alg_len(), so a calg added via
+XFRM_MSG_NEWSA is always self-consistent.
+
+Initialize calg->alg_key_len to 0, matching the aalg/ealg branches.
+
+Fixes: 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint address(es)")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zijing Yin <yzjaurora@gmail.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/key/af_key.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -1218,6 +1218,7 @@ static struct xfrm_state * pfkey_msg2xfr
+ goto out;
+ }
+ strcpy(x->calg->alg_name, a->name);
++ x->calg->alg_key_len = 0;
+ x->props.calgo = sa->sadb_sa_encrypt;
+ } else {
+ int keysize = 0;
--- /dev/null
+From efb8763d7bbb40cff4cc55a6b62c3095a038149c Mon Sep 17 00:00:00 2001
+From: Wyatt Feng <bronzed_45_vested@icloud.com>
+Date: Mon, 15 Jun 2026 18:31:18 +0800
+Subject: net: ipv4: bound TCP reordering sysctl writes and MTU probe sizes
+
+From: Wyatt Feng <bronzed_45_vested@icloud.com>
+
+commit efb8763d7bbb40cff4cc55a6b62c3095a038149c upstream.
+
+Reject invalid `net.ipv4.tcp_reordering` values before they reach TCP
+socket state. The sysctl is stored as an `int` but copied into the
+`u32` `tp->reordering` field for new sockets, so negative writes wrap
+to large values.
+
+With `tcp_mtu_probing=2`, the wrapped value can overflow the
+`tcp_mtu_probe()` size calculation and drive the MTU probing path into
+an out-of-bounds read. Route `tcp_reordering` writes through
+`proc_dointvec_minmax()` and require it to be at least 1. Also require
+`tcp_max_reordering` to be at least 1 so the configured maximum cannot
+become negative either.
+
+When registering the table for a non-init network namespace, relocate
+`extra2` pointers that refer into `init_net.ipv4` so the
+`tcp_reordering` upper bound follows that namespace's
+`tcp_max_reordering`.
+
+Harden `tcp_mtu_probe()` itself by computing `size_needed` as `u64`.
+This keeps the send queue and window checks from being bypassed through
+signed integer overflow.
+
+Fixes: 91cc17c0e5e5 ("[TCP]: MTUprobe: receiver window & data available checks fixed")
+Cc: stable@vger.kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Wyatt Feng <bronzed_45_vested@icloud.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/1a5b7e1ef4d70fbad8c8ee0b82d8405f3c964a3d.1781395200.git.bronzed_45_vested@icloud.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/sysctl_net_ipv4.c | 10 ++++++++--
+ net/ipv4/tcp_output.c | 4 ++--
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1058,7 +1058,9 @@ static struct ctl_table ipv4_net_table[]
+ .data = &init_net.ipv4.sysctl_tcp_reordering,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+- .proc_handler = proc_dointvec
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ONE,
++ .extra2 = &init_net.ipv4.sysctl_tcp_max_reordering,
+ },
+ {
+ .procname = "tcp_retries1",
+@@ -1293,7 +1295,8 @@ static struct ctl_table ipv4_net_table[]
+ .data = &init_net.ipv4.sysctl_tcp_max_reordering,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+- .proc_handler = proc_dointvec
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ONE,
+ },
+ {
+ .procname = "tcp_dsack",
+@@ -1676,6 +1679,9 @@ static __net_init int ipv4_sysctl_init_n
+ */
+ table[i].mode &= ~0222;
+ }
++ if (table[i].extra2 >= (void *)&init_net.ipv4 &&
++ table[i].extra2 < (void *)(&init_net.ipv4 + 1))
++ table[i].extra2 += (void *)net - (void *)&init_net;
+ }
+ }
+
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -2687,7 +2687,7 @@ static int tcp_mtu_probe(struct sock *sk
+ struct sk_buff *skb, *nskb, *next;
+ struct net *net = sock_net(sk);
+ int probe_size;
+- int size_needed;
++ u64 size_needed;
+ int copy, len;
+ int mss_now;
+ int interval;
+@@ -2711,7 +2711,7 @@ static int tcp_mtu_probe(struct sock *sk
+ mss_now = tcp_current_mss(sk);
+ probe_size = tcp_mtu_to_mss(sk, (icsk->icsk_mtup.search_high +
+ icsk->icsk_mtup.search_low) >> 1);
+- size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
++ size_needed = probe_size + (tp->reordering + 1) * (u64)tp->mss_cache;
+ interval = icsk->icsk_mtup.search_high - icsk->icsk_mtup.search_low;
+ /* When misfortune happens, we are reprobing actively,
+ * and then reprobe timer has expired. We stick with current
--- /dev/null
+From a7f57320bbbc67e347bf5fff4b4a9bab980d5956 Mon Sep 17 00:00:00 2001
+From: Pratham Gupta <pratham36gupta@gmail.com>
+Date: Mon, 4 May 2026 22:11:57 -0700
+Subject: netfilter: ctnetlink: use nf_ct_exp_net() in expectation dump
+
+From: Pratham Gupta <pratham36gupta@gmail.com>
+
+commit a7f57320bbbc67e347bf5fff4b4a9bab980d5956 upstream.
+
+Commit 02a3231b6d82 ("netfilter: nf_conntrack_expect: store netns and zone in expectation")
+introduced exp->net so RCU-only expectation paths no longer need to
+dereference exp->master for netns lookups.
+
+Commit 3db5647984de ("netfilter: nf_conntrack_expect: skip expectations in other netns via proc")
+updated the proc path accordingly, but ctnetlink_exp_dump_table() still
+compares against nf_ct_net(exp->master).
+
+Use nf_ct_exp_net(exp) here as well so the netlink dump path matches
+the rest of the March 2026 expectation netns/RCU cleanup.
+
+Fixes: 02a3231b6d82 ("netfilter: nf_conntrack_expect: store netns and zone in expectation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pratham Gupta <pratham36gupta@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nf_conntrack_netlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -3173,7 +3173,7 @@ restart:
+ if (l3proto && exp->tuple.src.l3num != l3proto)
+ continue;
+
+- if (!net_eq(nf_ct_net(exp->master), net))
++ if (!net_eq(nf_ct_exp_net(exp), net))
+ continue;
+
+ if (cb->args[1]) {
--- /dev/null
+From 7cd9103283b26b917360ec99d7d2f2d761bcf1ab Mon Sep 17 00:00:00 2001
+From: Xiang Mei <xmei5@asu.edu>
+Date: Wed, 24 Jun 2026 18:00:06 -0700
+Subject: netfilter: ipset: fix race between dump and ip_set_list resize
+
+From: Xiang Mei <xmei5@asu.edu>
+
+commit 7cd9103283b26b917360ec99d7d2f2d761bcf1ab upstream.
+
+The release path of ip_set_dump_do() and ip_set_dump_done() read
+inst->ip_set_list via ip_set_ref_netlink(), a plain rcu_dereference_raw()
+of the array pointer. These run from netlink_recvmsg() without the nfnl
+mutex and without an RCU read-side critical section.
+
+A concurrent ip_set_create() can grow the array: it publishes the new
+array, calls synchronize_net() and then kvfree()s the old one. Since the
+dump paths read the array outside any RCU reader, synchronize_net() does
+not wait for them and the old array can be freed while they still index
+into it, causing a use-after-free.
+
+The dumped set itself stays pinned via set->ref_netlink, so only the
+array load needs protecting. Take rcu_read_lock() around it, matching
+ip_set_get_byname() and __ip_set_put_byindex().
+
+ BUG: KASAN: slab-use-after-free in ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1697)
+ Read of size 8 at addr ffff88800b5c4018 by task exploit/150
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1697)
+ netlink_dump (net/netlink/af_netlink.c:2325)
+ netlink_recvmsg (net/netlink/af_netlink.c:1976)
+ sock_recvmsg (net/socket.c:1159)
+ __sys_recvfrom (net/socket.c:2315)
+ ...
+ Oops: general protection fault, probably for non-canonical address ... KASAN NOPTI
+ KASAN: maybe wild-memory-access in range [0x02d6...d0-0x02d6...d7]
+ RIP: 0010:ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1698)
+ Kernel panic - not syncing: Fatal exception
+
+Fixes: 8a02bdd50b2e ("netfilter: ipset: Fix calling ip_set() macro at dumping")
+Cc: stable@vger.kernel.org
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Acked-by: Jozsef Kadlecsik <kadlec@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/ipset/ip_set_core.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1480,7 +1480,11 @@ ip_set_dump_done(struct netlink_callback
+ struct ip_set_net *inst =
+ (struct ip_set_net *)cb->args[IPSET_CB_NET];
+ ip_set_id_t index = (ip_set_id_t)cb->args[IPSET_CB_INDEX];
+- struct ip_set *set = ip_set_ref_netlink(inst, index);
++ struct ip_set *set;
++
++ rcu_read_lock();
++ set = ip_set_ref_netlink(inst, index);
++ rcu_read_unlock();
+
+ if (set->variant->uref)
+ set->variant->uref(set, cb, false);
+@@ -1686,7 +1690,9 @@ next_set:
+ release_refcount:
+ /* If there was an error or set is done, release set */
+ if (ret || !cb->args[IPSET_CB_ARG0]) {
++ rcu_read_lock();
+ set = ip_set_ref_netlink(inst, index);
++ rcu_read_unlock();
+ if (set->variant->uref)
+ set->variant->uref(set, cb, false);
+ pr_debug("release set %s\n", set->name);
--- /dev/null
+From 45f1458a85017a023f138b22ac5c76abd477db42 Mon Sep 17 00:00:00 2001
+From: Breno Leitao <leitao@debian.org>
+Date: Thu, 25 Jun 2026 05:03:18 -0700
+Subject: netpoll: fix a use-after-free on shutdown path
+
+From: Breno Leitao <leitao@debian.org>
+
+commit 45f1458a85017a023f138b22ac5c76abd477db42 upstream.
+
+There is a use-after-free error on netpoll, which is clearly detected by
+KASAN.
+
+ BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0x3b/0x80
+ Read of size 1 at addr ... by task kworker/9:1
+ Workqueue: events queue_process
+ Call Trace:
+ skb_dequeue+0x1e/0xb0
+ queue_process+0x2c/0x600
+ process_scheduled_works+0x4b6/0x850
+ worker_thread+0x414/0x5a0
+ Allocated by task 242:
+ __netpoll_setup+0x201/0x4a0
+ netpoll_setup+0x249/0x550
+ enabled_store+0x32f/0x380
+ Freed by task 0:
+ kfree+0x1b7/0x540
+ rcu_core+0x3f8/0x7a0
+
+The problem happens when there is a pending TX worker running in
+parallel with the cleanup path.
+
+This is what happens on netpoll shutdown path:
+
+1) __netpoll_cleanup() is called
+2) set dev->npinfo to NULL
+3) call_rcu() with rcu_cleanup_netpoll_info()
+ 3.1) rcu_cleanup_netpoll_info() tries to cancel all workers with
+ cancel_delayed_work(), but doesn't wait for the worker to finish
+4) and kfree(npinfo);
+
+Because 3.1) doesn't really cancel the work, as the comment says "we
+can't call cancel_delayed_work_sync here, as we are in softirq", the TX
+worker can run after 4).
+
+Tl;DR: queue_process() is not an RCU reader, it reaches npinfo through
+the work item via container_of().
+
+Use disable_delayed_work_sync() to ensure the worker is completely
+stopped and prevent any future re-arming attempts. Once npinfo is set
+to NULL, senders will bail out and not queue new work. The disable flag
+ensures any in-flight re-arming attempts also fail silently.
+
+In the future, we can do the cleanup inline here without needing the
+npinfo->rcu rcu_head, but that is net-next material.
+
+Cc: stable@vger.kernel.org
+Fixes: 38e6bc185d95 ("netpoll: make __netpoll_cleanup non-block")
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Link: https://patch.msgid.link/20260625-netpoll_rcu_fix-v2-1-0748ffac1e98@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/netpoll.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -814,14 +814,6 @@ static void rcu_cleanup_netpoll_info(str
+ container_of(rcu_head, struct netpoll_info, rcu);
+
+ skb_queue_purge(&npinfo->txq);
+-
+- /* we can't call cancel_delayed_work_sync here, as we are in softirq */
+- cancel_delayed_work(&npinfo->tx_work);
+-
+- /* clean after last, unfinished work */
+- __skb_queue_purge(&npinfo->txq);
+- /* now cancel it again */
+- cancel_delayed_work(&npinfo->tx_work);
+ kfree(npinfo);
+ }
+
+@@ -845,6 +837,7 @@ static void __netpoll_cleanup(struct net
+ ops->ndo_netpoll_cleanup(np->dev);
+
+ RCU_INIT_POINTER(np->dev->npinfo, NULL);
++ disable_delayed_work_sync(&npinfo->tx_work);
+ call_rcu(&npinfo->rcu, rcu_cleanup_netpoll_info);
+ }
+
--- /dev/null
+From 4dcddc1c794d1c65eda68f1f8dd04a0fecc0870f Mon Sep 17 00:00:00 2001
+From: Koichiro Den <den@valinux.co.jp>
+Date: Wed, 4 Mar 2026 17:30:28 +0900
+Subject: NTB: epf: Avoid calling pci_irq_vector() from hardirq context
+
+From: Koichiro Den <den@valinux.co.jp>
+
+commit 4dcddc1c794d1c65eda68f1f8dd04a0fecc0870f upstream.
+
+ntb_epf_vec_isr() calls pci_irq_vector() in hardirq context to derive
+the vector number. pci_irq_vector() calls msi_get_virq() that takes a
+mutex and can therefore trigger "scheduling while atomic" splats:
+
+ BUG: scheduling while atomic: kworker/u33:0/55/0x00010001
+ ...
+ Call trace:
+ ...
+ schedule+0x38/0x110
+ schedule_preempt_disabled+0x28/0x50
+ __mutex_lock.constprop.0+0x848/0x908
+ __mutex_lock_slowpath+0x18/0x30
+ mutex_lock+0x4c/0x60
+ msi_domain_get_virq+0xe8/0x138
+ pci_irq_vector+0x2c/0x60
+ ntb_epf_vec_isr+0x28/0x120 [ntb_hw_epf]
+ __handle_irq_event_percpu+0x70/0x3a8
+ handle_irq_event+0x48/0x100
+ handle_edge_irq+0x100/0x1c8
+ ...
+
+Cache the Linux IRQ number for vector 0 when vectors are allocated and
+use it as a base in the ISR. Running the ISR in a threaded IRQ handler
+would also avoid the problem, but that would be unnecessary here.
+
+Fixes: 812ce2f8d14e ("NTB: Add support for EPF PCI Non-Transparent Bridge")
+Signed-off-by: Koichiro Den <den@valinux.co.jp>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Cc: stable@vger.kernel.org # v5.12+
+Link: https://patch.msgid.link/20260304083028.1391068-3-den@valinux.co.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ntb/hw/epf/ntb_hw_epf.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/ntb/hw/epf/ntb_hw_epf.c
++++ b/drivers/ntb/hw/epf/ntb_hw_epf.c
+@@ -92,6 +92,7 @@ struct ntb_epf_dev {
+
+ int db_val;
+ u64 db_valid_mask;
++ int irq_base;
+ };
+
+ #define ntb_ndev(__ntb) container_of(__ntb, struct ntb_epf_dev, ntb)
+@@ -318,7 +319,7 @@ static irqreturn_t ntb_epf_vec_isr(int i
+ struct ntb_epf_dev *ndev = dev;
+ int irq_no;
+
+- irq_no = irq - pci_irq_vector(ndev->ntb.pdev, 0);
++ irq_no = irq - ndev->irq_base;
+ ndev->db_val = irq_no + 1;
+
+ if (irq_no == 0)
+@@ -350,6 +351,7 @@ static int ntb_epf_init_isr(struct ntb_e
+ argument &= ~MSIX_ENABLE;
+ }
+
++ ndev->irq_base = pci_irq_vector(pdev, 0);
+ for (i = 0; i < irq; i++) {
+ ret = request_irq(pci_irq_vector(pdev, i), ntb_epf_vec_isr,
+ 0, "ntb_epf", ndev);
--- /dev/null
+From 5b6eedd7cc2936f9238e852b553a1b326105bde8 Mon Sep 17 00:00:00 2001
+From: Valeriy Yashnikov <yashnikov.valeriy@gmail.com>
+Date: Sat, 4 Jul 2026 19:38:57 +1000
+Subject: ntfs: avoid calling post_write_mst_fixup() for invalid index_block
+
+From: Valeriy Yashnikov <yashnikov.valeriy@gmail.com>
+
+commit 5b6eedd7cc2936f9238e852b553a1b326105bde8 upstream.
+
+ntfs_icx_ib_sync_write() calls post_write_mst_fixup() when ntfs_ib_write()
+returns an error, intending to restore the buffer after a failed write.
+
+However, ntfs_ib_write() returns an error immediately if
+pre_write_mst_fixup() validation fails. The caller,
+ntfs_icx_ib_sync_write(), interprets any error as a write failure
+requiring rollback. It does not differentiate between I/O errors and
+validation failures, and calls post_write_mst_fixup() anyway.
+
+Since post_write_mst_fixup() assumes that the index_block contents is
+correct, it doesn't perform the boundary checks, which results in
+out-of-bounds memory access.
+
+An attacker can craft a malicious NTFS image with:
+ - large index_block.usa_ofs offset, pointing outside the ntfs_record
+ - index_block.usa_count = 0, causing integer underflow
+ - or index_block.usa_count larger than actual number of sectors in the
+ ntfs_record, causing out-of-bounds access
+
+KASAN reports describing the memory corruption:
+ ==================================================================
+ BUG: KASAN: slab-out-of-bounds in post_write_mst_fixup+0x19c/0x1d0
+ Read of size 2 at addr ffff8881586c9018 by task p/9428
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x100/0x190
+ print_report+0x139/0x4ad
+ ? post_write_mst_fixup+0x19c/0x1d0
+ ? __virt_addr_valid+0x262/0x500
+ ? post_write_mst_fixup+0x19c/0x1d0
+ kasan_report+0xe4/0x1d0
+ ? post_write_mst_fixup+0x19c/0x1d0
+ post_write_mst_fixup+0x19c/0x1d0
+ ntfs_icx_ib_sync_write+0x179/0x220
+ ntfs_inode_sync_filename+0x83d/0x1080
+ __ntfs_write_inode+0x1049/0x1480
+ ntfs_file_fsync+0x131/0x9b0
+ ==================================================================
+ BUG: KASAN: slab-out-of-bounds in post_write_mst_fixup+0x1aa/0x1d0
+ Write of size 2 at addr ffff8881586c91fe by task p/9428
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x100/0x190
+ print_report+0x139/0x4ad
+ ? post_write_mst_fixup+0x1aa/0x1d0
+ ? __virt_addr_valid+0x262/0x500
+ ? post_write_mst_fixup+0x1aa/0x1d0
+ kasan_report+0xe4/0x1d0
+ ? post_write_mst_fixup+0x1aa/0x1d0
+ post_write_mst_fixup+0x1aa/0x1d0
+ ntfs_icx_ib_sync_write+0x179/0x220
+ ntfs_inode_sync_filename+0x83d/0x1080
+ __ntfs_write_inode+0x1049/0x1480
+ ntfs_file_fsync+0x131/0x9b0
+ ==================================================================
+
+Let's move the post_write_mst_fixup() call to ntfs_ib_write().
+The ntfs_ib_write() function calls pre_write_mst_fixup() at the beginning.
+If the index_block contents is invalid, pre_write_mst_fixup() fails and
+ntfs_ib_write() returns early without calling post_write_mst_fixup() on
+bad index_block.
+
+Fixes: 0a8ac0c1fa0b ("ntfs: update directory operations")
+Cc: stable@vger.kernel.org
+Signed-off-by: Valeriy Yashnikov <yashnikov.valeriy@gmail.com>
+Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ntfs/index.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/ntfs/index.c
++++ b/fs/ntfs/index.c
+@@ -141,6 +141,10 @@ static int ntfs_ib_write(struct ntfs_ind
+ ret = ntfs_inode_attr_pwrite(VFS_I(icx->ia_ni),
+ ntfs_ib_vcn_to_pos(icx, vcn), icx->block_size,
+ (u8 *)ib, icx->sync_write);
++
++ /* Perform data restoration before returning */
++ post_write_mst_fixup((struct ntfs_record *)ib);
++
+ if (ret != icx->block_size) {
+ ntfs_debug("Failed to write index block %lld, inode %llu",
+ vcn, (unsigned long long)icx->idx_ni->mft_no);
+@@ -178,7 +182,6 @@ int ntfs_icx_ib_sync_write(struct ntfs_i
+ icx->ib = NULL;
+ icx->ib_dirty = false;
+ } else {
+- post_write_mst_fixup((struct ntfs_record *)icx->ib);
+ icx->sync_write = false;
+ }
+
pci-qcom-initialize-dwc-msi-lock-for-firmware-managed-ecam-hosts.patch
pci-skip-resizable-bar-restore-on-read-error.patch
pci-iov-skip-vf-resizable-bar-restore-on-read-error.patch
+tcp-restore-rcu-grace-period-in-tcp_ao_destroy_sock.patch
+mm-damon-ops-common-handle-extreme-intervals-in-damon_hot_score.patch
+netfilter-ipset-fix-race-between-dump-and-ip_set_list-resize.patch
+virtio_pci-fix-vq-info-pointer-lookup-via-wrong-index.patch
+virtio-mmio-fix-device-release-warning-on-module-unload.patch
+hwrng-virtio-clamp-device-reported-used.len-at-copy_data.patch
+usb-chaoskey-fix-slab-use-after-free-in-chaoskey_release.patch
+usb-dwc3-run-gadget-disconnect-from-sleepable-suspend-context.patch
+usb-misc-usbio-fix-disconnect-uaf-in-client-teardown.patch
+6lowpan-fix-nhc-entry-use-after-free-on-error-path.patch
+tracing-fix-null-pointer-dereference-in-func_set_flag.patch
+tipc-fix-out-of-bounds-read-in-broadcast-gap-ack-blocks.patch
+staging-vme_user-bound-slave-read-write-to-the-kern_buf-size.patch
+smb-client-restrict-implied-bcc-exemption-to-responses-without-data-area.patch
+staging-vme_user-fix-location-monitor-leak-in-fake-bridge.patch
+staging-vme_user-fix-location-monitor-leak-in-tsi148-bridge.patch
+media-staging-ipu3-imgu-add-range-check-for-imgu_css_cfg_acc_stripe.patch
+staging-media-atomisp-reduce-load_primary_binaries-stack-usage.patch
+staging-media-ipu7-fix-double-free-and-use-after-free-in-error-paths.patch
+staging-rtl8723bs-don-t-drop-short-tx-frames-in-_rtw_pktfile_read.patch
+staging-rtl8723bs-fix-heap-buffer-overflow-in-rtw_cfg80211_set_wpa_ie.patch
+staging-rtl8723bs-fix-wep-length-underflow-and-oob-read-in-onauth.patch
+staging-rtl8723bs-fix-oob-read-in-onassocrsp-ie-loop.patch
+staging-rtl8723bs-fix-oob-read-in-update_beacon_info-ie-loop.patch
+staging-rtl8723bs-fix-oob-reads-in-ie-loops-in-issue_assocreq-and-join_cmd_hdl.patch
+staging-rtl8723bs-fix-oob-reads-in-is_ap_in_tkip-ie-loop.patch
+staging-rtl8723bs-fix-oob-reads-in-rtw_get_sec_ie-rtw_get_wapi_ie-and-rtw_get_wps_attr.patch
+staging-rtl8723bs-fix-oob-write-in-ht_caps_handler.patch
+crypto-amlogic-avoid-double-cleanup-in-meson_crypto_probe.patch
+crypto-krb5-filter-out-async-aead-implementations-at-alloc.patch
+crypto-qat-fix-vf2pf-work-teardown-race-in-adf_disable_sriov.patch
+ksmbd-fix-use-after-free-of-a-deferred-file_lock-on-smb2_close-then-smb2_cancel.patch
+net-af_key-initialize-alg_key_len-for-ipcomp-states.patch
+audit-fix-data-races-of-skb_queue_len-readers-on-audit_queue.patch
+bluetooth-l2cap-fix-uaf-in-channel-timeout-by-holding-conn-ref.patch
+bluetooth-mgmt-fix-uaf-of-hci_conn_params-in-add_device_complete.patch
+coresight-etb10-restore-atomic_t-for-shared-reading-state.patch
+debugobjects-plug-race-against-a-concurrent-oom-disable.patch
+fs-ntfs3-validate-dirty-page-table-capacity-in-log_replay-copy_lcns.patch
+ntfs-avoid-calling-post_write_mst_fixup-for-invalid-index_block.patch
+ntb-epf-avoid-calling-pci_irq_vector-from-hardirq-context.patch
+gpio-eic-sprd-use-raw_spinlock_t-in-the-irq-startup-path.patch
+gpio-sch-use-raw_spinlock_t-in-the-irq-startup-path.patch
+hid-logitech-dj-fix-maxfield-check-in-dj-short-report-validation.patch
+io_uring-nop-fix-file-reference-leak-with-iosqe_fixed_file.patch
+io_uring-io-wq-re-check-io_wq_bit_exit-for-each-linked-work-item.patch
+io_uring-rw-preserve-partial-result-for-iopoll.patch
+netpoll-fix-a-use-after-free-on-shutdown-path.patch
+ipv4-igmp-remove-multicast-group-from-hash-table-on-device-destruction.patch
+net-ipv4-bound-tcp-reordering-sysctl-writes-and-mtu-probe-sizes.patch
+media-nxp-imx8-isi-fix-use-after-free-on-remove.patch
+mfd-cros_ec-delay-dev_set_drvdata-until-probe-success.patch
+mm-shrinker-do-not-hold-rcu-lock-in-shrinker_debugfs_count_show.patch
+mm-shrinker-fix-shrinker_info-teardown-race-with-expansion.patch
+mm-shrinker-fix-null-pointer-dereference-in-debugfs.patch
+mm-swap_cgroup-fix-null-deref-in-lookup_swap_cgroup_id-on-swapless-host.patch
+mm-swap-add-cond_resched-in-swap_reclaim_full_clusters-to-prevent-softlockup.patch
+netfilter-ctnetlink-use-nf_ct_exp_net-in-expectation-dump.patch
--- /dev/null
+From 53b7c271f06be4dd5cfc8c6ef552a8355c891a7f Mon Sep 17 00:00:00 2001
+From: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+Date: Tue, 7 Jul 2026 20:23:58 +0900
+Subject: smb: client: restrict implied bcc[0] exemption to responses without data area
+
+From: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+
+commit 53b7c271f06be4dd5cfc8c6ef552a8355c891a7f upstream.
+
+smb2_check_message() has a long-standing quirk that accepts a response
+whose calculated length is one byte larger than the bytes actually
+received ("server can return one byte more due to implied bcc[0]").
+This was introduced to accommodate servers that omit the trailing bcc[0]
+overlap byte when no data area is present.
+
+However, the exemption is applied unconditionally, regardless of whether
+the command actually carries a data area (has_smb2_data_area[]). When a
+response with a data area is subject to the +1 exemption, the reported
+data can extend one byte beyond the bytes actually received, yet
+smb2_check_message() still accepts it. The subsequent decoder then reads
+past the end of the receive buffer. This is reachable during NEGOTIATE
+and SESSION_SETUP, before the session is established.
+
+The resulting out-of-bounds reads are visible under KASAN when mounting
+against a non-conforming server; both the SPNEGO/negTokenInit and the
+NTLMSSP challenge decoders are affected:
+
+ BUG: KASAN: slab-out-of-bounds in asn1_ber_decoder+0x16a7/0x1b00
+ Read of size 1 at addr ffff8880084d67c0 by task mount.cifs/81
+ CPU: 1 UID: 0 PID: 81 Comm: mount.cifs Not tainted 7.1.0-rc6 #1
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x4e/0x70
+ print_report+0x157/0x4c9
+ kasan_report+0xce/0x100
+ asn1_ber_decoder+0x16a7/0x1b00
+ decode_negTokenInit+0x19/0x30
+ SMB2_negotiate+0x31d9/0x4c90
+ cifs_negotiate_protocol+0x1f2/0x3f0
+ cifs_get_smb_ses+0x93f/0x17e0
+ cifs_mount_get_session+0x7f/0x3a0
+ cifs_mount+0xb4/0xcf0
+ cifs_smb3_do_mount+0x23a/0x1500
+ smb3_get_tree+0x3b0/0x630
+ vfs_get_tree+0x82/0x2d0
+ fc_mount+0x10/0x1b0
+ path_mount+0x50d/0x1de0
+ __x64_sys_mount+0x20b/0x270
+ do_syscall_64+0xee/0x590
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ </TASK>
+ Allocated by task 85:
+ kmem_cache_alloc_noprof+0x106/0x380
+ mempool_alloc_noprof+0x116/0x1e0
+ cifs_small_buf_get+0x31/0x80
+ allocate_buffers+0x10d/0x2b0
+ cifs_demultiplex_thread+0x1d5/0x1d50
+ kthread+0x2c6/0x390
+ ret_from_fork+0x36e/0x5a0
+ ret_from_fork_asm+0x1a/0x30
+ The buggy address is located 0 bytes to the right of
+ allocated 448-byte region [ffff8880084d6600, ffff8880084d67c0)
+ which belongs to the cache cifs_small_rq of size 448
+
+ BUG: KASAN: slab-out-of-bounds in kmemdup_noprof+0x36/0x50
+ Read of size 329 at addr ffff88800726c678 by task mount.cifs/89
+ CPU: 0 UID: 0 PID: 89 Comm: mount.cifs Tainted: G B 7.1.0-rc6 #1
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x4e/0x70
+ print_report+0x157/0x4c9
+ kasan_report+0xce/0x100
+ kasan_check_range+0x10f/0x1e0
+ __asan_memcpy+0x23/0x60
+ kmemdup_noprof+0x36/0x50
+ decode_ntlmssp_challenge+0x457/0x680
+ SMB2_sess_auth_rawntlmssp_negotiate+0x6f0/0xcb0
+ SMB2_sess_setup+0x219/0x4f0
+ cifs_setup_session+0x248/0xaf0
+ cifs_get_smb_ses+0xf79/0x17e0
+ cifs_mount_get_session+0x7f/0x3a0
+ cifs_mount+0xb4/0xcf0
+ cifs_smb3_do_mount+0x23a/0x1500
+ smb3_get_tree+0x3b0/0x630
+ vfs_get_tree+0x82/0x2d0
+ fc_mount+0x10/0x1b0
+ path_mount+0x50d/0x1de0
+ __x64_sys_mount+0x20b/0x270
+ do_syscall_64+0xee/0x590
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ </TASK>
+ Allocated by task 93:
+ kmem_cache_alloc_noprof+0x106/0x380
+ mempool_alloc_noprof+0x116/0x1e0
+ cifs_small_buf_get+0x31/0x80
+ allocate_buffers+0x10d/0x2b0
+ cifs_demultiplex_thread+0x1d5/0x1d50
+ kthread+0x2c6/0x390
+ ret_from_fork+0x36e/0x5a0
+ ret_from_fork_asm+0x1a/0x30
+ The buggy address is located 120 bytes inside of
+ allocated 448-byte region [ffff88800726c600, ffff88800726c7c0)
+ which belongs to the cache cifs_small_rq of size 448
+
+Restrict the +1 exemption to responses that have no data area, so that
+it still covers the bcc[0] omission it was meant for. When a data area
+is present, the +1 discrepancy instead means the reported data length
+overruns the received buffer, so the response must be rejected.
+
+Fixes: 093b2bdad322 ("CIFS: Make demultiplex_thread work with SMB2 code")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shoichiro Miyamoto <shoichiro.miyamoto@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2misc.c | 32 ++++++++++++++++++++++++++------
+ 1 file changed, 26 insertions(+), 6 deletions(-)
+
+--- a/fs/smb/client/smb2misc.c
++++ b/fs/smb/client/smb2misc.c
+@@ -19,6 +19,8 @@
+ #include "nterr.h"
+ #include "cached_dir.h"
+
++static unsigned int __smb2_calc_size(void *buf, bool *have_data);
++
+ static int
+ check_smb2_hdr(struct smb2_hdr *shdr, __u64 mid)
+ {
+@@ -145,6 +147,7 @@ smb2_check_message(char *buf, unsigned i
+ int command;
+ __u32 calc_len; /* calculated length */
+ __u64 mid;
++ bool have_data;
+
+ /* If server is a channel, select the primary channel */
+ pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
+@@ -228,7 +231,8 @@ smb2_check_message(char *buf, unsigned i
+ }
+ }
+
+- calc_len = smb2_calc_size(buf);
++ have_data = false;
++ calc_len = __smb2_calc_size(buf, &have_data);
+
+ /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
+ * be 0, and not a real miscalculation */
+@@ -247,8 +251,13 @@ smb2_check_message(char *buf, unsigned i
+ /* Windows 7 server returns 24 bytes more */
+ if (calc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
+ return 0;
+- /* server can return one byte more due to implied bcc[0] */
+- if (calc_len == len + 1)
++ /*
++ * Server can return one byte more due to implied bcc[0].
++ * Allow it only when there is no data area; if data_length > 0
++ * the +1 gap indicates an overreported data length rather than
++ * the bcc[0] omission.
++ */
++ if (calc_len == len + 1 && !have_data)
+ return 0;
+
+ /*
+@@ -409,14 +418,17 @@ smb2_get_data_area_len(int *off, int *le
+ /*
+ * Calculate the size of the SMB message based on the fixed header
+ * portion, the number of word parameters and the data portion of the message.
++ * If have_data is non-NULL, it is set to true when a non-empty data area was
++ * found (data_length > 0), allowing callers to distinguish the implied bcc[0]
++ * case (no data area) from an overreported data length.
+ */
+-unsigned int
+-smb2_calc_size(void *buf)
++static unsigned int
++__smb2_calc_size(void *buf, bool *have_data)
+ {
+ struct smb2_pdu *pdu = buf;
+ struct smb2_hdr *shdr = &pdu->hdr;
+ int offset; /* the offset from the beginning of SMB to data area */
+- int data_length; /* the length of the variable length data area */
++ int data_length = 0; /* the length of the variable length data area */
+ /* Structure Size has already been checked to make sure it is 64 */
+ int len = le16_to_cpu(shdr->StructureSize);
+
+@@ -449,9 +461,17 @@ smb2_calc_size(void *buf)
+ }
+ calc_size_exit:
+ cifs_dbg(FYI, "SMB2 len %d\n", len);
++ if (have_data)
++ *have_data = (data_length > 0);
+ return len;
+ }
+
++unsigned int
++smb2_calc_size(void *buf)
++{
++ return __smb2_calc_size(buf, NULL);
++}
++
+ /* Note: caller must free return buffer */
+ __le16 *
+ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
--- /dev/null
+From f4d51e55dd47ef467fbe37d8575e20eee41b092d Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Wed, 25 Mar 2026 13:59:43 +0100
+Subject: staging: media: atomisp: reduce load_primary_binaries() stack usage
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit f4d51e55dd47ef467fbe37d8575e20eee41b092d upstream.
+
+The load_primary_binaries() function is overly complex and has som large
+variables on the stack, which can cause warnings depending on CONFIG_FRAME_WARN
+setting:
+
+drivers/staging/media/atomisp/pci/sh_css.c: In function 'load_primary_binaries':
+drivers/staging/media/atomisp/pci/sh_css.c:5260:1: error: the frame size of 1560 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
+
+Half of the stack usage is for the prim_descr[] array, but only one
+member of the array is used at any given time.
+
+Reduce the stack usage by turning the array into a single structure.
+
+Fixes: a49d25364dfb ("staging/atomisp: Add support for the Intel IPU v2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/media/atomisp/pci/sh_css.c
++++ b/drivers/staging/media/atomisp/pci/sh_css.c
+@@ -5020,7 +5020,6 @@ static int load_primary_binaries(
+ struct ia_css_capture_settings *mycs;
+ unsigned int i;
+ bool need_extra_yuv_scaler = false;
+- struct ia_css_binary_descr prim_descr[MAX_NUM_PRIMARY_STAGES];
+
+ IA_CSS_ENTER_PRIVATE("");
+ assert(pipe);
+@@ -5189,15 +5188,16 @@ static int load_primary_binaries(
+
+ /* Primary */
+ for (i = 0; i < mycs->num_primary_stage; i++) {
++ struct ia_css_binary_descr prim_descr;
+ struct ia_css_frame_info *local_vf_info = NULL;
+
+ if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] &&
+ (i == mycs->num_primary_stage - 1))
+ local_vf_info = &vf_info;
+- ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i],
++ ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr,
+ &prim_in_info, &prim_out_info,
+ local_vf_info, i);
+- err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]);
++ err = ia_css_binary_find(&prim_descr, &mycs->primary_binary[i]);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
--- /dev/null
+From d3a9a8cf2d7fd61a2f63df61f6cbc0a9bb007cc0 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Mon, 13 Apr 2026 17:12:44 +0200
+Subject: staging: media: ipu7: fix double-free and use-after-free in error paths
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit d3a9a8cf2d7fd61a2f63df61f6cbc0a9bb007cc0 upstream.
+
+In both ipu7_isys_init() and ipu7_psys_init(), pdata is allocated and
+then passed to ipu7_bus_initialize_device(), which stores it in
+adev->pdata. The ipu7_bus_release() function frees adev->pdata when the
+device's reference count drops to zero.
+
+Two error paths incorrectly call kfree(pdata) after the device teardown
+has already freed it:
+
+1. When ipu7_mmu_init() fails: put_device() is called, which drops the
+ reference count to zero and triggers ipu7_bus_release() ->
+ kfree(pdata). The subsequent kfree(pdata) is a double-free.
+
+2. When ipu7_bus_add_device() fails: it calls auxiliary_device_uninit()
+ internally, which calls put_device() -> ipu7_bus_release() ->
+ kfree(pdata). The subsequent kfree(pdata) is again a double-free.
+
+Note that the kfree(pdata) when ipu7_bus_initialize_device() itself
+fails is correct, because in that case auxiliary_device_init() failed
+and the release function was never set up, so pdata must be freed
+manually.
+
+Additionally, the error code was not saved before calling put_device(),
+causing ERR_CAST() to dereference the already-freed adev pointer when
+constructing the return value. Fix this by saving the error from
+dev_err_probe() before put_device() and returning ERR_PTR() instead.
+
+Remove the redundant kfree(pdata) calls and fix the use-after-free in
+the return values of the two affected error paths.
+
+Fixes: b7fe4c0019b1 ("media: staging/ipu7: add Intel IPU7 PCI device driver")
+Cc: stable@vger.kernel.org
+Reviewed-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/ipu7/ipu7.c | 22 ++++++++--------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+--- a/drivers/staging/media/ipu7/ipu7.c
++++ b/drivers/staging/media/ipu7/ipu7.c
+@@ -2169,21 +2169,18 @@ ipu7_isys_init(struct pci_dev *pdev, str
+ isys_adev->mmu = ipu7_mmu_init(dev, base, ISYS_MMID,
+ &ipdata->hw_variant);
+ if (IS_ERR(isys_adev->mmu)) {
+- dev_err_probe(dev, PTR_ERR(isys_adev->mmu),
+- "ipu7_mmu_init(isys_adev->mmu) failed\n");
++ ret = dev_err_probe(dev, PTR_ERR(isys_adev->mmu),
++ "ipu7_mmu_init(isys_adev->mmu) failed\n");
+ put_device(&isys_adev->auxdev.dev);
+- kfree(pdata);
+- return ERR_CAST(isys_adev->mmu);
++ return ERR_PTR(ret);
+ }
+
+ isys_adev->mmu->dev = &isys_adev->auxdev.dev;
+ isys_adev->subsys = IPU_IS;
+
+ ret = ipu7_bus_add_device(isys_adev);
+- if (ret) {
+- kfree(pdata);
++ if (ret)
+ return ERR_PTR(ret);
+- }
+
+ return isys_adev;
+ }
+@@ -2216,21 +2213,18 @@ ipu7_psys_init(struct pci_dev *pdev, str
+ psys_adev->mmu = ipu7_mmu_init(&pdev->dev, base, PSYS_MMID,
+ &ipdata->hw_variant);
+ if (IS_ERR(psys_adev->mmu)) {
+- dev_err_probe(&pdev->dev, PTR_ERR(psys_adev->mmu),
+- "ipu7_mmu_init(psys_adev->mmu) failed\n");
++ ret = dev_err_probe(&pdev->dev, PTR_ERR(psys_adev->mmu),
++ "ipu7_mmu_init(psys_adev->mmu) failed\n");
+ put_device(&psys_adev->auxdev.dev);
+- kfree(pdata);
+- return ERR_CAST(psys_adev->mmu);
++ return ERR_PTR(ret);
+ }
+
+ psys_adev->mmu->dev = &psys_adev->auxdev.dev;
+ psys_adev->subsys = IPU_PS;
+
+ ret = ipu7_bus_add_device(psys_adev);
+- if (ret) {
+- kfree(pdata);
++ if (ret)
+ return ERR_PTR(ret);
+- }
+
+ return psys_adev;
+ }
--- /dev/null
+From 252f8c681adc8614b70f844ba3de3a138c33a783 Mon Sep 17 00:00:00 2001
+From: Christopher Mackle <christophermackle01@gmail.com>
+Date: Sat, 20 Jun 2026 01:39:16 +0000
+Subject: staging: rtl8723bs: don't drop short TX frames in _rtw_pktfile_read()
+
+From: Christopher Mackle <christophermackle01@gmail.com>
+
+commit 252f8c681adc8614b70f844ba3de3a138c33a783 upstream.
+
+Commit bc4df274dca6 ("staging: rtl8723bs: update _rtw_pktfile_read() to
+return error codes") changed _rtw_pktfile_read() to fail when the caller
+asks for more bytes than remain in the packet:
+
+ if (rtw_remainder_len(pfile) < rlen)
+ return -EINVAL;
+
+That breaks the assumption made by the data TX path. In
+rtw_xmitframe_coalesce() (core/rtw_xmit.c) the per-fragment copy is
+issued with the full fragment length, mpdu_len, which is derived from
+pxmitpriv->frag_len (~2300 bytes), and the code relies on the historical
+behaviour of copying only what is left and returning the number of bytes
+actually copied:
+
+ mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
+ if (mem_sz < 0)
+ return mem_sz;
+
+So for every outbound packet smaller than the fragmentation threshold -
+i.e. essentially all normal traffic, including the EAPOL frames of the
+WPA 4-way handshake and DHCP - rlen is larger than the bytes remaining,
+_rtw_pktfile_read() returns -EINVAL, rtw_xmitframe_coalesce() aborts, and
+the frame is dropped before it is queued to the hardware. The driver
+floods the log with:
+
+ rtl8723bs ...: xmit_xmitframes: coalesce failed with error -22
+
+Management frames (authentication/association) use a different path and
+still go out, so the interface scans and associates, but no data frame is
+ever transmitted. The 4-way handshake therefore never completes and
+wpa_supplicant misreports it as:
+
+ WPA: 4-Way Handshake failed - pre-shared key may be incorrect
+
+AP mode is unaffected. The net effect is that the chip is unusable in
+station mode on any kernel carrying the offending commit.
+
+This was confirmed with a wpa_supplicant -dd trace on an RTL8723BS SDIO
+adapter (Bay Trail): message 1/4 is received and the PTK is derived, but
+each "Sending EAPOL-Key 2/4" coincides 1:1 with a "coalesce failed with
+error -22", so message 2/4 never reaches the AP, which keeps retrying
+message 1/4 until the handshake times out.
+
+Restore the original semantics: clamp the requested length to the bytes
+remaining in the packet and return that length. The skb_copy_bits()
+error path is kept, so genuine copy failures are still propagated.
+
+Fixes: bc4df274dca6 ("staging: rtl8723bs: update _rtw_pktfile_read() to return error codes")
+Cc: stable <stable@kernel.org>
+Tested-by: Christopher Mackle <christophermackle01@gmail.com>
+Signed-off-by: Christopher Mackle <christophermackle01@gmail.com>
+Link: https://patch.msgid.link/20260620013916.7148-1-christophermackle01@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/os_dep/xmit_linux.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/rtl8723bs/os_dep/xmit_linux.c b/drivers/staging/rtl8723bs/os_dep/xmit_linux.c
+index d5bb1c7932fc..4260ed5f4e97 100644
+--- a/drivers/staging/rtl8723bs/os_dep/xmit_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/xmit_linux.c
+@@ -24,9 +24,11 @@ void _rtw_open_pktfile(struct sk_buff *pktptr, struct pkt_file *pfile)
+ int _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, unsigned int rlen)
+ {
+ int ret;
++ unsigned int remain = rtw_remainder_len(pfile);
+
+- if (rtw_remainder_len(pfile) < rlen)
+- return -EINVAL;
++ /* clamp to bytes remaining; the coalesce loop relies on short reads */
++ if (rlen > remain)
++ rlen = remain;
+
+ if (rmem) {
+ ret = skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, rlen);
+--
+2.55.0
+
--- /dev/null
+From 5a752a616e756844388a1a45404db9fc29fec655 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Fri, 22 May 2026 02:45:27 +0200
+Subject: staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit 5a752a616e756844388a1a45404db9fc29fec655 upstream.
+
+supplicant_ie is a 256-byte array in struct security_priv. The WPA and
+WPA2 IE copy paths use:
+
+ memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
+
+where wpa_ielen is the raw IE length field (u8, 0-255). When a local user
+supplies a connect request via nl80211 with a crafted WPA IE of length 255,
+wpa_ielen + 2 equals 257, overflowing the 256-byte buffer by one byte into
+the adjacent last_mic_err_time field.
+
+rtw_parse_wpa_ie() does not prevent this: its length consistency check
+compares *(wpa_ie+1) against (u8)(wpa_ie_len-2), which is (u8)(255) == 255
+when wpa_ie_len = 257, so the check passes silently.
+
+Add explicit bounds checks for both the WPA and WPA2 paths before the
+memcpy, rejecting any IE whose total size (wpa_ielen + 2) exceeds the
+supplicant_ie buffer.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-4-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -1445,6 +1445,10 @@ static int rtw_cfg80211_set_wpa_ie(struc
+
+ pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
+ if (pwpa && wpa_ielen > 0) {
++ if (wpa_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
++ ret = -EINVAL;
++ goto exit;
++ }
+ if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
+@@ -1454,6 +1458,10 @@ static int rtw_cfg80211_set_wpa_ie(struc
+
+ pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
+ if (pwpa2 && wpa2_ielen > 0) {
++ if (wpa2_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
++ ret = -EINVAL;
++ goto exit;
++ }
+ if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
--- /dev/null
+From f9654207e92283e0acac5d64fe5f8835383b5a23 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Fri, 22 May 2026 02:45:29 +0200
+Subject: staging: rtl8723bs: fix OOB read in OnAssocRsp() IE loop
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit f9654207e92283e0acac5d64fe5f8835383b5a23 upstream.
+
+The IE parsing loop in OnAssocRsp() advances by (pIE->length + 2) each
+iteration but only guards on i < pkt_len. When a malicious AP sends an
+AssocResponse whose last IE has only one byte remaining in the frame
+(the element_id byte lands at pkt_len-1), the loop reads pIE->length
+from pframe[pkt_len], which is one byte past the allocated receive buffer.
+
+Additionally, even when the header bytes are in bounds, pIE->length
+itself can extend the data window beyond pkt_len, silently passing a
+truncated IE to the handler functions.
+
+Add two guards at the top of the loop body:
+ 1. Break if fewer than sizeof(*pIE) bytes remain (can't read header).
+ 2. Break if the IE's declared data extends past pkt_len.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Link: https://patch.msgid.link/20260522004531.1038924-6-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -1406,7 +1406,11 @@ unsigned int OnAssocRsp(struct adapter *
+ /* to handle HT, WMM, rate adaptive, update MAC reg */
+ /* for not to handle the synchronous IO in the tasklet */
+ for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
++ if (i + sizeof(*pIE) > pkt_len)
++ break;
+ pIE = (struct ndis_80211_var_ie *)(pframe + i);
++ if (i + sizeof(*pIE) + pIE->length > pkt_len)
++ break;
+
+ switch (pIE->element_id) {
+ case WLAN_EID_VENDOR_SPECIFIC:
--- /dev/null
+From ed51de4a86e173c3b0ef78e039c2e49e08b11f16 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Fri, 22 May 2026 02:45:25 +0200
+Subject: staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit ed51de4a86e173c3b0ef78e039c2e49e08b11f16 upstream.
+
+The IE parsing loop in update_beacon_info() advances by
+(pIE->length + 2) each iteration but only guards on i < len.
+When a malicious AP sends a Beacon whose last IE has only one byte
+remaining in the frame (the element_id byte lands at len-1), the loop
+reads pIE->length from one byte past the allocated receive buffer.
+
+Additionally, even when the header bytes are in bounds, pIE->length
+itself can extend the data window beyond len, passing a truncated IE
+to the handler functions.
+
+Add two guards at the top of the loop body:
+ 1. Break if fewer than sizeof(*pIE) bytes remain (can't read header).
+ 2. Break if the IE's declared data extends past len.
+
+Also replace i += (pIE->length + 2) with i += sizeof(*pIE) + pIE->length
+for consistency with the sizeof(*pIE) guards added above.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-2-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
++++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+@@ -1289,7 +1289,11 @@ void update_beacon_info(struct adapter *
+ len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
+
+ for (i = 0; i < len;) {
++ if (i + sizeof(*pIE) > len)
++ break;
+ pIE = (struct ndis_80211_var_ie *)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
++ if (i + sizeof(*pIE) + pIE->length > len)
++ break;
+
+ switch (pIE->element_id) {
+ case WLAN_EID_VENDOR_SPECIFIC:
+@@ -1314,7 +1318,7 @@ void update_beacon_info(struct adapter *
+ break;
+ }
+
+- i += (pIE->length + 2);
++ i += sizeof(*pIE) + pIE->length;
+ }
+ }
+
--- /dev/null
+From ef61d628dfad38fead1fd2e08979ae9126d011d5 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Fri, 22 May 2026 02:45:26 +0200
+Subject: staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl()
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit ef61d628dfad38fead1fd2e08979ae9126d011d5 upstream.
+
+Two IE parsing loops are missing the header bounds checks before they
+dereference pIE->length:
+
+ - issue_assocreq() walks pmlmeinfo->network.ies to build the
+ association request. If the stored IE data ends with only an
+ element_id byte and no length byte, pIE->length is read one byte
+ past the end of the buffer.
+
+ - join_cmd_hdl() walks pnetwork->ies during station join and has
+ the same problem under the same conditions.
+
+Both buffers are filled from AP beacon and probe-response frames, so a
+malicious AP that sends a truncated final IE can trigger the issue.
+
+Apply the two-guard pattern established in update_beacon_info():
+ 1. Break if fewer than sizeof(*pIE) bytes remain.
+ 2. Break if the IE's declared data extends past the buffer end.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-3-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -2935,7 +2935,11 @@ void issue_assocreq(struct adapter *pada
+
+ /* vendor specific IE, such as WPA, WMM, WPS */
+ for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.ie_length;) {
++ if (i + sizeof(*pIE) > pmlmeinfo->network.ie_length)
++ break;
+ pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.ies + i);
++ if (i + sizeof(*pIE) + pIE->length > pmlmeinfo->network.ie_length)
++ break;
+
+ switch (pIE->element_id) {
+ case WLAN_EID_VENDOR_SPECIFIC:
+@@ -5328,7 +5332,11 @@ u8 join_cmd_hdl(struct adapter *padapter
+
+ /* sizeof(struct ndis_802_11_fix_ie) */
+ for (i = _FIXED_IE_LENGTH_; i < pnetwork->ie_length;) {
++ if (i + sizeof(*pIE) > pnetwork->ie_length)
++ break;
+ pIE = (struct ndis_80211_var_ie *)(pnetwork->ies + i);
++ if (i + sizeof(*pIE) + pIE->length > pnetwork->ie_length)
++ break;
+
+ switch (pIE->element_id) {
+ case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
--- /dev/null
+From 3bf39f711ff27c64be8680a8938bcc5001982e81 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Fri, 22 May 2026 02:45:30 +0200
+Subject: staging: rtl8723bs: fix OOB reads in is_ap_in_tkip() IE loop
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit 3bf39f711ff27c64be8680a8938bcc5001982e81 upstream.
+
+The loop in is_ap_in_tkip() iterates over IEs without verifying that
+enough bytes remain before dereferencing the IE header or its payload:
+
+- pIE->element_id and pIE->length are read without checking that
+ i + sizeof(*pIE) <= ie_length, so a truncated IE at the end of the
+ buffer causes an OOB read.
+
+- For WLAN_EID_VENDOR_SPECIFIC the code compares pIE->data + 12,
+ which requires pIE->length >= 16. For WLAN_EID_RSN it compares
+ pIE->data + 8, requiring pIE->length >= 12. Neither requirement
+ is checked.
+
+Add the missing IE header and payload bounds checks and guard each
+data access with an explicit pIE->length minimum, matching the
+pattern established in update_beacon_info().
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-7-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
++++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+@@ -1334,15 +1334,23 @@ unsigned int is_ap_in_tkip(struct adapte
+ for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.ie_length;) {
+ pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.ies + i);
+
++ if (i + sizeof(*pIE) > pmlmeinfo->network.ie_length)
++ break;
++ if (i + sizeof(*pIE) + pIE->length > pmlmeinfo->network.ie_length)
++ break;
++
+ switch (pIE->element_id) {
+ case WLAN_EID_VENDOR_SPECIFIC:
+- if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4)))
++ if (pIE->length >= 16 &&
++ !memcmp(pIE->data, RTW_WPA_OUI, 4) &&
++ !memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4))
+ return true;
+
+ break;
+
+ case WLAN_EID_RSN:
+- if (!memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
++ if (pIE->length >= 12 &&
++ !memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
+ return true;
+ break;
+
+@@ -1350,7 +1358,7 @@ unsigned int is_ap_in_tkip(struct adapte
+ break;
+ }
+
+- i += (pIE->length + 2);
++ i += sizeof(*pIE) + pIE->length;
+ }
+
+ return false;
--- /dev/null
+From 1463ca3ec6601cbb097d8d87dbf5dcf1cb86a344 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Fri, 22 May 2026 02:45:31 +0200
+Subject: staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr()
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit 1463ca3ec6601cbb097d8d87dbf5dcf1cb86a344 upstream.
+
+Three IE/attribute parsing functions have missing bounds checks.
+
+rtw_get_sec_ie() and rtw_get_wapi_ie() iterate over a raw IE buffer
+without verifying that the header bytes (tag + length) are within the
+remaining buffer before reading them. Additionally, rtw_get_sec_ie()
+compares the 4-byte WPA OUI at cnt+2 without checking that at least
+6 bytes remain, and rtw_get_wapi_ie() compares a 4-byte WAPI OUI at
+cnt+6 without checking that at least 10 bytes remain.
+
+rtw_get_wps_attr() reads wps_ie[0] and wps_ie+2 unconditionally at
+entry, before verifying that wps_ielen is large enough to contain
+the 6-byte WPS IE header (element_id + length + 4-byte OUI). Inside
+the attribute loop, get_unaligned_be16() is called on attr_ptr and
+attr_ptr+2 without checking that 4 bytes remain in the buffer.
+
+Add a cnt+2 bounds check before each loop body in rtw_get_sec_ie()
+and rtw_get_wapi_ie(), guard each multi-byte comparison with a minimum
+IE length requirement, add a wps_ielen < 6 early return in
+rtw_get_wps_attr(), and add a 4-byte bounds check in its inner loop.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004531.1038924-8-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
+@@ -583,9 +583,14 @@ int rtw_get_wapi_ie(u8 *in_ie, uint in_l
+ cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
+
+ while (cnt < in_len) {
++ if (cnt + 2 > in_len)
++ break;
++ if (cnt + 2 + in_ie[cnt + 1] > in_len)
++ break;
+ authmode = in_ie[cnt];
+
+ if (authmode == WLAN_EID_BSS_AC_ACCESS_DELAY &&
++ in_ie[cnt + 1] >= 8 &&
+ (!memcmp(&in_ie[cnt + 6], wapi_oui1, 4) ||
+ !memcmp(&in_ie[cnt + 6], wapi_oui2, 4))) {
+ if (wapi_ie)
+@@ -616,9 +621,14 @@ void rtw_get_sec_ie(u8 *in_ie, uint in_l
+ cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
+
+ while (cnt < in_len) {
++ if (cnt + 2 > in_len)
++ break;
++ if (cnt + 2 + in_ie[cnt + 1] > in_len)
++ break;
+ authmode = in_ie[cnt];
+
+ if ((authmode == WLAN_EID_VENDOR_SPECIFIC) &&
++ in_ie[cnt + 1] >= 4 &&
+ (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
+ if (wpa_ie)
+ memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
+@@ -699,6 +709,9 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wp
+ if (len_attr)
+ *len_attr = 0;
+
++ if (wps_ielen < 6)
++ return attr_ptr;
++
+ if ((wps_ie[0] != WLAN_EID_VENDOR_SPECIFIC) ||
+ (memcmp(wps_ie + 2, wps_oui, 4))) {
+ return attr_ptr;
+@@ -709,6 +722,8 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wp
+
+ while (attr_ptr - wps_ie < wps_ielen) {
+ /* 4 = 2(Attribute ID) + 2(Length) */
++ if (attr_ptr + 4 > wps_ie + wps_ielen)
++ break;
+ u16 attr_id = get_unaligned_be16(attr_ptr);
+ u16 attr_data_len = get_unaligned_be16(attr_ptr + 2);
+ u16 attr_len = attr_data_len + 4;
--- /dev/null
+From f8001e1a516ba3b495728c65b61f799cbfad6bd0 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Fri, 22 May 2026 02:45:28 +0200
+Subject: staging: rtl8723bs: fix OOB write in HT_caps_handler()
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit f8001e1a516ba3b495728c65b61f799cbfad6bd0 upstream.
+
+HT_caps_handler() iterates pIE->length bytes and writes into
+HT_caps.u.HT_cap[], which is a fixed 26-byte array (sizeof struct
+HT_caps_element). Because pIE->length is a raw u8 from an over-the-air
+802.11 AssocResponse frame and is never validated, a malicious AP can
+set it up to 255, causing up to 229 bytes of out-of-bounds writes into
+adjacent fields of struct mlme_ext_info.
+
+Truncate the iteration count to the size of HT_caps.u.HT_cap using
+umin() so that data from a longer-than-expected IE is silently ignored
+rather than written out of bounds, preserving interoperability with APs
+that pad the element. An early return on oversized IEs was considered
+but rejected: it would bypass the pmlmeinfo->HT_caps_enable = 1
+assignment that precedes the loop, silently disabling HT mode for APs
+that append extra bytes to the HT Capabilities IE.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
+Link: https://patch.msgid.link/20260522004531.1038924-5-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
++++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+@@ -936,7 +936,8 @@ void HT_caps_handler(struct adapter *pad
+
+ pmlmeinfo->HT_caps_enable = 1;
+
+- for (i = 0; i < (pIE->length); i++) {
++ for (i = 0; i < umin(pIE->length,
++ sizeof(pmlmeinfo->HT_caps.u.HT_cap)); i++) {
+ if (i != 2) {
+ /* Commented by Albert 2010/07/12 */
+ /* Got the endian issue here. */
--- /dev/null
+From a1fc19d61f661d47204f095b593de507884849f7 Mon Sep 17 00:00:00 2001
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+Date: Fri, 22 May 2026 02:46:05 +0200
+Subject: staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()
+
+From: Alexandru Hossu <hossu.alexandru@gmail.com>
+
+commit a1fc19d61f661d47204f095b593de507884849f7 upstream.
+
+OnAuth() has two bugs in the shared-key authentication path.
+
+When the Privacy bit is set, rtw_wep_decrypt() is called without
+verifying that the frame is long enough to contain a valid WEP IV and
+ICV. Inside rtw_wep_decrypt(), length is computed as:
+
+ length = len - WLAN_HDR_A3_LEN - iv_len
+
+and then passed as (length - 4) to crc32_le(). If len is less than
+WLAN_HDR_A3_LEN + iv_len + icv_len (32 bytes), length - 4 is negative
+and, after the implicit cast to size_t, causes crc32_le() to read far
+beyond the frame buffer. Add a minimum length check before accessing
+the IV field and calling the decryption path.
+
+When processing a seq=3 response, rtw_get_ie() stores the Challenge
+Text IE length in ie_len, but the subsequent memcmp() always reads 128
+bytes regardless of ie_len. IEEE 802.11 mandates a challenge text of
+exactly 128 bytes; reject any IE whose length field differs, matching
+the check already applied to OnAuthClient().
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Alexandru Hossu <hossu.alexandru@gmail.com>
+Link: https://patch.msgid.link/20260522004605.1039209-1-hossu.alexandru@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -687,6 +687,9 @@ unsigned int OnAuth(struct adapter *pada
+ if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ return _FAIL;
+
++ if (len < WLAN_HDR_A3_LEN)
++ return _FAIL;
++
+ sa = GetAddr2Ptr(pframe);
+
+ auth_mode = psecuritypriv->dot11AuthAlgrthm;
+@@ -698,6 +701,9 @@ unsigned int OnAuth(struct adapter *pada
+ prxattrib->hdrlen = WLAN_HDR_A3_LEN;
+ prxattrib->encrypt = _WEP40_;
+
++ if (len < WLAN_HDR_A3_LEN + 8)
++ return _FAIL;
++
+ iv = pframe+prxattrib->hdrlen;
+ prxattrib->key_index = ((iv[3]>>6)&0x3);
+
+@@ -802,7 +808,7 @@ unsigned int OnAuth(struct adapter *pada
+ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, WLAN_EID_CHALLENGE, (int *)&ie_len,
+ len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
+
+- if (!p || ie_len <= 0) {
++ if (!p || ie_len != 128) {
+ status = WLAN_STATUS_CHALLENGE_FAIL;
+ goto auth_fail;
+ }
--- /dev/null
+From 9f32f38265014fac7f5dc9490fb01a638ce6e121 Mon Sep 17 00:00:00 2001
+From: Michael Tautschnig <tautschn@amazon.com>
+Date: Thu, 18 Jun 2026 13:47:09 +0200
+Subject: staging: vme_user: bound slave read/write to the kern_buf size
+
+From: Michael Tautschnig <tautschn@amazon.com>
+
+commit 9f32f38265014fac7f5dc9490fb01a638ce6e121 upstream.
+
+The SLAVE-path helpers buffer_to_user() and buffer_from_user() copy
+'count' bytes into/out of the fixed-size kern_buf (size_buf ==
+PCI_BUF_SIZE == 0x20000, 128 KiB) using *ppos as the offset, without
+bounding *ppos + count against size_buf.
+
+vme_user_write()/vme_user_read() only clamp count to the VME window size
+(image_size = vme_get_size(resource)), which VME_SET_SLAVE sets from the
+user-supplied slave.size -- validated against the VME address space (up
+to VME_A32_MAX = 4 GiB), not against PCI_BUF_SIZE. When the window
+exceeds 128 KiB, a write()/read() copies past the kern_buf allocation.
+
+Clamp count against size_buf in both helpers, with an early return when
+*ppos is already at/after the buffer end. *ppos is >= 0 here (the caller
+rejects negative offsets), so size_buf - *ppos cannot wrap. This mirrors
+the existing clamp in the MASTER-path helpers resource_to_user() /
+resource_from_user(), and matches the read()/write() convention of a
+short transfer at end-of-buffer.
+
+Found by static analysis (CodeQL taint tracking + CBMC bounded model
+checking) and confirmed dynamically under KASAN with the vme_fake bridge:
+
+ BUG: KASAN: slab-out-of-bounds in _copy_from_user+0x2d/0x80
+ Write of size 262144 at addr ffff888004100000 by task trigger/68
+ _copy_from_user+0x2d/0x80
+ vme_user_write+0x13e/0x240 [vme_user]
+ vfs_write+0x1b8/0x7a0
+ ksys_write+0xb8/0x150
+
+Fixes: f00a86d98a1e ("Staging: vme: add VME userspace driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Michael Tautschnig <tautschn@amazon.com>
+Link: https://patch.msgid.link/20260618114709.72499-1-tautschn@amazon.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/vme_user/vme_user.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/drivers/staging/vme_user/vme_user.c
++++ b/drivers/staging/vme_user/vme_user.c
+@@ -156,6 +156,17 @@ static ssize_t buffer_to_user(unsigned i
+ {
+ void *image_ptr;
+
++ /*
++ * The slave window (image_size) can exceed the fixed kern_buf
++ * (size_buf == PCI_BUF_SIZE), so bound the copy to kern_buf.
++ * *ppos is >= 0 here (checked by the caller), so the
++ * subtraction below cannot wrap.
++ */
++ if (*ppos >= image[minor].size_buf)
++ return 0;
++ if (count > image[minor].size_buf - *ppos)
++ count = image[minor].size_buf - *ppos;
++
+ image_ptr = image[minor].kern_buf + *ppos;
+ if (copy_to_user(buf, image_ptr, (unsigned long)count))
+ return -EFAULT;
+@@ -168,6 +179,17 @@ static ssize_t buffer_from_user(unsigned
+ {
+ void *image_ptr;
+
++ /*
++ * The slave window (image_size) can exceed the fixed kern_buf
++ * (size_buf == PCI_BUF_SIZE), so bound the copy to kern_buf.
++ * *ppos is >= 0 here (checked by the caller), so the
++ * subtraction below cannot wrap.
++ */
++ if (*ppos >= image[minor].size_buf)
++ return 0;
++ if (count > image[minor].size_buf - *ppos)
++ count = image[minor].size_buf - *ppos;
++
+ image_ptr = image[minor].kern_buf + *ppos;
+ if (copy_from_user(image_ptr, buf, (unsigned long)count))
+ return -EFAULT;
--- /dev/null
+From e8422d89e8af41d87f0e9db564be8e2634f4c602 Mon Sep 17 00:00:00 2001
+From: Hao-Qun Huang <alvinhuang0603@gmail.com>
+Date: Sat, 4 Jul 2026 14:58:15 +0800
+Subject: staging: vme_user: fix location monitor leak in fake bridge
+
+From: Hao-Qun Huang <alvinhuang0603@gmail.com>
+
+commit e8422d89e8af41d87f0e9db564be8e2634f4c602 upstream.
+
+fake_init() allocates a location monitor resource and links it into
+fake_bridge->lm_resources. The init error path frees this list, but
+fake_exit() only frees the slave and master resource lists. Loading
+and unloading the module therefore triggers a kmemleak warning:
+
+ unreferenced object 0xffff8b8b82aebe40 (size 64):
+ comm "init", pid 1, jiffies 4294894572
+ backtrace (crc c1e013ef):
+ kmemleak_alloc+0x4e/0x90
+ __kmalloc_cache_noprof+0x338/0x430
+ 0xffffffffc0602246
+ do_one_initcall+0x4f/0x320
+ do_init_module+0x68/0x270
+ load_module+0x2a3b/0x2d90
+
+Free the lm_resources list in fake_exit() as well, before fake_bridge
+is freed.
+
+Fixes: 658bcdae9c67 ("vme: Adding Fake VME driver")
+Cc: stable <stable@kernel.org>
+Cc: Martyn Welch <martyn@welchs.me.uk>
+Assisted-by: Claude:claude-fable-5
+Signed-off-by: Hao-Qun Huang <alvinhuang0603@gmail.com>
+Link: https://patch.msgid.link/20260704065817.403111-1-alvinhuang0603@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/vme_user/vme_fake.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/staging/vme_user/vme_fake.c
++++ b/drivers/staging/vme_user/vme_fake.c
+@@ -1239,6 +1239,7 @@ static void __exit fake_exit(void)
+ {
+ struct list_head *pos = NULL;
+ struct list_head *tmplist;
++ struct vme_lm_resource *lm;
+ struct vme_master_resource *master_image;
+ struct vme_slave_resource *slave_image;
+ int i;
+@@ -1269,6 +1270,13 @@ static void __exit fake_exit(void)
+
+ fake_crcsr_exit(fake_bridge);
+ /* resources are stored in link list */
++ list_for_each_safe(pos, tmplist, &fake_bridge->lm_resources) {
++ lm = list_entry(pos, struct vme_lm_resource, list);
++ list_del(pos);
++ kfree(lm);
++ }
++
++ /* resources are stored in link list */
+ list_for_each_safe(pos, tmplist, &fake_bridge->slave_resources) {
+ slave_image = list_entry(pos, struct vme_slave_resource, list);
+ list_del(pos);
--- /dev/null
+From 151edde741f8bc7f2931c5f44ab376d32b0c8beb Mon Sep 17 00:00:00 2001
+From: Hao-Qun Huang <alvinhuang0603@gmail.com>
+Date: Sat, 4 Jul 2026 14:58:16 +0800
+Subject: staging: vme_user: fix location monitor leak in tsi148 bridge
+
+From: Hao-Qun Huang <alvinhuang0603@gmail.com>
+
+commit 151edde741f8bc7f2931c5f44ab376d32b0c8beb upstream.
+
+tsi148_probe() allocates a location monitor resource and links it into
+tsi148_bridge->lm_resources. The probe error path frees this list, but
+tsi148_remove() only frees the dma, slave and master resource lists, so
+the location monitor resource is leaked on device unbind or module
+unload.
+
+Free the lm_resources list in tsi148_remove() as well, before
+tsi148_bridge is freed.
+
+Fixes: d22b8ed9a3b0 ("Staging: vme: add Tundra TSI148 VME-PCI Bridge driver")
+Cc: stable <stable@kernel.org>
+Cc: Martyn Welch <martyn@welchs.me.uk>
+Assisted-by: Claude:claude-fable-5
+Signed-off-by: Hao-Qun Huang <alvinhuang0603@gmail.com>
+Link: https://patch.msgid.link/20260704065817.403111-2-alvinhuang0603@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/vme_user/vme_tsi148.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/staging/vme_user/vme_tsi148.c
++++ b/drivers/staging/vme_user/vme_tsi148.c
+@@ -2534,6 +2534,7 @@ static void tsi148_remove(struct pci_dev
+ {
+ struct list_head *pos = NULL;
+ struct list_head *tmplist;
++ struct vme_lm_resource *lm;
+ struct vme_master_resource *master_image;
+ struct vme_slave_resource *slave_image;
+ struct vme_dma_resource *dma_ctrlr;
+@@ -2591,6 +2592,13 @@ static void tsi148_remove(struct pci_dev
+ tsi148_crcsr_exit(tsi148_bridge, pdev);
+
+ /* resources are stored in link list */
++ list_for_each_safe(pos, tmplist, &tsi148_bridge->lm_resources) {
++ lm = list_entry(pos, struct vme_lm_resource, list);
++ list_del(pos);
++ kfree(lm);
++ }
++
++ /* resources are stored in link list */
+ list_for_each_safe(pos, tmplist, &tsi148_bridge->dma_resources) {
+ dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
+ list_del(pos);
--- /dev/null
+From 8bc4d43bccbd60efe85d0a44d5bf41762f2f0c30 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Thu, 25 Jun 2026 19:21:39 +0100
+Subject: tcp: restore RCU grace period in tcp_ao_destroy_sock
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 8bc4d43bccbd60efe85d0a44d5bf41762f2f0c30 upstream.
+
+Commit 51e547e8c89c ("tcp: Free TCP-AO/TCP-MD5 info/keys without RCU")
+removed the call_rcu() callback from tcp_ao_destroy_sock(), arguing that
+"the destruction of info/keys is delayed until the socket destructor"
+and therefore "no one can discover it anymore".
+
+That argument does not hold for the call site in tcp_connect()
+(net/ipv4/tcp_output.c:4327-4332). At that point the socket is in
+TCP_SYN_SENT, has already been inserted into the inet ehash by
+inet_hash_connect() in tcp_v4_connect(), and is therefore very much
+discoverable: any softirq running tcp_v4_rcv() on another CPU can take
+the socket out of the ehash, walk into tcp_inbound_hash(), and load
+tp->ao_info via implicit RCU before bh_lock_sock_nested() is taken on
+the destroying CPU.
+
+The reader path then enters __tcp_ao_do_lookup() (net/ipv4/tcp_ao.c:208)
+which re-loads tp->ao_info via rcu_dereference_check(); the re-load can
+still observe the (about-to-be-freed) pointer because there is no
+synchronize_rcu() between rcu_assign_pointer(tp->ao_info, NULL) and
+tcp_ao_info_free() in tcp_ao_destroy_sock(). The captured pointer is
+then walked at line 223:
+
+ hlist_for_each_entry_rcu(key, &ao->head, node, ...)
+
+The writer's synchronous kfree() is free to complete between the line
+218 re-fetch and the line 223 hlist iteration. The slab is reused
+(or simply LIST_POISON1-stamped if not yet reused) and the iteration
+walks attacker-controlled or poison memory in softirq context.
+
+Reproducer (no debug shim, stock x86_64 v7.1-rc2 SMP+KASAN, QEMU+KVM):
+an unprivileged uid=1000 process inside CLONE_NEWUSER|CLONE_NEWNET
+installs TCP_MD5SIG + TCP_AO_ADD_KEY on a TCP socket, sprays forged
+TCP-AO segments toward its eventual 4-tuple via raw sockets, then
+calls connect(). The md5-wins reconciliation in tcp_connect() fires
+tcp_ao_destroy_sock(); the softirq backlog reader on the loopback
+NAPI path crashes on the freed ao->head.first walk:
+
+ Oops: general protection fault, probably for non-canonical
+ address 0xfbd59c000000002f
+ KASAN: maybe wild-memory-access in range
+ [0xdead000000000178-0xdead00000000017f]
+ CPU: 0 UID: 1000 PID: 100 Comm: repro_userns
+ RIP: 0010:__tcp_ao_do_lookup+0x107/0x1c0
+ Call Trace: <IRQ>
+ __tcp_ao_do_lookup+0x107/0x1c0
+ tcp_ao_inbound_lookup.constprop.0+0x12a/0x200
+ tcp_inbound_ao_hash+0x5ea/0x1520
+ tcp_inbound_hash+0x7ce/0x1240
+ tcp_v4_rcv+0x1e7a/0x3e10
+ ...
+
+Restore the RCU grace period: re-add struct rcu_head to tcp_ao_info
+and replace the synchronous tcp_ao_info_free() with a call_rcu()
+callback. Readers that captured tp->ao_info before rcu_assign_pointer
+NULLed it now see the object remain valid until rcu_read_unlock().
+With the patch applied the reproducer runs cleanly for 2000 iterations
+on the same kernel build.
+
+Fixes: 51e547e8c89c ("tcp: Free TCP-AO/TCP-MD5 info/keys without RCU")
+Cc: stable@vger.kernel.org # v6.18+
+Reviewed-by: Dmitry Safonov <dima@arista.com>
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Dmitry Safonov <0x7f454c46@gmail.com>
+Link: https://patch.msgid.link/20260625-tcp-md5-connect-v3-1-1fd313d6c1e0@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/tcp_ao.h | 1 +
+ net/ipv4/tcp_ao.c | 5 +++--
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/include/net/tcp_ao.h
++++ b/include/net/tcp_ao.h
+@@ -130,6 +130,7 @@ struct tcp_ao_info {
+ u32 snd_sne;
+ u32 rcv_sne;
+ refcount_t refcnt; /* Protects twsk destruction */
++ struct rcu_head rcu;
+ };
+
+ #ifdef CONFIG_TCP_MD5SIG
+--- a/net/ipv4/tcp_ao.c
++++ b/net/ipv4/tcp_ao.c
+@@ -270,8 +270,9 @@ static void tcp_ao_key_free_rcu(struct r
+ kfree_sensitive(key);
+ }
+
+-static void tcp_ao_info_free(struct tcp_ao_info *ao)
++static void tcp_ao_info_free_rcu(struct rcu_head *head)
+ {
++ struct tcp_ao_info *ao = container_of(head, struct tcp_ao_info, rcu);
+ struct tcp_ao_key *key;
+ struct hlist_node *n;
+
+@@ -311,7 +312,7 @@ void tcp_ao_destroy_sock(struct sock *sk
+
+ if (!twsk)
+ tcp_ao_sk_omem_free(sk, ao);
+- tcp_ao_info_free(ao);
++ call_rcu(&ao->rcu, tcp_ao_info_free_rcu);
+ }
+
+ void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, struct tcp_sock *tp)
--- /dev/null
+From 2b66974a1b6134a4bbc3bfed181f7418f688eb54 Mon Sep 17 00:00:00 2001
+From: Samuel Page <sam@bynar.io>
+Date: Thu, 25 Jun 2026 15:38:15 +0100
+Subject: tipc: fix out-of-bounds read in broadcast Gap ACK blocks
+
+From: Samuel Page <sam@bynar.io>
+
+commit 2b66974a1b6134a4bbc3bfed181f7418f688eb54 upstream.
+
+A broadcast PROTOCOL/STATE_MSG can carry a Gap ACK blocks record in its
+data area. tipc_get_gap_ack_blks() only verifies that the record's len
+field is self-consistent with its ugack_cnt/bgack_cnt counts
+(sz == struct_size(p, gacks, ugack_cnt + bgack_cnt)); it does not check
+that the record actually fits in the message data area, msg_data_sz().
+
+The unicast caller tipc_link_proto_rcv() bounds it ("if (glen > dlen)
+break;"), but the broadcast caller tipc_bcast_sync_rcv() discards the
+returned size, so tipc_link_advance_transmq() copies the record off the
+receive skb with an attacker-controlled count:
+
+ this_ga = kmemdup(ga, struct_size(ga, gacks, ga->bgack_cnt),
+ GFP_ATOMIC);
+
+A TIPC neighbour that negotiated TIPC_GAP_ACK_BLOCK triggers it with one
+ordinary broadcast STATE_MSG (msg_bc_ack_invalid() clear), sized so its
+data area is short, carrying a Gap ACK record with len = 0x400,
+bgack_cnt = 0xff and ugack_cnt = 0. len then equals
+struct_size(p, gacks, 255), so the consistency check passes and ga is
+non-NULL; kmemdup() reads struct_size(ga, gacks, 255) = 1024 bytes out
+of the much smaller skb:
+
+ BUG: KASAN: slab-out-of-bounds in kmemdup_noprof+0x48/0x60
+ Read of size 1024 at addr ffff0000c7030d38 by task poc864/69
+ Call trace:
+ kmemdup_noprof+0x48/0x60
+ tipc_link_advance_transmq+0x86c/0xb80
+ tipc_link_bc_ack_rcv+0x19c/0x1e0
+ tipc_bcast_sync_rcv+0x1c4/0x2c4
+ tipc_rcv+0x85c/0x1340
+ tipc_l2_rcv_msg+0xac/0x104
+ The buggy address belongs to the object at ffff0000c7030d00
+ which belongs to the cache skbuff_small_head of size 704
+ The buggy address is located 56 bytes inside of
+ allocated 704-byte region [ffff0000c7030d00, ffff0000c7030fc0)
+
+The copied-out bytes are subsequently consumed as gap/ack values, but
+the read is already out of bounds at the kmemdup() regardless of how
+they are used.
+
+The unicast STATE path drops such a message: "if (glen > dlen) break;"
+skips the rest of STATE_MSG handling and the skb is freed. Make the
+broadcast path drop it too. tipc_bcast_sync_rcv() now bounds the record
+against msg_data_sz() and, when it does not fit, reports it back through
+tipc_node_bc_sync_rcv() to tipc_rcv() so the skb is discarded rather than
+processed. ga is not cleared on this path: ga == NULL already means
+"legacy peer without Selective ACK", a distinct legitimate state.
+
+Fixes: d7626b5acff9 ("tipc: introduce Gap ACK blocks for broadcast link")
+Cc: stable@vger.kernel.org
+Signed-off-by: Samuel Page <sam@bynar.io>
+Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
+Link: https://patch.msgid.link/20260625143815.1525412-1-sam@bynar.io
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tipc/bcast.c | 22 ++++++++++++++--------
+ net/tipc/bcast.h | 2 +-
+ net/tipc/node.c | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 12 deletions(-)
+
+--- a/net/tipc/bcast.c
++++ b/net/tipc/bcast.c
+@@ -497,12 +497,13 @@ void tipc_bcast_ack_rcv(struct net *net,
+ */
+ int tipc_bcast_sync_rcv(struct net *net, struct tipc_link *l,
+ struct tipc_msg *hdr,
+- struct sk_buff_head *retrq)
++ struct sk_buff_head *retrq, bool *valid)
+ {
+ struct sk_buff_head *inputq = &tipc_bc_base(net)->inputq;
+ struct tipc_gap_ack_blks *ga;
+ struct sk_buff_head xmitq;
+ int rc = 0;
++ u16 glen;
+
+ __skb_queue_head_init(&xmitq);
+
+@@ -510,13 +511,18 @@ int tipc_bcast_sync_rcv(struct net *net,
+ if (msg_type(hdr) != STATE_MSG) {
+ tipc_link_bc_init_rcv(l, hdr);
+ } else if (!msg_bc_ack_invalid(hdr)) {
+- tipc_get_gap_ack_blks(&ga, l, hdr, false);
+- if (!sysctl_tipc_bc_retruni)
+- retrq = &xmitq;
+- rc = tipc_link_bc_ack_rcv(l, msg_bcast_ack(hdr),
+- msg_bc_gap(hdr), ga, &xmitq,
+- retrq);
+- rc |= tipc_link_bc_sync_rcv(l, hdr, &xmitq);
++ glen = tipc_get_gap_ack_blks(&ga, l, hdr, false);
++ if (glen > msg_data_sz(hdr)) {
++ /* Malformed Gap ACK blocks; caller drops the msg */
++ *valid = false;
++ } else {
++ if (!sysctl_tipc_bc_retruni)
++ retrq = &xmitq;
++ rc = tipc_link_bc_ack_rcv(l, msg_bcast_ack(hdr),
++ msg_bc_gap(hdr), ga, &xmitq,
++ retrq);
++ rc |= tipc_link_bc_sync_rcv(l, hdr, &xmitq);
++ }
+ }
+ tipc_bcast_unlock(net);
+
+--- a/net/tipc/bcast.h
++++ b/net/tipc/bcast.h
+@@ -97,7 +97,7 @@ void tipc_bcast_ack_rcv(struct net *net,
+ struct tipc_msg *hdr);
+ int tipc_bcast_sync_rcv(struct net *net, struct tipc_link *l,
+ struct tipc_msg *hdr,
+- struct sk_buff_head *retrq);
++ struct sk_buff_head *retrq, bool *valid);
+ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg,
+ struct tipc_link *bcl);
+ int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[]);
+--- a/net/tipc/node.c
++++ b/net/tipc/node.c
+@@ -1831,12 +1831,15 @@ static void tipc_node_mcast_rcv(struct t
+ }
+
+ static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr,
+- int bearer_id, struct sk_buff_head *xmitq)
++ int bearer_id, struct sk_buff_head *xmitq,
++ bool *valid)
+ {
+ struct tipc_link *ucl;
+ int rc;
+
+- rc = tipc_bcast_sync_rcv(n->net, n->bc_entry.link, hdr, xmitq);
++ rc = tipc_bcast_sync_rcv(n->net, n->bc_entry.link, hdr, xmitq, valid);
++ if (!*valid)
++ return;
+
+ if (rc & TIPC_LINK_DOWN_EVT) {
+ tipc_node_reset_links(n);
+@@ -2140,12 +2143,18 @@ rcv:
+
+ /* Ensure broadcast reception is in synch with peer's send state */
+ if (unlikely(usr == LINK_PROTOCOL)) {
++ bool valid = true;
++
+ if (unlikely(skb_linearize(skb))) {
+ tipc_node_put(n);
+ goto discard;
+ }
+ hdr = buf_msg(skb);
+- tipc_node_bc_sync_rcv(n, hdr, bearer_id, &xmitq);
++ tipc_node_bc_sync_rcv(n, hdr, bearer_id, &xmitq, &valid);
++ if (!valid) {
++ tipc_node_put(n);
++ goto discard;
++ }
+ } else if (unlikely(tipc_link_acked(n->bc_entry.link) != bc_ack)) {
+ tipc_bcast_ack_rcv(net, n->bc_entry.link, hdr);
+ }
--- /dev/null
+From c3e94604675e3db186111b8942650d86577df9b0 Mon Sep 17 00:00:00 2001
+From: Yuanhe Shu <xiangzao@linux.alibaba.com>
+Date: Wed, 24 Jun 2026 14:17:15 +0800
+Subject: tracing: Fix NULL pointer dereference in func_set_flag()
+
+From: Yuanhe Shu <xiangzao@linux.alibaba.com>
+
+commit c3e94604675e3db186111b8942650d86577df9b0 upstream.
+
+func_set_flag() dereferences tr->current_trace_flags before verifying
+that the current tracer is actually the function tracer. When the active
+tracer has been switched away from "function" (e.g., to "wakeup_rt"),
+tr->current_trace_flags can be NULL, leading to a NULL pointer
+dereference and kernel crash.
+
+The call chain that triggers this is:
+
+ trace_options_write()
+ -> __set_tracer_option()
+ -> trace->set_flag() /* func_set_flag */
+
+In func_set_flag(), the first operation is:
+
+ if (!!set == !!(tr->current_trace_flags->val & bit))
+
+This dereferences tr->current_trace_flags unconditionally. The safety
+check that guards against a non-function tracer:
+
+ if (tr->current_trace != &function_trace)
+ return 0;
+
+is placed *after* the dereference, which is too late.
+
+This was observed with the following crash dump:
+
+ BUG: unable to handle page fault at 0000000000000000
+ RIP: func_set_flag+0xd
+
+ Call Trace:
+ __set_tracer_option+0x27
+ trace_options_write+0x75
+ vfs_write+0x12a
+ ksys_write+0x66
+ do_syscall_64+0x5b
+
+ RIP: ffffffff914c973d RSP: ff67ec88b01dfdf0 RFLAGS: 00010202
+ RAX: 0000000000000000 RBX: ff3a826e80354580 RCX: 0000000000000001
+ RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffffffff93918080
+
+The disassembly confirms the fault:
+
+ func_set_flag+0: mov 0x1f08(%rdi), %rax ; RAX = tr->current_trace_flags = NULL
+ func_set_flag+13: mov (%rax), %eax ; page fault: dereference NULL
+
+At the time of the crash:
+ tr->current_trace_flags = 0x0 (NULL)
+ tr->current_trace = wakeup_rt_tracer (not function_trace)
+
+The scenario is that a process opens a function tracer option file (such
+as "func_stack_trace"), then the current tracer is switched to another
+tracer (e.g., "wakeup_rt"), which sets current_trace_flags to NULL. When
+the process subsequently writes to the option file, func_set_flag() is
+invoked and crashes on the NULL dereference.
+
+Fix this by moving the current_trace check before the
+current_trace_flags dereference, so that func_set_flag() returns early
+when the function tracer is not active.
+
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260624061715.1445655-1-xiangzao@linux.alibaba.com
+Fixes: 76680d0d2825 ("tracing: Have function tracer define options per instance")
+Signed-off-by: Yuanhe Shu <xiangzao@linux.alibaba.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_functions.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/kernel/trace/trace_functions.c
++++ b/kernel/trace/trace_functions.c
+@@ -458,12 +458,12 @@ func_set_flag(struct trace_array *tr, u3
+ ftrace_func_t func;
+ u32 new_flags;
+
+- /* Do nothing if already set. */
+- if (!!set == !!(tr->current_trace_flags->val & bit))
++ /* We can change this flag only when current tracer is function. */
++ if (tr->current_trace != &function_trace)
+ return 0;
+
+- /* We can change this flag only when not running. */
+- if (tr->current_trace != &function_trace)
++ /* Do nothing if already set. */
++ if (!!set == !!(tr->current_trace_flags->val & bit))
+ return 0;
+
+ new_flags = (tr->current_trace_flags->val & ~bit) | (set ? bit : 0);
--- /dev/null
+From abf76d3239dee97b66e7241ad04811f1ce562e28 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 9 Jun 2026 13:37:36 -0400
+Subject: USB: chaoskey: Fix slab-use-after-free in chaoskey_release()
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit abf76d3239dee97b66e7241ad04811f1ce562e28 upstream.
+
+The chaoskey driver has a use-after-free bug in its release routine.
+If the user closes the device file after the USB device has been
+unplugged, a debugging log statement will try to access the
+usb_interface structure after it has been deallocated:
+
+ BUG: KASAN: slab-use-after-free in dev_driver_string (drivers/base/core.c:2406)
+ Read of size 8 at addr ffff888168e8a0b8 by task chaoskey_raw_re/10106
+
+ Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+ Call Trace:
+ <TASK>
+ dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
+ print_report (mm/kasan/report.c:378 mm/kasan/report.c:482)
+ kasan_report (mm/kasan/report.c:595)
+ dev_driver_string (drivers/base/core.c:2406)
+ __dynamic_dev_dbg (lib/dynamic_debug.c:906)
+ chaoskey_release (drivers/usb/misc/chaoskey.c:323)
+ __fput (fs/file_table.c:510)
+ fput_close_sync (fs/file_table.c:615)
+ __x64_sys_close (fs/open.c:1507 fs/open.c:1492 fs/open.c:1492)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+The driver's last reference to the interface structure is dropped in
+the chaoskey_free() routine, so the code must not use the interface --
+even in a debugging statement -- after that routine returns.
+(Exception: If we know that another reference is held by someone else,
+such as the device core while the disconnect routine runs, there's no
+problem. Thanks to Johan Hovold for pointing this out.)
+
+Since the bad access is part of an unimportant debugging statement,
+we can fix the problem simply by removing the whole statement.
+
+Reported-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
+Closes: https://lore.kernel.org/linux-usb/20EC9664-054E-438B-B411-2145D347F97B@gmail.com/
+Tested-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Fixes: 66e3e591891d ("usb: Add driver for Altus Metrum ChaosKey device (v2)")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/bb5b1dc6-eb59-43e1-8d26-51e658e88bbe@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/chaoskey.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -320,7 +320,6 @@ bail:
+ mutex_unlock(&dev->lock);
+ destruction:
+ mutex_unlock(&chaoskey_list_lock);
+- usb_dbg(interface, "release success");
+ return rv;
+ }
+
--- /dev/null
+From 010382937fb69892b3469ac4d30af072262f59e8 Mon Sep 17 00:00:00 2001
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Date: Fri, 12 Jun 2026 13:20:05 +0800
+Subject: usb: dwc3: run gadget disconnect from sleepable suspend context
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+commit 010382937fb69892b3469ac4d30af072262f59e8 upstream.
+
+dwc3_gadget_suspend() takes dwc->lock with IRQs disabled and then calls
+dwc3_disconnect_gadget(). For async callbacks that helper only uses
+plain spin_unlock()/spin_lock(), so the gadget ->disconnect() callback
+still runs with IRQs disabled and any sleepable callback trips Lockdep.
+
+This issue was found by our static analysis tool and then manually
+reviewed against the current tree.
+
+The grounded PoC kept the dwc3_gadget_suspend() ->
+dwc3_disconnect_gadget() -> gadget_driver->disconnect() chain, and
+Lockdep reported:
+
+ BUG: sleeping function called from invalid context
+ gadget_disconnect+0x21/0x39 [vuln_msv]
+ dwc3_gadget_suspend.constprop.0+0x2b/0x42 [vuln_msv]
+
+Keep the disconnect callback selection in one common helper, but add a
+sleepable suspend-side wrapper which snapshots the callback under
+dwc->lock and then runs it after spin_unlock_irqrestore(). The regular
+event path still uses the existing spin_unlock()/spin_lock() window.
+
+Fixes: c8540870af4c ("usb: dwc3: gadget: Improve dwc3_gadget_suspend() and dwc3_gadget_resume()")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://patch.msgid.link/20260612052005.3849659-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c | 43 ++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 36 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -3934,15 +3934,48 @@ static void dwc3_endpoint_interrupt(stru
+ }
+ }
+
++static bool dwc3_prepare_disconnect_gadget(struct dwc3 *dwc,
++ struct usb_gadget_driver **driver,
++ struct usb_gadget **gadget)
++{
++ if (!dwc->async_callbacks || !dwc->gadget_driver ||
++ !dwc->gadget_driver->disconnect)
++ return false;
++
++ *driver = dwc->gadget_driver;
++ *gadget = dwc->gadget;
++
++ return true;
++}
++
+ static void dwc3_disconnect_gadget(struct dwc3 *dwc)
+ {
+- if (dwc->async_callbacks && dwc->gadget_driver->disconnect) {
++ struct usb_gadget_driver *driver;
++ struct usb_gadget *gadget;
++
++ if (dwc3_prepare_disconnect_gadget(dwc, &driver, &gadget)) {
+ spin_unlock(&dwc->lock);
+- dwc->gadget_driver->disconnect(dwc->gadget);
++ driver->disconnect(gadget);
+ spin_lock(&dwc->lock);
+ }
+ }
+
++static void dwc3_disconnect_gadget_sleepable(struct dwc3 *dwc)
++{
++ struct usb_gadget_driver *driver;
++ struct usb_gadget *gadget;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ if (!dwc3_prepare_disconnect_gadget(dwc, &driver, &gadget)) {
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return;
++ }
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ driver->disconnect(gadget);
++}
++
+ static void dwc3_suspend_gadget(struct dwc3 *dwc)
+ {
+ if (dwc->async_callbacks && dwc->gadget_driver->suspend) {
+@@ -4838,7 +4871,6 @@ EXPORT_SYMBOL_GPL(dwc3_gadget_exit);
+
+ int dwc3_gadget_suspend(struct dwc3 *dwc)
+ {
+- unsigned long flags;
+ int ret;
+
+ ret = dwc3_gadget_soft_disconnect(dwc);
+@@ -4852,10 +4884,7 @@ int dwc3_gadget_suspend(struct dwc3 *dwc
+ return -EAGAIN;
+ }
+
+- spin_lock_irqsave(&dwc->lock, flags);
+- if (dwc->gadget_driver)
+- dwc3_disconnect_gadget(dwc);
+- spin_unlock_irqrestore(&dwc->lock, flags);
++ dwc3_disconnect_gadget_sleepable(dwc);
+
+ return 0;
+ }
--- /dev/null
+From 0bfeec21984fedd32987f4e4c0cde34b445af404 Mon Sep 17 00:00:00 2001
+From: Cen Zhang <zzzccc427@gmail.com>
+Date: Thu, 18 Jun 2026 20:40:29 +0800
+Subject: usb: misc: usbio: fix disconnect UAF in client teardown
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+commit 0bfeec21984fedd32987f4e4c0cde34b445af404 upstream.
+
+usbio_disconnect() walks usbio->cli_list in reverse and uninitializes each
+auxiliary device. auxiliary_device_uninit() drops the device reference, and
+for an unbound child that can run usbio_auxdev_release() and free the
+containing struct usbio_client.
+
+list_for_each_entry_reverse() advances after the loop body by reading
+client->link.prev. If the current client is freed by
+auxiliary_device_uninit(), the iterator dereferences freed memory.
+
+Use list_for_each_entry_safe_reverse() so the previous client is
+cached before the body can drop the final reference. This preserves
+reverse teardown order while keeping the next iterator cursor independent
+of the current client's lifetime.
+
+Validation reproduced this kernel report:
+BUG: KASAN: slab-use-after-free in usbio_disconnect+0x12e/0x150
+
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x630
+ ? usbio_disconnect+0x12e/0x150
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? __virt_addr_valid+0x188/0x320
+ ? usbio_disconnect+0x12e/0x150
+ kasan_report+0xe0/0x110
+ ? usbio_disconnect+0x12e/0x150
+ usbio_disconnect+0x12e/0x150
+ usb_unbind_interface+0xf3/0x400
+ really_probe+0x316/0x660
+ __driver_probe_device+0x106/0x240
+ driver_probe_device+0x4a/0x110
+ __device_attach_driver+0xf1/0x1a0
+ ? __pfx___device_attach_driver+0x10/0x10
+ bus_for_each_drv+0xf9/0x160
+ ? __pfx_bus_for_each_drv+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? trace_hardirqs_on+0x18/0x130
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? _raw_spin_unlock_irqrestore+0x44/0x60
+ __device_attach+0x133/0x2a0
+ ? __pfx___device_attach+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? do_raw_spin_unlock+0x9a/0x100
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ device_initial_probe+0x55/0x70
+ bus_probe_device+0x4a/0xd0
+ device_add+0x9b9/0xc10
+ ? __pfx_device_add+0x10/0x10
+ ? _raw_spin_unlock_irqrestore+0x44/0x60
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? lockdep_hardirqs_on_prepare+0xea/0x1a0
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? usb_enable_lpm+0x3c/0x260
+ usb_set_configuration+0xb64/0xf20
+ usb_generic_driver_probe+0x5f/0x90
+ usb_probe_device+0x71/0x1b0
+ really_probe+0x46b/0x660
+ __driver_probe_device+0x106/0x240
+ driver_probe_device+0x4a/0x110
+ __device_attach_driver+0xf1/0x1a0
+ ? __pfx___device_attach_driver+0x10/0x10
+ bus_for_each_drv+0xf9/0x160
+ ? __pfx_bus_for_each_drv+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? trace_hardirqs_on+0x18/0x130
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? _raw_spin_unlock_irqrestore+0x44/0x60
+ __device_attach+0x133/0x2a0
+ ? __pfx___device_attach+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? do_raw_spin_unlock+0x9a/0x100
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ device_initial_probe+0x55/0x70
+ bus_probe_device+0x4a/0xd0
+ device_add+0x9b9/0xc10
+ ? __pfx_device_add+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? add_device_randomness+0xb7/0xf0
+ usb_new_device+0x492/0x870
+ hub_event+0x1b10/0x29c0
+ ? __pfx_hub_event+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? lock_acquire+0x187/0x300
+ ? process_one_work+0x475/0xb90
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? lock_release+0xc8/0x290
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ process_one_work+0x4d7/0xb90
+ ? __pfx_process_one_work+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? __list_add_valid_or_report+0x37/0xf0
+ ? __pfx_hub_event+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ worker_thread+0x2d8/0x570
+ ? __pfx_worker_thread+0x10/0x10
+ kthread+0x1ad/0x1f0
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x3c9/0x540
+ ? __pfx_ret_from_fork+0x10/0x10
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? __switch_to+0x2e9/0x730
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Fixes: 121a0f839dbb ("usb: misc: Add Intel USBIO bridge driver")
+Cc: stable <stable@kernel.org>
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Link: https://patch.msgid.link/20260618124029.3704089-1-zzzccc427@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/usbio.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/usbio.c
++++ b/drivers/usb/misc/usbio.c
+@@ -518,7 +518,7 @@ static int usbio_resume(struct usb_inter
+ static void usbio_disconnect(struct usb_interface *intf)
+ {
+ struct usbio_device *usbio = usb_get_intfdata(intf);
+- struct usbio_client *client;
++ struct usbio_client *client, *next;
+
+ /* Wakeup any clients waiting for a reply */
+ usbio->rxdat_len = 0;
+@@ -535,7 +535,7 @@ static void usbio_disconnect(struct usb_
+ usb_kill_urb(usbio->urb);
+ usb_free_urb(usbio->urb);
+
+- list_for_each_entry_reverse(client, &usbio->cli_list, link) {
++ list_for_each_entry_safe_reverse(client, next, &usbio->cli_list, link) {
+ auxiliary_device_delete(&client->auxdev);
+ auxiliary_device_uninit(&client->auxdev);
+ }
--- /dev/null
+From c687bc35694698ec4c7f92bf929c3d659f0cecb8 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 27 Apr 2026 16:37:10 +0200
+Subject: virtio-mmio: fix device release warning on module unload
+
+From: Johan Hovold <johan@kernel.org>
+
+commit c687bc35694698ec4c7f92bf929c3d659f0cecb8 upstream.
+
+Driver core expects devices to be allocated dynamically and complains
+loudly when a device that lacks a release function is freed.
+
+Use __root_device_register() to allocate and register the root device
+instead of open coding using a static device.
+
+Note that root_device_register(), which also creates a link to the
+module, cannot be used as the device is registered when parsing the
+module parameters which happens before the module kobject has been set
+up.
+
+Fixes: 81a054ce0b46 ("virtio-mmio: Devices parameter parsing")
+Cc: stable@vger.kernel.org # 3.5
+Cc: Pawel Moll <pawel.moll@arm.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-ID: <20260427143710.14702-1-johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/virtio/virtio_mmio.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+--- a/drivers/virtio/virtio_mmio.c
++++ b/drivers/virtio/virtio_mmio.c
+@@ -662,9 +662,7 @@ static void virtio_mmio_remove(struct pl
+
+ #if defined(CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES)
+
+-static struct device vm_cmdline_parent = {
+- .init_name = "virtio-mmio-cmdline",
+-};
++static struct device *vm_cmdline_parent;
+
+ static int vm_cmdline_parent_registered;
+ static int vm_cmdline_id;
+@@ -672,7 +670,6 @@ static int vm_cmdline_id;
+ static int vm_cmdline_set(const char *device,
+ const struct kernel_param *kp)
+ {
+- int err;
+ struct resource resources[2] = {};
+ char *str;
+ long long base, size;
+@@ -704,11 +701,10 @@ static int vm_cmdline_set(const char *de
+ resources[1].start = resources[1].end = irq;
+
+ if (!vm_cmdline_parent_registered) {
+- err = device_register(&vm_cmdline_parent);
+- if (err) {
+- put_device(&vm_cmdline_parent);
++ vm_cmdline_parent = __root_device_register("virtio-mmio-cmdline", NULL);
++ if (IS_ERR(vm_cmdline_parent)) {
+ pr_err("Failed to register parent device!\n");
+- return err;
++ return PTR_ERR(vm_cmdline_parent);
+ }
+ vm_cmdline_parent_registered = 1;
+ }
+@@ -719,7 +715,7 @@ static int vm_cmdline_set(const char *de
+ (unsigned long long)resources[0].end,
+ (int)resources[1].start);
+
+- pdev = platform_device_register_resndata(&vm_cmdline_parent,
++ pdev = platform_device_register_resndata(vm_cmdline_parent,
+ "virtio-mmio", vm_cmdline_id++,
+ resources, ARRAY_SIZE(resources), NULL, 0);
+
+@@ -743,8 +739,12 @@ static int vm_cmdline_get_device(struct
+ static int vm_cmdline_get(char *buffer, const struct kernel_param *kp)
+ {
+ buffer[0] = '\0';
+- device_for_each_child(&vm_cmdline_parent, buffer,
+- vm_cmdline_get_device);
++
++ if (vm_cmdline_parent_registered) {
++ device_for_each_child(vm_cmdline_parent, buffer,
++ vm_cmdline_get_device);
++ }
++
+ return strlen(buffer) + 1;
+ }
+
+@@ -766,9 +766,9 @@ static int vm_unregister_cmdline_device(
+ static void vm_unregister_cmdline_devices(void)
+ {
+ if (vm_cmdline_parent_registered) {
+- device_for_each_child(&vm_cmdline_parent, NULL,
++ device_for_each_child(vm_cmdline_parent, NULL,
+ vm_unregister_cmdline_device);
+- device_unregister(&vm_cmdline_parent);
++ root_device_unregister(vm_cmdline_parent);
+ vm_cmdline_parent_registered = 0;
+ }
+ }
--- /dev/null
+From f7d380fb525c13bdd114369a1979c80c346e6abc Mon Sep 17 00:00:00 2001
+From: Ammar Faizi <ammarfaizi2@openresty.com>
+Date: Sun, 15 Mar 2026 21:18:08 +0700
+Subject: virtio_pci: fix vq info pointer lookup via wrong index
+
+From: Ammar Faizi <ammarfaizi2@openresty.com>
+
+commit f7d380fb525c13bdd114369a1979c80c346e6abc upstream.
+
+Unbinding a virtio balloon device:
+
+ echo virtio0 > /sys/bus/virtio/drivers/virtio_balloon/unbind
+
+triggers a NULL pointer dereference. The dmesg says:
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000008
+ [...]
+ RIP: 0010:__list_del_entry_valid_or_report+0x5/0xf0
+ Call Trace:
+ <TASK>
+ vp_del_vqs+0x121/0x230
+ remove_common+0x135/0x150
+ virtballoon_remove+0xee/0x100
+ virtio_dev_remove+0x3b/0x80
+ device_release_driver_internal+0x187/0x2c0
+ unbind_store+0xb9/0xe0
+ kernfs_fop_write_iter.llvm.11660790530567441834+0xf6/0x180
+ vfs_write+0x2a9/0x3b0
+ ksys_write+0x5c/0xd0
+ do_syscall_64+0x54/0x230
+ entry_SYSCALL_64_after_hwframe+0x29/0x31
+ [...]
+ </TASK>
+
+The virtio_balloon device registers 5 queues (inflate, deflate, stats,
+free_page, reporting) but only the first two are unconditional. The
+stats, free_page and reporting queues are each conditional on their
+respective feature bits. When any of these features are absent, the
+corresponding vqs_info entry has name == NULL, creating holes in the
+array.
+
+The root cause is an indexing mismatch introduced when vq info storage
+was changed to be passed as an argument. vp_find_vqs_msix() and
+vp_find_vqs_intx() store the info pointer at vp_dev->vqs[i], where 'i'
+is the caller's sparse array index. However, the virtqueue itself gets
+vq->index assigned from queue_idx, a dense index that skips NULL
+entries. When holes exist, 'i' and queue_idx diverge. Later,
+vp_del_vqs() looks up info via vp_dev->vqs[vq->index] using the dense
+index into the sparsely-populated array, and hits NULL.
+
+Fix this by storing info at vp_dev->vqs[queue_idx] instead of
+vp_dev->vqs[i], so the store index matches the lookup index
+(vq->index). Apply the fix to both the MSIX and INTX paths.
+
+Cc: Yichun Zhang <yichun@openresty.com>
+Cc: Jiri Pirko <jiri@nvidia.com>
+Cc: stable@vger.kernel.org # v6.11+
+Tested-by: Yuka <yuka@umeyashiki.org>
+Fixes: 89a1c435aec2 ("virtio_pci: pass vq info as an argument to vp_setup_vq()")
+Signed-off-by: Ammar Faizi <ammarfaizi2@openresty.com>
+Message-Id: <20260315141808.547081-1-ammarfaizi2@openresty.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/virtio/virtio_pci_common.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/virtio/virtio_pci_common.c
++++ b/drivers/virtio/virtio_pci_common.c
+@@ -423,10 +423,11 @@ static int vp_find_vqs_msix(struct virti
+ vqs[i] = NULL;
+ continue;
+ }
+- vqs[i] = vp_find_one_vq_msix(vdev, queue_idx++, vqi->callback,
++ vqs[i] = vp_find_one_vq_msix(vdev, queue_idx, vqi->callback,
+ vqi->name, vqi->ctx, false,
+ &allocated_vectors, vector_policy,
+- &vp_dev->vqs[i]);
++ &vp_dev->vqs[queue_idx]);
++ queue_idx++;
+ if (IS_ERR(vqs[i])) {
+ err = PTR_ERR(vqs[i]);
+ goto error_find;
+@@ -485,9 +486,10 @@ static int vp_find_vqs_intx(struct virti
+ vqs[i] = NULL;
+ continue;
+ }
+- vqs[i] = vp_setup_vq(vdev, queue_idx++, vqi->callback,
++ vqs[i] = vp_setup_vq(vdev, queue_idx, vqi->callback,
+ vqi->name, vqi->ctx,
+- VIRTIO_MSI_NO_VECTOR, &vp_dev->vqs[i]);
++ VIRTIO_MSI_NO_VECTOR, &vp_dev->vqs[queue_idx]);
++ queue_idx++;
+ if (IS_ERR(vqs[i])) {
+ err = PTR_ERR(vqs[i]);
+ goto out_del_vqs;