]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 May 2026 08:47:03 +0000 (10:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 May 2026 08:47:03 +0000 (10:47 +0200)
added patches:
alsa-asihpi-fix-potential-oob-array-access-at-reading-cache.patch
alsa-pcm-don-t-setup-bogus-iov_iter-for-silencing.patch
alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch
alsa-ua101-reject-too-short-usb-descriptors.patch
bluetooth-bnep-fix-uaf-read-of-dev-name.patch
bluetooth-fix-uaf-in-l2cap_sock_cleanup_listen-vs-l2cap_conn_del.patch
bluetooth-hci_uart-fix-uafs-and-race-conditions-in-close-and-init-paths.patch
bluetooth-iso-drop-iso_end-frames-received-without-prior-iso_start.patch
bluetooth-l2cap-ecred_reconfigure-send-packed-pdu-not-stack-pointer.patch
bluetooth-mgmt-validate-add-extended-advertising-data-length.patch
bluetooth-serialize-accept_q-access.patch
drivers-base-memory-fix-memory-block-reference-leak-in-poison-accounting.patch
efi-allocate-runtime-workqueue-before-acpi-init.patch
hwmon-pmbus-adm1266-widen-blackbox-info-buffer-to-i2c_smbus_block_max.patch
io_uring-waitid-clear-waitid-info-before-copying-it-to-userspace.patch
ipv6-ioam-refresh-hdr-pointer-before-ioam6_event.patch
ksmbd-fix-null-pointer-dereference-in-compare_guid_key.patch
ksmbd-fix-sid-memory-leak-in-set_posix_acl_entries_dacl-on-overflow.patch
ksmbd-validate-sid-in-parent-security-descriptor-during-acl-inheritance.patch
mm-damon-sysfs-schemes-call-missing-mem_cgroup_iter_break.patch
mm-fix-__vm_normal_page-to-handle-missing-support-for-pmd_special-pud_special.patch
mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
mm-memory_hotplug-fix-memory-block-reference-leak-on-remove.patch
mm-page_alloc-fix-initialization-of-tags-of-the-huge-zero-folio-with-init_on_free.patch
net-bcmgenet-keep-rbuf-eee-pm-disabled.patch
net-ifb-report-ethtool-stats-over-num_tx_queues.patch
net-mlx5e-fix-use-after-free-in-mlx5e_tx_reporter_timeout_recover.patch
net-phy-skip-eee-advertisement-write-when-autoneg-is-disabled.patch
net-pse-pd-fix-sign-on-enoent-check-in-of_load_pse_pis.patch
net-wwan-iosm-fix-potential-memory-leaks-in-ipc_imem_init.patch
netfilter-ip6t_hbh-reject-oversized-option-lists.patch
netfilter-ipset-stop-hash-range-iteration-at-end.patch
netfilter-nf_queue-hold-bridge-skb-dev-while-queued.patch
netfilter-nft_inner-fix-ipv6-inner_thoff-desync.patch
phonet-pep-disable-bh-around-forwarded-sk_receive_skb.patch
regulator-tps65219-fix-irq_data.rdev-not-being-assigned.patch
selftests-mm-run_vmtests.sh-fix-destructive-tests-invocation.patch
smb-client-protect-tc_count-increment-in-smb2_find_smb_sess_tcon_unlocked.patch
smb-client-require-net-admin-for-cifs-swn-netlink.patch
smb-client-use-data_len-for-smb2-read-encrypted-folioq-copy.patch
smb-server-promote-s_del_on_cls-to-s_del_pending-when-close.patch
spi-amd-set-correct-bus-number-in-acpi-probe-path.patch
sysfs-don-t-remove-existing-directory-on-update-failure.patch

44 files changed:
queue-6.18/alsa-asihpi-fix-potential-oob-array-access-at-reading-cache.patch [new file with mode: 0644]
queue-6.18/alsa-pcm-don-t-setup-bogus-iov_iter-for-silencing.patch [new file with mode: 0644]
queue-6.18/alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch [new file with mode: 0644]
queue-6.18/alsa-ua101-reject-too-short-usb-descriptors.patch [new file with mode: 0644]
queue-6.18/bluetooth-bnep-fix-uaf-read-of-dev-name.patch [new file with mode: 0644]
queue-6.18/bluetooth-fix-uaf-in-l2cap_sock_cleanup_listen-vs-l2cap_conn_del.patch [new file with mode: 0644]
queue-6.18/bluetooth-hci_uart-fix-uafs-and-race-conditions-in-close-and-init-paths.patch [new file with mode: 0644]
queue-6.18/bluetooth-iso-drop-iso_end-frames-received-without-prior-iso_start.patch [new file with mode: 0644]
queue-6.18/bluetooth-l2cap-ecred_reconfigure-send-packed-pdu-not-stack-pointer.patch [new file with mode: 0644]
queue-6.18/bluetooth-mgmt-validate-add-extended-advertising-data-length.patch [new file with mode: 0644]
queue-6.18/bluetooth-serialize-accept_q-access.patch [new file with mode: 0644]
queue-6.18/drivers-base-memory-fix-memory-block-reference-leak-in-poison-accounting.patch [new file with mode: 0644]
queue-6.18/efi-allocate-runtime-workqueue-before-acpi-init.patch [new file with mode: 0644]
queue-6.18/hwmon-pmbus-adm1266-widen-blackbox-info-buffer-to-i2c_smbus_block_max.patch [new file with mode: 0644]
queue-6.18/io_uring-waitid-clear-waitid-info-before-copying-it-to-userspace.patch [new file with mode: 0644]
queue-6.18/ipv6-ioam-refresh-hdr-pointer-before-ioam6_event.patch [new file with mode: 0644]
queue-6.18/ksmbd-fix-null-pointer-dereference-in-compare_guid_key.patch [new file with mode: 0644]
queue-6.18/ksmbd-fix-sid-memory-leak-in-set_posix_acl_entries_dacl-on-overflow.patch [new file with mode: 0644]
queue-6.18/ksmbd-validate-sid-in-parent-security-descriptor-during-acl-inheritance.patch [new file with mode: 0644]
queue-6.18/mm-damon-sysfs-schemes-call-missing-mem_cgroup_iter_break.patch [new file with mode: 0644]
queue-6.18/mm-fix-__vm_normal_page-to-handle-missing-support-for-pmd_special-pud_special.patch [new file with mode: 0644]
queue-6.18/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch [new file with mode: 0644]
queue-6.18/mm-memory_hotplug-fix-memory-block-reference-leak-on-remove.patch [new file with mode: 0644]
queue-6.18/mm-page_alloc-fix-initialization-of-tags-of-the-huge-zero-folio-with-init_on_free.patch [new file with mode: 0644]
queue-6.18/net-bcmgenet-keep-rbuf-eee-pm-disabled.patch [new file with mode: 0644]
queue-6.18/net-ifb-report-ethtool-stats-over-num_tx_queues.patch [new file with mode: 0644]
queue-6.18/net-mlx5e-fix-use-after-free-in-mlx5e_tx_reporter_timeout_recover.patch [new file with mode: 0644]
queue-6.18/net-phy-skip-eee-advertisement-write-when-autoneg-is-disabled.patch [new file with mode: 0644]
queue-6.18/net-pse-pd-fix-sign-on-enoent-check-in-of_load_pse_pis.patch [new file with mode: 0644]
queue-6.18/net-wwan-iosm-fix-potential-memory-leaks-in-ipc_imem_init.patch [new file with mode: 0644]
queue-6.18/netfilter-ip6t_hbh-reject-oversized-option-lists.patch [new file with mode: 0644]
queue-6.18/netfilter-ipset-stop-hash-range-iteration-at-end.patch [new file with mode: 0644]
queue-6.18/netfilter-nf_queue-hold-bridge-skb-dev-while-queued.patch [new file with mode: 0644]
queue-6.18/netfilter-nft_inner-fix-ipv6-inner_thoff-desync.patch [new file with mode: 0644]
queue-6.18/phonet-pep-disable-bh-around-forwarded-sk_receive_skb.patch [new file with mode: 0644]
queue-6.18/regulator-tps65219-fix-irq_data.rdev-not-being-assigned.patch [new file with mode: 0644]
queue-6.18/selftests-mm-run_vmtests.sh-fix-destructive-tests-invocation.patch [new file with mode: 0644]
queue-6.18/series
queue-6.18/smb-client-protect-tc_count-increment-in-smb2_find_smb_sess_tcon_unlocked.patch [new file with mode: 0644]
queue-6.18/smb-client-require-net-admin-for-cifs-swn-netlink.patch [new file with mode: 0644]
queue-6.18/smb-client-use-data_len-for-smb2-read-encrypted-folioq-copy.patch [new file with mode: 0644]
queue-6.18/smb-server-promote-s_del_on_cls-to-s_del_pending-when-close.patch [new file with mode: 0644]
queue-6.18/spi-amd-set-correct-bus-number-in-acpi-probe-path.patch [new file with mode: 0644]
queue-6.18/sysfs-don-t-remove-existing-directory-on-update-failure.patch [new file with mode: 0644]

diff --git a/queue-6.18/alsa-asihpi-fix-potential-oob-array-access-at-reading-cache.patch b/queue-6.18/alsa-asihpi-fix-potential-oob-array-access-at-reading-cache.patch
new file mode 100644 (file)
index 0000000..c6877a4
--- /dev/null
@@ -0,0 +1,37 @@
+From 7b7d6572145c1dab2dd9bfb550b188e5f0ff3c3f Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 15 May 2026 10:55:58 +0200
+Subject: ALSA: asihpi: Fix potential OOB array access at reading cache
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 7b7d6572145c1dab2dd9bfb550b188e5f0ff3c3f upstream.
+
+find_control() to retrieve a cached info accesses the array with the
+given index blindly, which may lead to an OOB array access.
+Add a sanity check for avoiding it.
+
+Link: https://sashiko.dev/#/patchset/20260511230121.28606-1-rosenp%40gmail.com
+Cc: <stable@vger.kernel.org>
+Link: https://patch.msgid.link/20260515085606.242284-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/asihpi/hpicmn.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/sound/pci/asihpi/hpicmn.c
++++ b/sound/pci/asihpi/hpicmn.c
+@@ -276,6 +276,12 @@ static short find_control(u16 control_in
+               return 0;
+       }
++      if (control_index >= p_cache->control_count) {
++              HPI_DEBUG_LOG(VERBOSE, "control_index out of bounce %d\n",
++                      control_index);
++              return 0;
++      }
++
+       *pI = p_cache->p_info[control_index];
+       if (!*pI) {
+               HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
diff --git a/queue-6.18/alsa-pcm-don-t-setup-bogus-iov_iter-for-silencing.patch b/queue-6.18/alsa-pcm-don-t-setup-bogus-iov_iter-for-silencing.patch
new file mode 100644 (file)
index 0000000..770c541
--- /dev/null
@@ -0,0 +1,42 @@
+From e4d3386b74fba8e01280484b67ee481ece00201e Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Sun, 17 May 2026 18:51:20 +0200
+Subject: ALSA: pcm: Don't setup bogus iov_iter for silencing
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit e4d3386b74fba8e01280484b67ee481ece00201e upstream.
+
+At transition to the iov_iter for PCM data transfer, we blindly
+applied the iov_iter setup also for silencing (i.e. data = NULL), and
+it leads to a calculation of bogus iov_iter.  Fortunately this didn't
+cause troubles on most of architectures but it goes wrong on RISC-V
+now, causing a NULL dereference.
+
+Handle the NULL data case to treat the silencing in interleaved_copy()
+for addressing the bug above.  noninterleaved_copy() has already the
+NULL data handling, so it doesn't need changes.
+
+Reported-by: Jiakai Xu <xujiakai24@mails.ucas.ac.cn>
+Closes: https://lore.kernel.org/20260515051516.3103036-1-xujiakai24@mails.ucas.ac.cn
+Fixes: cf393babb37a ("ALSA: pcm: Add copy ops with iov_iter")
+Cc: <stable@vger.kernel.org>
+Link: https://patch.msgid.link/20260517165121.31399-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/pcm_lib.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/sound/core/pcm_lib.c
++++ b/sound/core/pcm_lib.c
+@@ -2138,6 +2138,9 @@ static int interleaved_copy(struct snd_p
+       off = frames_to_bytes(runtime, off);
+       frames = frames_to_bytes(runtime, frames);
++      if (!data)
++              return fill_silence(substream, 0, hwoff, NULL, frames);
++
+       return do_transfer(substream, 0, hwoff, data + off, frames, transfer,
+                          in_kernel);
+ }
diff --git a/queue-6.18/alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch b/queue-6.18/alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch
new file mode 100644 (file)
index 0000000..4634ff6
--- /dev/null
@@ -0,0 +1,52 @@
+From a69b677e47a80319ce148d61cc29a2b57006e78d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= <cassiogabrielcontato@gmail.com>
+Date: Tue, 19 May 2026 11:46:19 -0300
+Subject: ALSA: scarlett2: Allow flash writes ending at segment boundary
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+commit a69b677e47a80319ce148d61cc29a2b57006e78d upstream.
+
+scarlett2_hwdep_write() rejects writes when offset + count is greater than
+or equal to the selected flash segment size. That incorrectly treats a
+write ending exactly at the end of the segment as out of space, although
+the last byte written is still within the segment.
+
+Split invalid argument checks from the segment-space check, keep
+zero-length writes as no-ops, and compare count against the remaining
+segment size. This permits exact-end writes and avoids relying on
+offset + count before deciding whether the request is in bounds.
+
+Fixes: 1abfbd3c9527 ("ALSA: scarlett2: Add support for uploading new firmware")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-alsa-scarlett2-flash-write-boundary-v1-1-b550480e92da@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/mixer_scarlett2.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/sound/usb/mixer_scarlett2.c
++++ b/sound/usb/mixer_scarlett2.c
+@@ -9186,12 +9186,15 @@ static long scarlett2_hwdep_write(struct
+       flash_size = private->flash_segment_blocks[segment_id] *
+                    SCARLETT2_FLASH_BLOCK_SIZE;
+-      if (count < 0 || *offset < 0 || *offset + count >= flash_size)
+-              return -ENOSPC;
++      if (count < 0 || *offset < 0)
++              return -EINVAL;
+       if (!count)
+               return 0;
++      if (*offset >= flash_size || count > flash_size - *offset)
++              return -ENOSPC;
++
+       /* Limit the *req size to SCARLETT2_FLASH_RW_MAX */
+       if (count > max_data_size)
+               count = max_data_size;
diff --git a/queue-6.18/alsa-ua101-reject-too-short-usb-descriptors.patch b/queue-6.18/alsa-ua101-reject-too-short-usb-descriptors.patch
new file mode 100644 (file)
index 0000000..014ea0e
--- /dev/null
@@ -0,0 +1,45 @@
+From b59d5c51bb328a60749b4dd5fe7e649bfb4089b4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= <cassiogabrielcontato@gmail.com>
+Date: Tue, 19 May 2026 00:32:15 -0300
+Subject: ALSA: ua101: Reject too-short USB descriptors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+commit b59d5c51bb328a60749b4dd5fe7e649bfb4089b4 upstream.
+
+find_format_descriptor() walks the class-specific interface extras by
+advancing with bLength. It rejects descriptors that extend past the
+remaining buffer, but it does not reject descriptor lengths smaller than
+a USB descriptor header.
+
+Reject too-short descriptors before using bLength to advance the local
+scan. This keeps the UA-101 parser robust against malformed descriptor
+data and matches the usual USB descriptor walking rules.
+
+Fixes: 63978ab3e3e9 ("sound: add Edirol UA-101 support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-alsa-ua101-desc-len-v1-1-4307d1a5e054@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/misc/ua101.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/sound/usb/misc/ua101.c
++++ b/sound/usb/misc/ua101.c
+@@ -894,8 +894,9 @@ find_format_descriptor(struct usb_interf
+               struct uac_format_type_i_discrete_descriptor *desc;
+               desc = (struct uac_format_type_i_discrete_descriptor *)extra;
+-              if (desc->bLength > extralen) {
+-                      dev_err(&interface->dev, "descriptor overflow\n");
++              if (desc->bLength < sizeof(struct usb_descriptor_header) ||
++                  desc->bLength > extralen) {
++                      dev_err(&interface->dev, "invalid descriptor length\n");
+                       return NULL;
+               }
+               if (desc->bLength == UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1) &&
diff --git a/queue-6.18/bluetooth-bnep-fix-uaf-read-of-dev-name.patch b/queue-6.18/bluetooth-bnep-fix-uaf-read-of-dev-name.patch
new file mode 100644 (file)
index 0000000..6a21f24
--- /dev/null
@@ -0,0 +1,40 @@
+From 59e932ded949fa6f0340bf7c6d7818f962fa4fd2 Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Tue, 12 May 2026 22:15:39 +0200
+Subject: Bluetooth: bnep: Fix UAF read of dev->name
+
+From: Jann Horn <jannh@google.com>
+
+commit 59e932ded949fa6f0340bf7c6d7818f962fa4fd2 upstream.
+
+bnep_add_connection() needs to keep holding the bnep_session_sem while
+reading dev->name (just like bnep_get_connlist() does); otherwise the
+bnep_session() thread can concurrently free the net_device, which can for
+example be triggered by a concurrent bnep_del_connection().
+
+(This UAF is fairly uninteresting from a security perspective;
+calling bnep_add_connection() requires passing a capable(CAP_NET_ADMIN)
+check. It also requires completely tearing down a netdev during a fairly
+tight race window.)
+
+Cc: stable@vger.kernel.org
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/bnep/core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/bluetooth/bnep/core.c
++++ b/net/bluetooth/bnep/core.c
+@@ -638,8 +638,8 @@ int bnep_add_connection(struct bnep_conn
+               goto failed;
+       }
+-      up_write(&bnep_session_sem);
+       strcpy(req->device, dev->name);
++      up_write(&bnep_session_sem);
+       return 0;
+ failed:
diff --git a/queue-6.18/bluetooth-fix-uaf-in-l2cap_sock_cleanup_listen-vs-l2cap_conn_del.patch b/queue-6.18/bluetooth-fix-uaf-in-l2cap_sock_cleanup_listen-vs-l2cap_conn_del.patch
new file mode 100644 (file)
index 0000000..bae8258
--- /dev/null
@@ -0,0 +1,236 @@
+From ab1513597c6cf17cd1ad2a21e3b045421b48e022 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Safa=20Karaku=C5=9F?= <safa.karakus@secunnix.com>
+Date: Sat, 16 May 2026 21:15:04 +0300
+Subject: Bluetooth: fix UAF in l2cap_sock_cleanup_listen() vs l2cap_conn_del()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Safa Karakuş <safa.karakus@secunnix.com>
+
+commit ab1513597c6cf17cd1ad2a21e3b045421b48e022 upstream.
+
+bt_accept_dequeue() unlinks a not-yet-accepted child from the parent
+accept queue and release_sock()s it before returning, so the returned
+sk has no caller reference and is unlocked.
+
+l2cap_sock_cleanup_listen() walks these children on listening-socket
+close.  A concurrent HCI disconnect drives hci_rx_work ->
+l2cap_conn_del() which runs l2cap_chan_del() + l2cap_sock_kill() and
+frees the child sk and its l2cap_chan; cleanup_listen() then uses both:
+
+  BUG: KASAN: slab-use-after-free in l2cap_sock_kill
+    l2cap_sock_kill / l2cap_sock_cleanup_listen / __x64_sys_close
+  Freed by: l2cap_conn_del -> l2cap_sock_close_cb -> l2cap_sock_kill
+
+This is distinct from the two fixes already in this area: commit
+e83f5e24da741 ("Bluetooth: serialize accept_q access") serialises the
+accept_q list/poll and takes temporary refs inside bt_accept_dequeue(),
+and CVE-2025-39860 serialises the userspace close()/accept() race by
+calling cleanup_listen() under lock_sock() in l2cap_sock_release().
+Neither covers l2cap_conn_del() running from hci_rx_work, so this UAF
+still reproduces on current bluetooth/master.
+
+Take the reference at the source: bt_accept_dequeue() does sock_hold()
+while sk is still locked, before release_sock(); callers sock_put().
+cleanup_listen() pins the chan with l2cap_chan_hold_unless_zero() under
+a brief child sk lock (serialising vs l2cap_sock_teardown_cb()), drops
+it before l2cap_chan_lock(), and skips a duplicate l2cap_sock_kill() on
+SOCK_DEAD.  conn->lock is not taken here: cleanup_listen() runs under
+the parent sk lock and that would invert
+conn->lock -> chan->lock -> sk_lock (lockdep).
+
+KASAN/SMP: an unprivileged listen/close vs HCI-disconnect race produced
+12 use-after-free reports per run before this change; 0, and no lockdep
+report, over 1600+ raced iterations after it on bluetooth/master.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Cc: stable@vger.kernel.org
+Reported-by: Siwei Zhang <oss@fourdim.xyz>
+Reviewed-by: Siwei Zhang <oss@fourdim.xyz>
+Signed-off-by: Safa Karakuş <safa.karakus@secunnix.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/af_bluetooth.c |   10 ++++++++
+ net/bluetooth/iso.c          |    9 ++++++-
+ net/bluetooth/l2cap_sock.c   |   51 +++++++++++++++++++++++++++++++++++++------
+ net/bluetooth/rfcomm/sock.c  |    9 ++++++-
+ net/bluetooth/sco.c          |    9 ++++++-
+ 5 files changed, 78 insertions(+), 10 deletions(-)
+
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -309,6 +309,16 @@ restart:
+                       if (newsock)
+                               sock_graft(sk, newsock);
++                      /* Hand the caller a reference taken while sk is
++                       * still locked.  bt_accept_unlink() just dropped
++                       * the accept-queue reference; without this hold a
++                       * concurrent teardown (e.g. l2cap_conn_del() ->
++                       * l2cap_sock_kill()) could free sk between
++                       * release_sock() and the caller using it.  Every
++                       * caller drops this with sock_put() when done.
++                       */
++                      sock_hold(sk);
++
+                       release_sock(sk);
+                       return sk;
+               }
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -741,6 +741,8 @@ static void iso_sock_cleanup_listen(stru
+       while ((sk = bt_accept_dequeue(parent, NULL))) {
+               iso_sock_close(sk);
+               iso_sock_kill(sk);
++              /* Drop the reference handed back by bt_accept_dequeue(). */
++              sock_put(sk);
+       }
+       /* If listening socket has a hcon, properly disconnect it */
+@@ -1282,8 +1284,13 @@ static int iso_sock_accept(struct socket
+               }
+               ch = bt_accept_dequeue(sk, newsock);
+-              if (ch)
++              if (ch) {
++                      /* Drop the bridging ref from bt_accept_dequeue();
++                       * the grafted socket keeps ch alive from here.
++                       */
++                      sock_put(ch);
+                       break;
++              }
+               if (!timeo) {
+                       err = -EAGAIN;
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -349,8 +349,13 @@ static int l2cap_sock_accept(struct sock
+               }
+               nsk = bt_accept_dequeue(sk, newsock);
+-              if (nsk)
++              if (nsk) {
++                      /* Drop the bridging ref from bt_accept_dequeue();
++                       * the grafted socket keeps nsk alive from here.
++                       */
++                      sock_put(nsk);
+                       break;
++              }
+               if (!timeo) {
+                       err = -EAGAIN;
+@@ -1457,22 +1462,54 @@ static void l2cap_sock_cleanup_listen(st
+       BT_DBG("parent %p state %s", parent,
+              state_to_string(parent->sk_state));
+-      /* Close not yet accepted channels */
++      /* Close not yet accepted channels.
++       *
++       * bt_accept_dequeue() now returns sk with an extra reference held
++       * (taken while sk was still locked) so a concurrent l2cap_conn_del()
++       * -> l2cap_sock_kill() cannot free sk under us.
++       *
++       * cleanup_listen() runs under the parent sk lock, so unlike
++       * l2cap_sock_shutdown() we must NOT take conn->lock here: that would
++       * establish sk_lock -> conn->lock and invert the established
++       * conn->lock -> chan->lock -> sk_lock order (lockdep deadlock).
++       *
++       * Instead, briefly take the child sk lock to fetch and pin its chan.
++       * l2cap_conn_del() reaches the chan free only via
++       * l2cap_chan_del() -> l2cap_sock_teardown_cb(), which itself takes
++       * the child sk lock; holding it across l2cap_chan_hold_unless_zero()
++       * therefore guarantees the chan cannot be freed while we read and
++       * pin it (hold_unless_zero() additionally skips a chan already past
++       * its last reference).  We then drop the sk lock before taking
++       * chan->lock, so sk and chan locks are never held together.
++       */
+       while ((sk = bt_accept_dequeue(parent, NULL))) {
+-              struct l2cap_chan *chan = l2cap_pi(sk)->chan;
++              struct l2cap_chan *chan;
++
++              lock_sock_nested(sk, L2CAP_NESTING_NORMAL);
++              chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan);
++              release_sock(sk);
++              if (!chan) {
++                      /* l2cap_conn_del() already tearing this child down */
++                      sock_put(sk);
++                      continue;
++              }
+               BT_DBG("child chan %p state %s", chan,
+                      state_to_string(chan->state));
+-              l2cap_chan_hold(chan);
+               l2cap_chan_lock(chan);
+-
+               __clear_chan_timer(chan);
+               l2cap_chan_close(chan, ECONNRESET);
+-              l2cap_sock_kill(sk);
+-
++              /* l2cap_conn_del() may already have killed this socket
++               * (it sets SOCK_DEAD); skip the duplicate to avoid a
++               * double sock_put()/l2cap_chan_put().
++               */
++              if (!sock_flag(sk, SOCK_DEAD))
++                      l2cap_sock_kill(sk);
+               l2cap_chan_unlock(chan);
++
+               l2cap_chan_put(chan);
++              sock_put(sk);
+       }
+ }
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -180,6 +180,8 @@ static void rfcomm_sock_cleanup_listen(s
+       while ((sk = bt_accept_dequeue(parent, NULL))) {
+               rfcomm_sock_close(sk);
+               rfcomm_sock_kill(sk);
++              /* Drop the reference handed back by bt_accept_dequeue(). */
++              sock_put(sk);
+       }
+       parent->sk_state  = BT_CLOSED;
+@@ -496,8 +498,13 @@ static int rfcomm_sock_accept(struct soc
+               }
+               nsk = bt_accept_dequeue(sk, newsock);
+-              if (nsk)
++              if (nsk) {
++                      /* Drop the bridging ref from bt_accept_dequeue();
++                       * the grafted socket keeps nsk alive from here.
++                       */
++                      sock_put(nsk);
+                       break;
++              }
+               if (!timeo) {
+                       err = -EAGAIN;
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -498,6 +498,8 @@ static void sco_sock_cleanup_listen(stru
+       while ((sk = bt_accept_dequeue(parent, NULL))) {
+               sco_sock_close(sk);
+               sco_sock_kill(sk);
++              /* Drop the reference handed back by bt_accept_dequeue(). */
++              sock_put(sk);
+       }
+       parent->sk_state  = BT_CLOSED;
+@@ -759,8 +761,13 @@ static int sco_sock_accept(struct socket
+               }
+               ch = bt_accept_dequeue(sk, newsock);
+-              if (ch)
++              if (ch) {
++                      /* Drop the bridging ref from bt_accept_dequeue();
++                       * the grafted socket keeps ch alive from here.
++                       */
++                      sock_put(ch);
+                       break;
++              }
+               if (!timeo) {
+                       err = -EAGAIN;
diff --git a/queue-6.18/bluetooth-hci_uart-fix-uafs-and-race-conditions-in-close-and-init-paths.patch b/queue-6.18/bluetooth-hci_uart-fix-uafs-and-race-conditions-in-close-and-init-paths.patch
new file mode 100644 (file)
index 0000000..929d324
--- /dev/null
@@ -0,0 +1,173 @@
+From c1bb9336ae6b54a5f6a353c4bd4ed9a4307e429b Mon Sep 17 00:00:00 2001
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Date: Mon, 18 May 2026 10:49:49 +0800
+Subject: Bluetooth: hci_uart: fix UAFs and race conditions in close and init paths
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+commit c1bb9336ae6b54a5f6a353c4bd4ed9a4307e429b upstream.
+
+Vulnerabilities leading to Use-After-Free (UAF) and Null Pointer
+Dereference (NPD) conditions were observed in the lifecycle management
+of hci_uart.
+
+The primary issue arises because the workqueues (init_ready and
+write_work) are only flushed/cancelled if the HCI_UART_PROTO_READY
+flag is set during TTY close. If a hangup occurs before setup completes,
+hci_uart_tty_close() skips the teardown of these workqueues and
+proceeds to free the `hu` struct. When the scheduled work executes
+later, it blindly dereferences the freed `hu` struct.
+
+Furthermore, several data races and UAFs were identified in the teardown
+sequence:
+1. Calling hci_uart_flush() from hci_uart_close() without effectively
+   disabling write_work causes a race condition where both can concurrently
+   double-free hu->tx_skb. This happens because protocol timers can
+   concurrently invoke hci_uart_tx_wakeup() and requeue write_work.
+2. Calling hci_free_dev(hdev) before hu->proto->close(hu) causes a UAF
+   when vendor specific protocol close callbacks dereference hu->hdev.
+3. In the initialization error paths, failing to take the proto_lock
+   write lock before clearing PROTO_READY leads to races with active
+   readers. Additionally, hci_uart_tty_receive() accesses hu->hdev
+   outside the read lock, leading to UAFs if the initialization error
+   path frees hdev concurrently.
+
+Fix these synchronization and lifecycle issues by:
+1. Re-ordering hci_uart_tty_close() to clear HCI_UART_PROTO_READY first,
+   followed immediately by a cancel_work_sync(&hu->write_work). Clearing
+   the flag locks out concurrent protocol timers from successfully invoking
+   hci_uart_tx_wakeup(), effectively rendering the cancellation permanent
+   and preventing the tx_skb double-free.
+2. Note: Clearing PROTO_READY early causes hci_uart_close() to skip
+   hu->proto->flush(). This is perfectly safe in the tty_close path
+   because hu->proto->close() executes shortly after, which intrinsically
+   purges all protocol SKB queues and tears down the state.
+3. Relocating hu->proto->close(hu) strictly prior to hci_free_dev(hdev)
+   across all close and error paths to prevent vendor-level UAFs.
+4. Moving the hdev->stat.byte_rx increment in hci_uart_tty_receive()
+   inside the proto_lock read-side critical section to safely synchronize
+   with device unregistration.
+5. Adding cancel_work_sync(&hu->write_work) to hci_uart_close() to safely
+   flush the workqueue before hci_uart_flush() is invoked via the HCI core.
+6. Utilizing cancel_work_sync() instead of disable_work_sync() across
+   all paths to prevent permanently breaking user-space retry capabilities.
+
+Fixes: 3b799254cf6f ("Bluetooth: hci_uart: Cancel init work before unregistering")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/hci_ldisc.c |   48 +++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 40 insertions(+), 8 deletions(-)
+
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -194,7 +194,15 @@ void hci_uart_init_work(struct work_stru
+       err = hci_register_dev(hu->hdev);
+       if (err < 0) {
+               BT_ERR("Can't register HCI device");
++
++              percpu_down_write(&hu->proto_lock);
+               clear_bit(HCI_UART_PROTO_READY, &hu->flags);
++              percpu_up_write(&hu->proto_lock);
++
++              /* Safely cancel work after clearing flags */
++              cancel_work_sync(&hu->write_work);
++
++              /* Close protocol before freeing hdev */
+               hu->proto->close(hu);
+               hdev = hu->hdev;
+               hu->hdev = NULL;
+@@ -263,8 +271,12 @@ static int hci_uart_open(struct hci_dev
+ /* Close device */
+ static int hci_uart_close(struct hci_dev *hdev)
+ {
++      struct hci_uart *hu = hci_get_drvdata(hdev);
++
+       BT_DBG("hdev %p", hdev);
++      cancel_work_sync(&hu->write_work);
++
+       hci_uart_flush(hdev);
+       hdev->flush = NULL;
+       return 0;
+@@ -531,6 +543,7 @@ static void hci_uart_tty_close(struct tt
+ {
+       struct hci_uart *hu = tty->disc_data;
+       struct hci_dev *hdev;
++      bool proto_ready;
+       BT_DBG("tty %p", tty);
+@@ -540,24 +553,38 @@ static void hci_uart_tty_close(struct tt
+       if (!hu)
+               return;
+-      hdev = hu->hdev;
+-      if (hdev)
+-              hci_uart_close(hdev);
++      /* Wait for init_ready to finish to prevent registration races */
++      cancel_work_sync(&hu->init_ready);
+-      if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
++      proto_ready = test_bit(HCI_UART_PROTO_READY, &hu->flags);
++      if (proto_ready) {
+               percpu_down_write(&hu->proto_lock);
+               clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+               percpu_up_write(&hu->proto_lock);
++      }
+-              cancel_work_sync(&hu->init_ready);
+-              cancel_work_sync(&hu->write_work);
++      /*
++       * Unconditionally cancel write_work AFTER clearing PROTO_READY.
++       * This ensures that concurrent protocol timers cannot requeue
++       * write_work via hci_uart_tx_wakeup(), permanently preventing
++       * double-free races and UAFs.
++       */
++      cancel_work_sync(&hu->write_work);
++
++      hdev = hu->hdev;
++      if (hdev)
++              hci_uart_close(hdev); /* proto->flush is safely skipped */
++      if (proto_ready) {
+               if (hdev) {
+                       if (test_bit(HCI_UART_REGISTERED, &hu->flags))
+                               hci_unregister_dev(hdev);
+-                      hci_free_dev(hdev);
+               }
++              /* Close protocol before freeing hdev (intrinsically purges queues) */
+               hu->proto->close(hu);
++
++              if (hdev)
++                      hci_free_dev(hdev);
+       }
+       clear_bit(HCI_UART_PROTO_SET, &hu->flags);
+@@ -625,11 +652,12 @@ static void hci_uart_tty_receive(struct
+        * tty caller
+        */
+       hu->proto->recv(hu, data, count);
+-      percpu_up_read(&hu->proto_lock);
+       if (hu->hdev)
+               hu->hdev->stat.byte_rx += count;
++      percpu_up_read(&hu->proto_lock);
++
+       tty_unthrottle(tty);
+ }
+@@ -695,6 +723,10 @@ static int hci_uart_register_dev(struct
+               percpu_down_write(&hu->proto_lock);
+               clear_bit(HCI_UART_PROTO_INIT, &hu->flags);
+               percpu_up_write(&hu->proto_lock);
++              /* Cancel work after clearing flags */
++              cancel_work_sync(&hu->write_work);
++
++              /* Close protocol before freeing hdev */
+               hu->proto->close(hu);
+               hu->hdev = NULL;
+               hci_free_dev(hdev);
diff --git a/queue-6.18/bluetooth-iso-drop-iso_end-frames-received-without-prior-iso_start.patch b/queue-6.18/bluetooth-iso-drop-iso_end-frames-received-without-prior-iso_start.patch
new file mode 100644 (file)
index 0000000..f00dd03
--- /dev/null
@@ -0,0 +1,47 @@
+From 84c24fb151fc1179355296d7ff29129ac7c42129 Mon Sep 17 00:00:00 2001
+From: David Carlier <devnexen@gmail.com>
+Date: Fri, 15 May 2026 07:25:25 +0100
+Subject: Bluetooth: ISO: drop ISO_END frames received without prior ISO_START
+
+From: David Carlier <devnexen@gmail.com>
+
+commit 84c24fb151fc1179355296d7ff29129ac7c42129 upstream.
+
+ISO data PDUs carry a packet-boundary flag indicating START, CONT, END
+or SINGLE. The ISO_CONT branch of iso_recv() guards against a missing
+ISO_START by checking conn->rx_len before touching conn->rx_skb, but
+ISO_END does not.
+
+If a peer sends an ISO_END as the first packet on a fresh ISO
+connection, conn->rx_skb is still NULL and conn->rx_len is zero, so
+skb_put(conn->rx_skb, ...) dereferences NULL and oopses. For BIS,
+where receivers sync to a broadcaster without pairing, any broadcaster
+on the air can trigger this.
+
+Mirror the ISO_CONT check at the top of ISO_END so a stray end fragment
+is logged and dropped instead of crashing the host.
+
+Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/iso.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -2461,6 +2461,11 @@ int iso_recv(struct hci_dev *hdev, u16 h
+               break;
+       case ISO_END:
++              if (!conn->rx_len) {
++                      BT_ERR("Unexpected end frame (len %d)", skb->len);
++                      goto drop;
++              }
++
+               skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
+                                         skb->len);
+               conn->rx_len -= skb->len;
diff --git a/queue-6.18/bluetooth-l2cap-ecred_reconfigure-send-packed-pdu-not-stack-pointer.patch b/queue-6.18/bluetooth-l2cap-ecred_reconfigure-send-packed-pdu-not-stack-pointer.patch
new file mode 100644 (file)
index 0000000..98a28b2
--- /dev/null
@@ -0,0 +1,84 @@
+From 3374ef8cf99368a40f7efd51a2a375a4c5dc6f0d Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Mon, 11 May 2026 08:26:41 -0400
+Subject: Bluetooth: L2CAP: ecred_reconfigure: send packed pdu, not stack pointer
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 3374ef8cf99368a40f7efd51a2a375a4c5dc6f0d upstream.
+
+Commit 1c08108f3014 ("Bluetooth: L2CAP: Avoid -Wflex-array-member-not-at-end
+warnings") converted the on-stack request PDU in l2cap_ecred_reconfigure()
+from an explicit packed struct to DEFINE_RAW_FLEX(), but did not adjust the
+size and source-pointer arguments to l2cap_send_cmd():
+
+  -    struct {
+  -            struct l2cap_ecred_reconf_req req;
+  -            __le16 scid;
+  -    } pdu;
+  +    DEFINE_RAW_FLEX(struct l2cap_ecred_reconf_req, pdu, scid, 1);
+       ...
+       l2cap_send_cmd(conn, chan->ident, L2CAP_ECRED_RECONF_REQ,
+                      sizeof(pdu), &pdu);
+
+After the conversion, DEFINE_RAW_FLEX() expands to declare an anonymous
+union pdu_u plus a local pointer "pdu" pointing at it. Therefore:
+
+  - sizeof(pdu) is now sizeof(struct l2cap_ecred_reconf_req *) = 8 on
+    64-bit (4 on 32-bit), not the 6 bytes of (mtu, mps, scid[1]).
+  - &pdu is the address of the local pointer's stack storage, not the
+    address of the request payload.
+
+l2cap_send_cmd() forwards (data, count) to l2cap_build_cmd(), which calls
+skb_put_data(skb, data, count). The L2CAP_ECRED_RECONFIGURE_REQ packet
+body therefore contains 8 bytes copied from the kernel stack starting at
+&pdu -- the 8 bytes overlap the pdu pointer's value, leaking a kernel
+stack address to the paired Bluetooth peer. The intended (mtu, mps, scid)
+fields are not transmitted at all, so the peer rejects the request as
+malformed and the L2CAP_ECRED_RECONFIGURE feature itself has been broken
+for the local-side initiator since the introducing commit landed.
+
+The sibling site l2cap_ecred_conn_req() in the same commit was converted
+correctly (sizeof(*pdu) + len, pdu); only this site was missed.
+
+Restore the original semantics: pass the full flex-struct size via
+struct_size(pdu, scid, 1) and the pdu pointer (the struct address) as
+the source.
+
+Validated on a stock 7.0-based host kernel via the real call path:
+setsockopt(SOL_BLUETOOTH, BT_RCVMTU, ...) on a BT_CONNECTED
+L2CAP_MODE_EXT_FLOWCTL socket emits an L2CAP_ECRED_RECONFIGURE_REQ
+whose body is 8 bytes (the on-stack pdu local's value) rather than
+the expected 6. Three captures from fresh socket / fresh hciemu peer
+on the same host -- low bytes vary per call, high 0xffff confirms a
+kernel virtual address (KASLR-randomised stack slot, not a fixed
+string):
+
+  RECONF_REQ body (ident=0x02 len=8): 42 fb 54 af 0e ca ff ff
+  RECONF_REQ body (ident=0x02 len=8): 52 3d 2e af 0e ca ff ff
+  RECONF_REQ body (ident=0x02 len=8): b2 fc 5b af 0e ca ff ff
+
+After this patch the body is 6 bytes carrying the expected
+little-endian (mtu, mps, scid).
+
+Cc: stable@vger.kernel.org
+Fixes: 1c08108f3014 ("Bluetooth: L2CAP: Avoid -Wflex-array-member-not-at-end warnings")
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -7275,7 +7275,7 @@ static void l2cap_ecred_reconfigure(stru
+       chan->ident = l2cap_get_ident(conn);
+       l2cap_send_cmd(conn, chan->ident, L2CAP_ECRED_RECONF_REQ,
+-                     sizeof(pdu), &pdu);
++                     struct_size(pdu, scid, 1), pdu);
+ }
+ int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu)
diff --git a/queue-6.18/bluetooth-mgmt-validate-add-extended-advertising-data-length.patch b/queue-6.18/bluetooth-mgmt-validate-add-extended-advertising-data-length.patch
new file mode 100644 (file)
index 0000000..430e149
--- /dev/null
@@ -0,0 +1,54 @@
+From d3f7d17960ed50df3a6709c5158caff989c8c905 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Fri, 15 May 2026 10:38:19 -0400
+Subject: Bluetooth: MGMT: validate Add Extended Advertising Data length
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit d3f7d17960ed50df3a6709c5158caff989c8c905 upstream.
+
+MGMT_OP_ADD_EXT_ADV_DATA is registered as a variable-length command,
+with MGMT_ADD_EXT_ADV_DATA_SIZE as the fixed header size.  The handler
+then uses cp->adv_data_len and cp->scan_rsp_len to validate and copy
+cp->data, but it never checks that those bytes are part of the mgmt
+command payload.
+
+A short command can therefore make add_ext_adv_data() pass an
+out-of-bounds pointer into tlv_data_is_valid().  If the bytes beyond
+the command buffer are addressable, they can also be copied into the
+advertising instance as scan response data, where the caller can read
+them back via MGMT_OP_GET_ADV_INSTANCE.  The trigger requires
+CAP_NET_ADMIN in the initial user namespace; KASAN reports an 8-byte
+slab-out-of-bounds read.
+
+Reject commands whose length does not match the fixed header plus both
+advertising data lengths before parsing cp->data.
+
+Fixes: 12410572833a ("Bluetooth: Break add adv into two mgmt commands")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+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 |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9094,9 +9094,15 @@ static int add_ext_adv_data(struct sock
+       struct adv_info *adv_instance;
+       int err = 0;
+       struct mgmt_pending_cmd *cmd;
++      u16 expected_len;
+       BT_DBG("%s", hdev->name);
++      expected_len = struct_size(cp, data, cp->adv_data_len + cp->scan_rsp_len);
++      if (expected_len != data_len)
++              return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_DATA,
++                                     MGMT_STATUS_INVALID_PARAMS);
++
+       hci_dev_lock(hdev);
+       adv_instance = hci_find_adv_instance(hdev, cp->instance);
diff --git a/queue-6.18/bluetooth-serialize-accept_q-access.patch b/queue-6.18/bluetooth-serialize-accept_q-access.patch
new file mode 100644 (file)
index 0000000..f63a42a
--- /dev/null
@@ -0,0 +1,218 @@
+From e83f5e24da741fa9405aeeff00b08c5ee7c37b88 Mon Sep 17 00:00:00 2001
+From: Jiexun Wang <wangjiexun2025@gmail.com>
+Date: Wed, 6 May 2026 19:43:30 +0800
+Subject: Bluetooth: serialize accept_q access
+
+From: Jiexun Wang <wangjiexun2025@gmail.com>
+
+commit e83f5e24da741fa9405aeeff00b08c5ee7c37b88 upstream.
+
+bt_sock_poll() walks the accept queue without synchronization, while
+child teardown can unlink the same socket and drop its last reference.
+The unsynchronized accept queue walk has existed since the initial
+Bluetooth import.
+
+Protect accept_q with a dedicated lock for queue updates and polling.
+Also rework bt_accept_dequeue() to take temporary child references under
+the queue lock before dropping it and locking the child socket.
+
+Fixes: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reported-by: Jann Horn <jannh@google.com>
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com>
+Reviewed-by: Jann Horn <jannh@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/bluetooth.h |    1 
+ net/bluetooth/af_bluetooth.c      |   87 ++++++++++++++++++++++++++++----------
+ 2 files changed, 66 insertions(+), 22 deletions(-)
+
+--- a/include/net/bluetooth/bluetooth.h
++++ b/include/net/bluetooth/bluetooth.h
+@@ -389,6 +389,7 @@ void baswap(bdaddr_t *dst, const bdaddr_
+ struct bt_sock {
+       struct sock sk;
+       struct list_head accept_q;
++      spinlock_t accept_q_lock; /* protects accept_q */
+       struct sock *parent;
+       unsigned long flags;
+       void (*skb_msg_name)(struct sk_buff *, void *, int *);
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -154,6 +154,7 @@ struct sock *bt_sock_alloc(struct net *n
+       sock_init_data(sock, sk);
+       INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
++      spin_lock_init(&bt_sk(sk)->accept_q_lock);
+       sock_reset_flag(sk, SOCK_ZAPPED);
+@@ -214,6 +215,7 @@ void bt_accept_enqueue(struct sock *pare
+ {
+       const struct cred *old_cred;
+       struct pid *old_pid;
++      struct bt_sock *par = bt_sk(parent);
+       BT_DBG("parent %p, sk %p", parent, sk);
+@@ -224,9 +226,13 @@ void bt_accept_enqueue(struct sock *pare
+       else
+               lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+-      list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
+       bt_sk(sk)->parent = parent;
++      spin_lock_bh(&par->accept_q_lock);
++      list_add_tail(&bt_sk(sk)->accept_q, &par->accept_q);
++      sk_acceptq_added(parent);
++      spin_unlock_bh(&par->accept_q_lock);
++
+       /* Copy credentials from parent since for incoming connections the
+        * socket is allocated by the kernel.
+        */
+@@ -244,8 +250,6 @@ void bt_accept_enqueue(struct sock *pare
+               bh_unlock_sock(sk);
+       else
+               release_sock(sk);
+-
+-      sk_acceptq_added(parent);
+ }
+ EXPORT_SYMBOL(bt_accept_enqueue);
+@@ -254,45 +258,72 @@ EXPORT_SYMBOL(bt_accept_enqueue);
+  */
+ void bt_accept_unlink(struct sock *sk)
+ {
++      struct sock *parent = bt_sk(sk)->parent;
++
+       BT_DBG("sk %p state %d", sk, sk->sk_state);
++      spin_lock_bh(&bt_sk(parent)->accept_q_lock);
+       list_del_init(&bt_sk(sk)->accept_q);
+-      sk_acceptq_removed(bt_sk(sk)->parent);
++      sk_acceptq_removed(parent);
++      spin_unlock_bh(&bt_sk(parent)->accept_q_lock);
+       bt_sk(sk)->parent = NULL;
+       sock_put(sk);
+ }
+ EXPORT_SYMBOL(bt_accept_unlink);
++static struct sock *bt_accept_get(struct sock *parent, struct sock *sk)
++{
++      struct bt_sock *bt = bt_sk(parent);
++      struct sock *next = NULL;
++
++      /* accept_q is modified from child teardown paths too, so take a
++       * temporary reference before dropping the queue lock.
++       */
++      spin_lock_bh(&bt->accept_q_lock);
++
++      if (sk) {
++              if (bt_sk(sk)->parent != parent)
++                      goto out;
++
++              if (!list_is_last(&bt_sk(sk)->accept_q, &bt->accept_q)) {
++                      next = &list_next_entry(bt_sk(sk), accept_q)->sk;
++                      sock_hold(next);
++              }
++      } else if (!list_empty(&bt->accept_q)) {
++              next = &list_first_entry(&bt->accept_q,
++                                       struct bt_sock, accept_q)->sk;
++              sock_hold(next);
++      }
++
++out:
++      spin_unlock_bh(&bt->accept_q_lock);
++      return next;
++}
++
+ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
+ {
+-      struct bt_sock *s, *n;
+-      struct sock *sk;
++      struct sock *sk, *next;
+       BT_DBG("parent %p", parent);
+ restart:
+-      list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
+-              sk = (struct sock *)s;
+-
++      for (sk = bt_accept_get(parent, NULL); sk; sk = next) {
+               /* Prevent early freeing of sk due to unlink and sock_kill */
+-              sock_hold(sk);
+               lock_sock(sk);
+               /* Check sk has not already been unlinked via
+                * bt_accept_unlink() due to serialisation caused by sk locking
+                */
+-              if (!bt_sk(sk)->parent) {
++              if (bt_sk(sk)->parent != parent) {
+                       BT_DBG("sk %p, already unlinked", sk);
+                       release_sock(sk);
+                       sock_put(sk);
+-                      /* Restart the loop as sk is no longer in the list
+-                       * and also avoid a potential infinite loop because
+-                       * list_for_each_entry_safe() is not thread safe.
+-                       */
+                       goto restart;
+               }
++              next = bt_accept_get(parent, sk);
++
+               /* sk is safely in the parent list so reduce reference count */
+               sock_put(sk);
+@@ -320,6 +351,8 @@ restart:
+                       sock_hold(sk);
+                       release_sock(sk);
++                      if (next)
++                              sock_put(next);
+                       return sk;
+               }
+@@ -528,18 +561,28 @@ EXPORT_SYMBOL(bt_sock_stream_recvmsg);
+ static inline __poll_t bt_accept_poll(struct sock *parent)
+ {
+-      struct bt_sock *s, *n;
++      struct bt_sock *bt = bt_sk(parent);
++      struct bt_sock *s;
+       struct sock *sk;
++      __poll_t mask = 0;
++
++      spin_lock_bh(&bt->accept_q_lock);
++      list_for_each_entry(s, &bt->accept_q, accept_q) {
++              int state;
+-      list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
+               sk = (struct sock *)s;
+-              if (sk->sk_state == BT_CONNECTED ||
+-                  (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
+-                   sk->sk_state == BT_CONNECT2))
+-                      return EPOLLIN | EPOLLRDNORM;
++              state = READ_ONCE(sk->sk_state);
++
++              if (state == BT_CONNECTED ||
++                  (test_bit(BT_SK_DEFER_SETUP, &bt->flags) &&
++                   state == BT_CONNECT2)) {
++                      mask = EPOLLIN | EPOLLRDNORM;
++                      break;
++              }
+       }
++      spin_unlock_bh(&bt->accept_q_lock);
+-      return 0;
++      return mask;
+ }
+ __poll_t bt_sock_poll(struct file *file, struct socket *sock,
diff --git a/queue-6.18/drivers-base-memory-fix-memory-block-reference-leak-in-poison-accounting.patch b/queue-6.18/drivers-base-memory-fix-memory-block-reference-leak-in-poison-accounting.patch
new file mode 100644 (file)
index 0000000..365bb24
--- /dev/null
@@ -0,0 +1,62 @@
+From 03a2cc1756a0570f887d624cd6c535ea0cbd4951 Mon Sep 17 00:00:00 2001
+From: Muchun Song <songmuchun@bytedance.com>
+Date: Tue, 28 Apr 2026 16:52:18 +0800
+Subject: drivers/base/memory: fix memory block reference leak in poison accounting
+
+From: Muchun Song <songmuchun@bytedance.com>
+
+commit 03a2cc1756a0570f887d624cd6c535ea0cbd4951 upstream.
+
+memblk_nr_poison_inc() and memblk_nr_poison_sub() look up a memory block
+via find_memory_block_by_id(), which acquires a reference to the memory
+block device.
+
+Both helpers use the returned memory block without dropping that
+reference, leaking the device reference on each successful lookup.  Drop
+the reference after updating nr_hwpoison.
+
+Link: https://lore.kernel.org/20260428085219.1316047-3-songmuchun@bytedance.com
+Fixes: 5033091de814 ("mm/hwpoison: introduce per-memory_block hwpoison counter")
+Signed-off-by: Muchun Song <songmuchun@bytedance.com>
+Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
+Acked-by: Oscar Salvador <osalvador@suse.de>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Cc: Danilo Krummrich <dakr@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: "Huang, Ying" <huang.ying.caritas@gmail.com>
+Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Vishal Verma <vishal.l.verma@intel.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/memory.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/base/memory.c
++++ b/drivers/base/memory.c
+@@ -1251,8 +1251,10 @@ void memblk_nr_poison_inc(unsigned long
+       const unsigned long block_id = pfn_to_block_id(pfn);
+       struct memory_block *mem = find_memory_block_by_id(block_id);
+-      if (mem)
++      if (mem) {
+               atomic_long_inc(&mem->nr_hwpoison);
++              put_device(&mem->dev);
++      }
+ }
+ void memblk_nr_poison_sub(unsigned long pfn, long i)
+@@ -1260,8 +1262,10 @@ void memblk_nr_poison_sub(unsigned long
+       const unsigned long block_id = pfn_to_block_id(pfn);
+       struct memory_block *mem = find_memory_block_by_id(block_id);
+-      if (mem)
++      if (mem) {
+               atomic_long_sub(i, &mem->nr_hwpoison);
++              put_device(&mem->dev);
++      }
+ }
+ static unsigned long memblk_nr_poison(struct memory_block *mem)
diff --git a/queue-6.18/efi-allocate-runtime-workqueue-before-acpi-init.patch b/queue-6.18/efi-allocate-runtime-workqueue-before-acpi-init.patch
new file mode 100644 (file)
index 0000000..87aa376
--- /dev/null
@@ -0,0 +1,88 @@
+From 13c6da02e767152c9ac4330962247a5e47011035 Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Tue, 19 May 2026 10:03:00 +0200
+Subject: efi: Allocate runtime workqueue before ACPI init
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+commit 13c6da02e767152c9ac4330962247a5e47011035 upstream.
+
+Since commit
+
+  5894cf571e14 ("acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers")
+
+ACPI PRM calls are delegated to a workqueue which runs in a kernel
+thread, making it easier to detect and mitigate faulting memory accesses
+performed by the firmware.
+
+Rafael reports that such PRM accesses may occur before efisubsys_init()
+executes, which is where the workqueue is allocated, leading to NULL
+pointer dereferences. Since acpi_init() [which triggers the early PRM
+accesses] executes as a subsys_initcall() as well, and has its own
+dependencies that may be sensitive to initcall ordering, deferring
+acpi_init() is not an option.
+
+So instead, split off the workqueue allocation into its own postcore
+initcall, as this is the only missing piece to allow EFI runtime calls
+to be made. This ensures that EFI runtime call (including PRM calls) are
+accessible to all code running at subsys_initcall() level.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 5894cf571e14 ("acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers")
+Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/firmware/efi/efi.c |   28 ++++++++++++++++------------
+ 1 file changed, 16 insertions(+), 12 deletions(-)
+
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -401,21 +401,11 @@ static void __init efi_debugfs_init(void
+ static inline void efi_debugfs_init(void) {}
+ #endif
+-/*
+- * We register the efi subsystem with the firmware subsystem and the
+- * efivars subsystem with the efi subsystem, if the system was booted with
+- * EFI.
+- */
+-static int __init efisubsys_init(void)
++static int __init efipostcore_init(void)
+ {
+-      int error;
+-
+       if (!efi_enabled(EFI_RUNTIME_SERVICES))
+               efi.runtime_supported_mask = 0;
+-      if (!efi_enabled(EFI_BOOT))
+-              return 0;
+-
+       if (efi.runtime_supported_mask) {
+               /*
+                * Since we process only one efi_runtime_service() at a time, an
+@@ -427,9 +417,23 @@ static int __init efisubsys_init(void)
+                       pr_err("Creating efi_rts_wq failed, EFI runtime services disabled.\n");
+                       clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
+                       efi.runtime_supported_mask = 0;
+-                      return 0;
+               }
+       }
++      return 0;
++}
++postcore_initcall(efipostcore_init);
++
++/*
++ * We register the efi subsystem with the firmware subsystem and the
++ * efivars subsystem with the efi subsystem, if the system was booted with
++ * EFI.
++ */
++static int __init efisubsys_init(void)
++{
++      int error;
++
++      if (!efi_enabled(EFI_BOOT))
++              return 0;
+       if (efi_rt_services_supported(EFI_RT_SUPPORTED_TIME_SERVICES))
+               platform_device_register_simple("rtc-efi", 0, NULL, 0);
diff --git a/queue-6.18/hwmon-pmbus-adm1266-widen-blackbox-info-buffer-to-i2c_smbus_block_max.patch b/queue-6.18/hwmon-pmbus-adm1266-widen-blackbox-info-buffer-to-i2c_smbus_block_max.patch
new file mode 100644 (file)
index 0000000..a5192d3
--- /dev/null
@@ -0,0 +1,51 @@
+From eee213daa1e1b402eb631bcd1b8c5aa340a6b081 Mon Sep 17 00:00:00 2001
+From: Abdurrahman Hussain <abdurrahman@nexthop.ai>
+Date: Fri, 15 May 2026 15:11:48 -0700
+Subject: hwmon: (pmbus/adm1266) widen blackbox-info buffer to I2C_SMBUS_BLOCK_MAX
+
+From: Abdurrahman Hussain <abdurrahman@nexthop.ai>
+
+commit eee213daa1e1b402eb631bcd1b8c5aa340a6b081 upstream.
+
+adm1266_nvmem_read_blackbox() declares a 5-byte stack buffer and
+passes it to i2c_smbus_read_block_data() to retrieve the 4-byte
+BLACKBOX_INFO response.  i2c_smbus_read_block_data() does not honour
+caller buffer sizes -- it memcpy()s data.block[0] bytes from the
+SMBus transaction (where data.block[0] is the length byte returned by
+the slave device, up to I2C_SMBUS_BLOCK_MAX = 32):
+
+       memcpy(values, &data.block[1], data.block[0]);
+
+If the device returns any block length above 5, the call overflows
+the caller's 5-byte stack buffer before the post-call
+
+       if (ret != 4)
+               return -EIO;
+
+check has a chance to reject the response.
+
+Widen the local buffer to I2C_SMBUS_BLOCK_MAX so the helper has room
+for any well-formed SMBus block response, matching the convention used
+by the other i2c_smbus_read_block_data() callers in this driver.
+
+Fixes: 15609d189302 ("hwmon: (pmbus/adm1266) read blackbox")
+Cc: stable@vger.kernel.org
+Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
+Link: https://lore.kernel.org/r/20260515-adm1266-fixes-v1-2-1c1ea1349cfe@nexthop.ai
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hwmon/pmbus/adm1266.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hwmon/pmbus/adm1266.c
++++ b/drivers/hwmon/pmbus/adm1266.c
+@@ -349,7 +349,7 @@ static int adm1266_nvmem_read_blackbox(s
+ {
+       int record_count;
+       char index;
+-      u8 buf[5];
++      u8 buf[I2C_SMBUS_BLOCK_MAX];
+       int ret;
+       ret = i2c_smbus_read_block_data(data->client, ADM1266_BLACKBOX_INFO, buf);
diff --git a/queue-6.18/io_uring-waitid-clear-waitid-info-before-copying-it-to-userspace.patch b/queue-6.18/io_uring-waitid-clear-waitid-info-before-copying-it-to-userspace.patch
new file mode 100644 (file)
index 0000000..4106e41
--- /dev/null
@@ -0,0 +1,41 @@
+From 93d93f5f8da791e98159795c6ef683f45bd95d13 Mon Sep 17 00:00:00 2001
+From: Heechan Kang <gganji11@naver.com>
+Date: Sun, 17 May 2026 03:47:09 +0900
+Subject: io_uring/waitid: clear waitid info before copying it to userspace
+
+From: Heechan Kang <gganji11@naver.com>
+
+commit 93d93f5f8da791e98159795c6ef683f45bd95d13 upstream.
+
+IORING_OP_WAITID stores its result fields in struct io_waitid::info and
+later copies them to userspace siginfo. The prep path initializes the
+request arguments, but it does not initialize info itself.
+
+If the wait operation completes without reporting a child event, the common
+wait code can return without writing wo_info. In that case io_waitid_finish()
+still copies iw->info to userspace, exposing stale bytes from the reused
+io_kiocb command storage.
+
+Clear the result storage during prep so the io_uring path matches the
+regular waitid syscall, which uses a zero-initialized struct waitid_info.
+
+Fixes: f31ecf671ddc ("io_uring: add IORING_OP_WAITID support")
+Cc: stable@vger.kernel.org # 6.7+
+Signed-off-by: Heechan Kang <gganji11@naver.com>
+Link: https://patch.msgid.link/20260516184709.852814-1-gganji11@naver.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/waitid.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/io_uring/waitid.c
++++ b/io_uring/waitid.c
+@@ -258,6 +258,7 @@ int io_waitid_prep(struct io_kiocb *req,
+       iw->upid = READ_ONCE(sqe->fd);
+       iw->options = READ_ONCE(sqe->file_index);
+       iw->infop = u64_to_user_ptr(READ_ONCE(sqe->addr2));
++      memset(&iw->info, 0, sizeof(iw->info));
+       return 0;
+ }
diff --git a/queue-6.18/ipv6-ioam-refresh-hdr-pointer-before-ioam6_event.patch b/queue-6.18/ipv6-ioam-refresh-hdr-pointer-before-ioam6_event.patch
new file mode 100644 (file)
index 0000000..89be3d8
--- /dev/null
@@ -0,0 +1,62 @@
+From e46e6bc97fb1f339730ff1ba74267fbf48e7a422 Mon Sep 17 00:00:00 2001
+From: Justin Iurman <justin.iurman@gmail.com>
+Date: Wed, 20 May 2026 14:42:42 +0200
+Subject: ipv6: ioam: refresh hdr pointer before ioam6_event()
+
+From: Justin Iurman <justin.iurman@gmail.com>
+
+commit e46e6bc97fb1f339730ff1ba74267fbf48e7a422 upstream.
+
+Reported by Sashiko:
+
+In ipv6_hop_ioam(), the hdr pointer is initialized to point into the
+skb's linear data buffer. Later, the code calls skb_ensure_writable(),
+which might reallocate the buffer:
+
+       if (skb_ensure_writable(skb, optoff + 2 + hdr->opt_len))
+               goto drop;
+
+       /* Trace pointer may have changed */
+       trace = (struct ioam6_trace_hdr *)(skb_network_header(skb)
+                                          + optoff + sizeof(*hdr));
+
+       ioam6_fill_trace_data(skb, ns, trace, true);
+
+       ioam6_event(IOAM6_EVENT_TRACE, dev_net(skb->dev),
+                   GFP_ATOMIC, (void *)trace, hdr->opt_len - 2);
+
+If the skb is cloned or lacks sufficient linear headroom,
+skb_ensure_writable() will invoke pskb_expand_head(), which reallocates
+the skb's data buffer and frees the old one, invalidating pointers to
+it. While the code recalculates the trace pointer immediately after the
+call to skb_ensure_writable(), it fails to recalculate the hdr pointer.
+
+This patch fixes the above by recalculating the hdr pointer before
+passing hdr->opt_len to ioam6_event(), so that we avoid any UaF.
+
+Fixes: f655c78d6225 ("net: exthdrs: ioam6: send trace event")
+Cc: stable@vger.kernel.org
+Signed-off-by: Justin Iurman <justin.iurman@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260520124242.32320-1-justin.iurman@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/exthdrs.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -955,9 +955,9 @@ static bool ipv6_hop_ioam(struct sk_buff
+               if (skb_ensure_writable(skb, optoff + 2 + hdr->opt_len))
+                       goto drop;
+-              /* Trace pointer may have changed */
+-              trace = (struct ioam6_trace_hdr *)(skb_network_header(skb)
+-                                                 + optoff + sizeof(*hdr));
++              /* Trace and hdr pointers may have changed */
++              hdr = (struct ioam6_hdr *)(skb_network_header(skb) + optoff);
++              trace = (struct ioam6_trace_hdr *)((u8 *)hdr + sizeof(*hdr));
+               ioam6_fill_trace_data(skb, ns, trace, true);
diff --git a/queue-6.18/ksmbd-fix-null-pointer-dereference-in-compare_guid_key.patch b/queue-6.18/ksmbd-fix-null-pointer-dereference-in-compare_guid_key.patch
new file mode 100644 (file)
index 0000000..a542a53
--- /dev/null
@@ -0,0 +1,73 @@
+From 4b83cbc4c15f09b000cc06f033f64b0824b6dc87 Mon Sep 17 00:00:00 2001
+From: Jeremy Laratro <research@aradex.io>
+Date: Wed, 13 May 2026 08:26:16 +0900
+Subject: ksmbd: fix null pointer dereference in compare_guid_key()
+
+From: Jeremy Laratro <research@aradex.io>
+
+commit 4b83cbc4c15f09b000cc06f033f64b0824b6dc87 upstream.
+
+session_fd_check() walks the per-inode m_op_list during durable-handle
+session teardown and sets op->conn = NULL for every opinfo whose conn
+matched the closing session's connection. The matching opinfo, however,
+stays linked in its per-ClientGuid lease_table_list entry's lb->lease_list
+because destroy_lease_table() only runs on full TCP-connection teardown,
+not on SESSION_LOGOFF.
+
+If the same TCP connection then negotiates a fresh session with the
+same ClientGuid (ClientGuid is bound to NEGOTIATE, not the session, and
+is unchanged across LOGOFF + SETUP) and issues a SMB2 CREATE with a
+lease context on a different inode, find_same_lease_key() walks
+lb->lease_list, reaches the stale opinfo, and calls compare_guid_key(),
+which unconditionally dereferences opinfo->conn->ClientGUID. The conn
+pointer is NULL and the kernel panics.
+
+Reproducer requires only a successful SMB2 SESSION_SETUP and a share
+configured with 'durable handles = yes'. KASAN report on mainline
+70390501d194:
+
+  general protection fault, probably for non-canonical address
+  0xdffffc0000000069: 0000 [#1] SMP KASAN PTI
+  KASAN: null-ptr-deref in range [0x0000000000000348-0x000000000000034f]
+  Workqueue: ksmbd-io handle_ksmbd_work
+  RIP: 0010:bcmp+0x5b/0x230
+  Call Trace:
+   compare_guid_key+0x4b/0xd0
+   find_same_lease_key+0x324/0x690
+   smb2_open+0x6aea/0x8e60
+   handle_ksmbd_work+0x796/0xee0
+   ...
+
+Faulting address 0x348 is the offset of ClientGUID within struct
+ksmbd_conn, confirming opinfo->conn was NULL.
+
+Read opinfo->conn once and bail out if it has been cleared by a
+concurrent session_fd_check(). A half-detached opinfo cannot be the
+owner of an active lease, so returning 0 is the correct match result.
+
+Fixes: c8efcc786146 ("ksmbd: add support for durable handles v1/v2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeremy Laratro <research@aradex.io>
+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/oplock.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/smb/server/oplock.c
++++ b/fs/smb/server/oplock.c
+@@ -484,8 +484,12 @@ static inline int compare_guid_key(struc
+                                  const char *guid1, const char *key1)
+ {
+       const char *guid2, *key2;
++      struct ksmbd_conn *conn;
+-      guid2 = opinfo->conn->ClientGUID;
++      conn = READ_ONCE(opinfo->conn);
++      if (!conn)
++              return 0;
++      guid2 = conn->ClientGUID;
+       key2 = opinfo->o_lease->lease_key;
+       if (!memcmp(guid1, guid2, SMB2_CLIENT_GUID_SIZE) &&
+           !memcmp(key1, key2, SMB2_LEASE_KEY_SIZE))
diff --git a/queue-6.18/ksmbd-fix-sid-memory-leak-in-set_posix_acl_entries_dacl-on-overflow.patch b/queue-6.18/ksmbd-fix-sid-memory-leak-in-set_posix_acl_entries_dacl-on-overflow.patch
new file mode 100644 (file)
index 0000000..367b366
--- /dev/null
@@ -0,0 +1,76 @@
+From af92ee994cc7f7e83a41c2025f32257a2f82a7ef Mon Sep 17 00:00:00 2001
+From: Ferry Meng <mengferry@linux.alibaba.com>
+Date: Mon, 11 May 2026 21:18:16 +0800
+Subject: ksmbd: fix SID memory leak in set_posix_acl_entries_dacl() on overflow
+
+From: Ferry Meng <mengferry@linux.alibaba.com>
+
+commit af92ee994cc7f7e83a41c2025f32257a2f82a7ef upstream.
+
+Commit 299f962c0b02 ("ksmbd: use check_add_overflow() to prevent u16
+DACL size overflow") added check_add_overflow() guards that break out
+of the ACE-building loops in set_posix_acl_entries_dacl() when the
+accumulated DACL size would wrap past 65535.
+
+However, each iteration allocates a struct smb_sid via kmalloc_obj()
+at the top of the loop and relies on the kfree(sid) call at the end
+of the loop body (the 'pass_same_sid' label in the first loop, and
+the explicit kfree at the tail of the second loop) to release it.
+The newly introduced 'break' statements bypass those kfree() calls,
+leaking the sid buffer every time an overflow is detected.
+
+A malicious or malformed file with enough POSIX ACL entries to trip
+the overflow check will leak one or more struct smb_sid allocations
+on every request that touches the file's DACL, providing a trivial
+kernel memory exhaustion vector.
+
+Free sid before breaking out of the loops to plug the leak.
+
+Fixes: 299f962c0b02 ("ksmbd: use check_add_overflow() to prevent u16 DACL size overflow")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ferry Meng <mengferry@linux.alibaba.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/smbacl.c |   12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/fs/smb/server/smbacl.c
++++ b/fs/smb/server/smbacl.c
+@@ -643,8 +643,10 @@ static void set_posix_acl_entries_dacl(s
+               ntace = (struct smb_ace *)((char *)pndace + *size);
+               ace_sz = fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
+                               pace->e_perm, 0777);
+-              if (check_add_overflow(*size, ace_sz, size))
++              if (check_add_overflow(*size, ace_sz, size)) {
++                      kfree(sid);
+                       break;
++              }
+               (*num_aces)++;
+               if (pace->e_tag == ACL_USER)
+                       ntace->access_req |=
+@@ -655,8 +657,10 @@ static void set_posix_acl_entries_dacl(s
+                       ntace = (struct smb_ace *)((char *)pndace + *size);
+                       ace_sz = fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
+                                       0x03, pace->e_perm, 0777);
+-                      if (check_add_overflow(*size, ace_sz, size))
++                      if (check_add_overflow(*size, ace_sz, size)) {
++                              kfree(sid);
+                               break;
++                      }
+                       (*num_aces)++;
+                       if (pace->e_tag == ACL_USER)
+                               ntace->access_req |=
+@@ -698,8 +702,10 @@ posix_default_acl:
+               ntace = (struct smb_ace *)((char *)pndace + *size);
+               ace_sz = fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
+                               pace->e_perm, 0777);
+-              if (check_add_overflow(*size, ace_sz, size))
++              if (check_add_overflow(*size, ace_sz, size)) {
++                      kfree(sid);
+                       break;
++              }
+               (*num_aces)++;
+               if (pace->e_tag == ACL_USER)
+                       ntace->access_req |=
diff --git a/queue-6.18/ksmbd-validate-sid-in-parent-security-descriptor-during-acl-inheritance.patch b/queue-6.18/ksmbd-validate-sid-in-parent-security-descriptor-during-acl-inheritance.patch
new file mode 100644 (file)
index 0000000..23fa849
--- /dev/null
@@ -0,0 +1,130 @@
+From 69f030cf95488ae1186c72ac8c66fd279664ea7f Mon Sep 17 00:00:00 2001
+From: Junyi Liu <moss80199@gmail.com>
+Date: Tue, 19 May 2026 16:12:04 +0900
+Subject: ksmbd: validate SID in parent security descriptor during ACL inheritance
+
+From: Junyi Liu <moss80199@gmail.com>
+
+commit 69f030cf95488ae1186c72ac8c66fd279664ea7f upstream.
+
+Introduce smb_validate_ntsd_sid() helper to safely validate Owner SID
+and Group SID inside the NT Security Descriptor (smb_ntsd) retrieved
+from the parent directory.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Junyi Liu <moss80199@gmail.com>
+Signed-off-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/smbacl.c |   66 +++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 50 insertions(+), 16 deletions(-)
+
+--- a/fs/smb/server/smbacl.c
++++ b/fs/smb/server/smbacl.c
+@@ -1096,6 +1096,40 @@ static int smb_append_inherited_ace(stru
+       return 0;
+ }
++static int smb_validate_ntsd_sid(struct smb_ntsd *pntsd, size_t pntsd_size,
++                                unsigned int sid_offset, struct smb_sid **sid,
++                                size_t *sid_size)
++{
++      size_t sid_end;
++
++      *sid = NULL;
++      *sid_size = 0;
++
++      if (!sid_offset)
++              return 0;
++
++      if (sid_offset < sizeof(struct smb_ntsd) ||
++          check_add_overflow(sid_offset, (size_t)CIFS_SID_BASE_SIZE,
++                             &sid_end) ||
++          sid_end > pntsd_size)
++              return -EINVAL;
++
++      *sid = (struct smb_sid *)((char *)pntsd + sid_offset);
++      if ((*sid)->num_subauth > SID_MAX_SUB_AUTHORITIES)
++              return -EINVAL;
++
++      if (check_add_overflow((size_t)CIFS_SID_BASE_SIZE,
++                             sizeof(__le32) * (size_t)(*sid)->num_subauth,
++                             &sid_end))
++              return -EINVAL;
++
++      if (sid_offset > pntsd_size || sid_end > pntsd_size - sid_offset)
++              return -EINVAL;
++
++      *sid_size = sid_end;
++      return 0;
++}
++
+ int smb_inherit_dacl(struct ksmbd_conn *conn,
+                    const struct path *path,
+                    unsigned int uid, unsigned int gid)
+@@ -1108,28 +1142,28 @@ int smb_inherit_dacl(struct ksmbd_conn *
+       struct dentry *parent = path->dentry->d_parent;
+       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
+       int inherited_flags = 0, flags = 0, i, nt_size = 0, pdacl_size;
+-      int rc = 0, pntsd_type, pntsd_size, acl_len, aces_size;
++      int rc = 0, pntsd_type, ppntsd_size, acl_len, aces_size;
+       unsigned int dacloffset;
+       size_t dacl_struct_end;
+       u16 num_aces, ace_cnt = 0;
+       char *aces_base;
+       bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
+-      pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
++      ppntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
+                                           parent, &parent_pntsd);
+-      if (pntsd_size <= 0)
++      if (ppntsd_size <= 0)
+               return -ENOENT;
+       dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
+       if (!dacloffset ||
+           check_add_overflow(dacloffset, sizeof(struct smb_acl), &dacl_struct_end) ||
+-          dacl_struct_end > (size_t)pntsd_size) {
++          dacl_struct_end > (size_t)ppntsd_size) {
+               rc = -EINVAL;
+               goto free_parent_pntsd;
+       }
+       parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
+-      acl_len = pntsd_size - dacloffset;
++      acl_len = ppntsd_size - dacloffset;
+       num_aces = le16_to_cpu(parent_pdacl->num_aces);
+       pntsd_type = le16_to_cpu(parent_pntsd->type);
+       pdacl_size = le16_to_cpu(parent_pdacl->size);
+@@ -1243,19 +1277,19 @@ pass:
+               struct smb_ntsd *pntsd;
+               struct smb_acl *pdacl;
+               struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
+-              int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
++              size_t powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
+               size_t pntsd_alloc_size;
+-              if (parent_pntsd->osidoffset) {
+-                      powner_sid = (struct smb_sid *)((char *)parent_pntsd +
+-                                      le32_to_cpu(parent_pntsd->osidoffset));
+-                      powner_sid_size = 1 + 1 + 6 + (powner_sid->num_subauth * 4);
+-              }
+-              if (parent_pntsd->gsidoffset) {
+-                      pgroup_sid = (struct smb_sid *)((char *)parent_pntsd +
+-                                      le32_to_cpu(parent_pntsd->gsidoffset));
+-                      pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
+-              }
++              rc = smb_validate_ntsd_sid(parent_pntsd, ppntsd_size,
++                                         le32_to_cpu(parent_pntsd->osidoffset),
++                                         &powner_sid, &powner_sid_size);
++              if (rc)
++                      goto free_aces_base;
++              rc = smb_validate_ntsd_sid(parent_pntsd, ppntsd_size,
++                                         le32_to_cpu(parent_pntsd->gsidoffset),
++                                         &pgroup_sid, &pgroup_sid_size);
++              if (rc)
++                      goto free_aces_base;
+               if (check_add_overflow(sizeof(struct smb_ntsd),
+                                      (size_t)powner_sid_size,
diff --git a/queue-6.18/mm-damon-sysfs-schemes-call-missing-mem_cgroup_iter_break.patch b/queue-6.18/mm-damon-sysfs-schemes-call-missing-mem_cgroup_iter_break.patch
new file mode 100644 (file)
index 0000000..852e8b6
--- /dev/null
@@ -0,0 +1,36 @@
+From d4e7b5c4cc353f154d5ab8bb2e1ce7714d77a6e9 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sj@kernel.org>
+Date: Sun, 26 Apr 2026 10:36:12 -0700
+Subject: mm/damon/sysfs-schemes: call missing mem_cgroup_iter_break()
+
+From: SeongJae Park <sj@kernel.org>
+
+commit d4e7b5c4cc353f154d5ab8bb2e1ce7714d77a6e9 upstream.
+
+damon_sysfs_memcg_path_to_id() breaks mem_cgroup_iter() loop without
+calling mem_cgroup_iter_break().  This leaks the cgroup reference.  Fix
+the issue by calling mem_cgroup_iter_break() before the break.
+
+The issue was discovered [1] by Sashiko.
+
+Link: https://lore.kernel.org/20260426173625.86521-1-sj@kernel.org
+Link: https://lore.kernel.org/20260423004148.74722-1-sj@kernel.org [1]
+Fixes: 29cbb9a13f05 ("mm/damon/sysfs-schemes: implement scheme filters")
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 6.3.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/sysfs-schemes.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/mm/damon/sysfs-schemes.c
++++ b/mm/damon/sysfs-schemes.c
+@@ -2444,6 +2444,7 @@ static int damon_sysfs_memcg_path_to_id(
+               if (damon_sysfs_memcg_path_eq(memcg, path, memcg_path)) {
+                       *id = mem_cgroup_id(memcg);
+                       found = true;
++                      mem_cgroup_iter_break(NULL, memcg);
+                       break;
+               }
+       }
diff --git a/queue-6.18/mm-fix-__vm_normal_page-to-handle-missing-support-for-pmd_special-pud_special.patch b/queue-6.18/mm-fix-__vm_normal_page-to-handle-missing-support-for-pmd_special-pud_special.patch
new file mode 100644 (file)
index 0000000..82c2558
--- /dev/null
@@ -0,0 +1,105 @@
+From c0c6ccd9828c3a1950623b546fa57292a77b5c73 Mon Sep 17 00:00:00 2001
+From: "David Hildenbrand (Arm)" <david@kernel.org>
+Date: Thu, 30 Apr 2026 13:31:22 +0200
+Subject: mm: fix __vm_normal_page() to handle missing support for pmd_special()/pud_special()
+
+From: David Hildenbrand (Arm) <david@kernel.org>
+
+commit c0c6ccd9828c3a1950623b546fa57292a77b5c73 upstream.
+
+On x86 32-bit with THP enabled, zap_huge_pmd() is seen to generate a
+"WARNING: mm/memory.c:735 at __vm_normal_page+0x6a/0x7d", from the
+VM_WARN_ON_ONCE(is_zero_pfn(pfn) || is_huge_zero_pfn(pfn)); followed by
+"BUG: Bad rss-counter state"s, then later "BUG: Bad page state"s when
+reclaim gets to call shrink_huge_zero_folio_scan().
+
+It's as if the _PAGE_SPECIAL bit never got set in the huge_zero pmd: and
+indeed, whereas pte_special() and pte_mkspecial() are subject to a
+dedicated CONFIG_ARCH_HAS_PTE_SPECIAL, pmd_special() and pmd_mkspecial()
+are subject to CONFIG_ARCH_SUPPORTS_PMD_PFNMAP, which is never enabled on
+any 32-bit architecture.
+
+While the problem was exposed through commit d80a9cb1a64a
+("mm/huge_memory: add and use normal_or_softleaf_folio_pmd()"), it was an
+oversight in commit af38538801c6 ("mm/memory: factor out common code from
+vm_normal_page_*()") and would result in other problems:
+* huge zero folio accounted in smaps, pagemap (PAGE_IS_FILE) and
+  numamaps as file-backed THP
+* folio_walk_start() returning the folio even without FW_ZEROPAGE set.
+  Callers seem to tolerate that, though.
+
+... and triggering the VM_WARN_ON_ONE(), although never reported so far.
+
+To fix it, teach vm_normal_page_pmd()/vm_normal_page_pud() to consider
+whether pmd_special/pud_special is actually implemented.
+
+Link: https://lore.kernel.org/20260430-pmd_special-v1-1-dbcbcfd72c20@kernel.org
+Fixes: af38538801c6 ("mm/memory: factor out common code from vm_normal_page_*()")
+Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
+Reported-by: Hugh Dickins <hughd@google.com>
+Closes: https://lore.kernel.org/r/74a75b59-2e13-3985-ee99-d5521f39df2a@google.com
+Reported-by: Bibo Mao <maobibo@loongson.cn>
+Closes: https://lore.kernel.org/r/20260430041121.2839350-1-maobibo@loongson.cn
+Debugged-by: Hugh Dickins <hughd@google.com>
+Reviewed-by: Lance Yang <lance.yang@linux.dev>
+Tested-by: Bibo Mao <maobibo@loongson.cn>
+Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
+Reviewed-by: Oscar Salvador <osalvador@suse.de>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: Liam R. Howlett <liam@infradead.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memory.c |   22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -612,6 +612,21 @@ static void print_bad_page_map(struct vm
+       dump_stack();
+       add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
+ }
++
++static inline bool pgtable_level_has_pxx_special(enum pgtable_level level)
++{
++      switch (level) {
++      case PGTABLE_LEVEL_PTE:
++              return IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL);
++      case PGTABLE_LEVEL_PMD:
++              return IS_ENABLED(CONFIG_ARCH_SUPPORTS_PMD_PFNMAP);
++      case PGTABLE_LEVEL_PUD:
++              return IS_ENABLED(CONFIG_ARCH_SUPPORTS_PUD_PFNMAP);
++      default:
++              return false;
++      }
++}
++
+ #define print_bad_pte(vma, addr, pte, page) \
+       print_bad_page_map(vma, addr, pte_val(pte), page, PGTABLE_LEVEL_PTE)
+@@ -684,7 +699,7 @@ static inline struct page *__vm_normal_p
+               unsigned long addr, unsigned long pfn, bool special,
+               unsigned long long entry, enum pgtable_level level)
+ {
+-      if (IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL)) {
++      if (pgtable_level_has_pxx_special(level)) {
+               if (unlikely(special)) {
+ #ifdef CONFIG_FIND_NORMAL_PAGE
+                       if (vma->vm_ops && vma->vm_ops->find_normal_page)
+@@ -699,8 +714,9 @@ static inline struct page *__vm_normal_p
+                       return NULL;
+               }
+               /*
+-               * With CONFIG_ARCH_HAS_PTE_SPECIAL, any special page table
+-               * mappings (incl. shared zero folios) are marked accordingly.
++               * With working pte_special()/pmd_special()..., any special page
++               * table mappings (incl. shared zero folios) are marked
++               * accordingly.
+                */
+       } else {
+               if (unlikely(vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))) {
diff --git a/queue-6.18/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch b/queue-6.18/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
new file mode 100644 (file)
index 0000000..c11410b
--- /dev/null
@@ -0,0 +1,190 @@
+From be3f38d05cc5a7c3f13e51994c5dd043ab604d28 Mon Sep 17 00:00:00 2001
+From: Alistair Popple <apopple@nvidia.com>
+Date: Fri, 1 May 2026 16:51:16 +1000
+Subject: mm/memory: fix spurious warning when unmapping device-private/exclusive pages
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alistair Popple <apopple@nvidia.com>
+
+commit be3f38d05cc5a7c3f13e51994c5dd043ab604d28 upstream.
+
+Device private and exclusive entries are only supported for anonymous
+folios.  This condition is tested in __migrate_device_pages() and
+make_device_exclusive() using folio_test_anon().  However the unmap path
+tests this assumption using vma_is_anonymous().
+
+This is wrong because whilst anonymous VMAs can only contain folios where
+folio_test_anon() is true the opposite relation does not hold.  A folio
+for which folio_test_anon() is true does not imply vma_is_anonymous() is
+true.  Such a condition can occur if for example a folio is part of a
+private filebacked mapping.
+
+In this case vma_is_anonymous() is false as the mapping is filebacked, but
+folio_test_anon() may be true, thus permitting devices to migrate the
+folio to device private memory.  This can lead to the following spurious
+warnings during process teardown:
+
+[  772.737706] ------------[ cut here ]------------
+[  772.739201] WARNING: mm/memory.c:1754 at unmap_page_range.cold+0x26/0x18a, CPU#17: hmm-tests/2041
+[  772.742050] Modules linked in: test_hmm nvidia_uvm(O) nvidia(O)
+[  772.743959] CPU: 17 UID: 0 PID: 2041 Comm: hmm-tests Tainted: G        W  O        7.0.0+ #387 PREEMPT(full)
+[  772.747104] Tainted: [W]=WARN, [O]=OOT_MODULE
+[  772.748509] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
+[  772.752117] RIP: 0010:unmap_page_range.cold+0x26/0x18a
+[  772.753780] Code: 7e fe ff ff 48 89 4c 24 78 4c 89 44 24 38 e8 f2 ff b1 00 48 8b 4c 24 78 4c 8b 44 24 38 48 8b 44 24 18 48 83 78 48 00 74 04 90 <0f> 0b 90 48 89 ca b8 ff ff 37 00 48 c1 ea 03 48 c1 e0 2a 80 3c 02
+[  772.759602] RSP: 0018:ffff888112607550 EFLAGS: 00010286
+[  772.761310] RAX: ffff88811bbf4dc0 RBX: dffffc0000000000 RCX: ffffea03e9bfffd8
+[  772.763583] RDX: 1ffff1102377e9c1 RSI: 0000000000000008 RDI: ffff88811bbf4e08
+[  772.765914] RBP: 0000000000000006 R08: ffff8881059f7448 R09: ffffed10224c0e68
+[  772.768184] R10: ffff888112607347 R11: 0000000000000001 R12: 0000000000000001
+[  772.770461] R13: ffffea03e9bfffc0 R14: ffff888112607908 R15: ffffea03e9bfffc0
+[  772.772782] FS:  00007f327caa2780(0000) GS:ffff888427b7d000(0000) knlGS:0000000000000000
+[  772.775328] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  772.777187] CR2: 00007f327ca89000 CR3: 00000001994d5000 CR4: 00000000000006f0
+[  772.779135] Call Trace:
+[  772.779792]  <TASK>
+[  772.780317]  ? dmirror_interval_invalidate+0x1a3/0x290 [test_hmm]
+[  772.781873]  ? vm_normal_page_pud+0x2b0/0x2b0
+[  772.782992]  ? __rwlock_init+0x150/0x150
+[  772.784006]  ? lock_release+0x216/0x2b0
+[  772.785008]  ? __mmu_notifier_invalidate_range_start+0x505/0x6e0
+[  772.786522]  ? lock_release+0x216/0x2b0
+[  772.787498]  ? unmap_single_vma+0xb6/0x210
+[  772.788573]  unmap_vmas+0x27d/0x520
+[  772.789506]  ? unmap_single_vma+0x210/0x210
+[  772.790607]  ? mas_update_gap.part.0+0x620/0x620
+[  772.791834]  unmap_region+0x19e/0x350
+[  772.792769]  ? remove_vma+0x130/0x130
+[  772.793684]  ? mas_alloc_nodes+0x1f2/0x300
+[  772.794730]  vms_complete_munmap_vmas+0x8c1/0xe20
+[  772.795926]  ? unmap_region+0x350/0x350
+[  772.796917]  do_vmi_align_munmap+0x36a/0x4e0
+[  772.798018]  ? lock_release+0x216/0x2b0
+[  772.799024]  ? vma_shrink+0x620/0x620
+[  772.799983]  do_vmi_munmap+0x150/0x2c0
+[  772.800939]  __vm_munmap+0x161/0x2c0
+[  772.801872]  ? expand_downwards+0xd60/0xd60
+[  772.802948]  ? clockevents_program_event+0x1ef/0x540
+[  772.804217]  ? lock_release+0x216/0x2b0
+[  772.805158]  __x64_sys_munmap+0x59/0x80
+[  772.805776]  do_syscall_64+0xfc/0x670
+[  772.806336]  ? irqentry_exit+0xda/0x580
+[  772.806976]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[  772.807772] RIP: 0033:0x7f327cbb2717
+[  772.808323] Code: 73 01 c3 48 8b 0d f9 76 0d 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 0b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c9 76 0d 00 f7 d8 64 89 01 48
+[  772.811337] RSP: 002b:00007ffde7f57d38 EFLAGS: 00000202 ORIG_RAX: 000000000000000b
+[  772.812564] RAX: ffffffffffffffda RBX: 00007f327cc9c000 RCX: 00007f327cbb2717
+[  772.813733] RDX: 0000000000000000 RSI: 0000000000400000 RDI: 00007f327c289000
+[  772.814867] RBP: 0000000000421360 R08: 000000000000001a R09: 0000000000000000
+[  772.815991] R10: 0000000000000003 R11: 0000000000000202 R12: 00007ffde7f57d74
+[  772.817121] R13: 00007f327c689010 R14: 0000000000100000 R15: 00007f327c289000
+[  772.818272]  </TASK>
+[  772.818614] irq event stamp: 0
+[  772.819159] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
+[  772.820174] hardirqs last disabled at (0): [<ffffffff82a57ab3>] copy_process+0x19f3/0x6440
+[  772.821511] softirqs last  enabled at (0): [<ffffffff82a57b00>] copy_process+0x1a40/0x6440
+[  772.822869] softirqs last disabled at (0): [<0000000000000000>] 0x0
+[  772.823871] ---[ end trace 0000000000000000 ]---
+
+Fix this by using the same check for folio_test_anon() in
+zap_nonpresent_ptes(). Also add a hmm-test case for this.
+
+Link: https://lore.kernel.org/20260501065116.2057242-1-apopple@nvidia.com
+Fixes: 999dad824c39 ("mm/shmem: persist uffd-wp bit across zapping for file-backed")
+Signed-off-by: Alistair Popple <apopple@nvidia.com>
+Reported-by: Arsen Arsenović <aarsenovic@baylibre.com>
+Reviewed-by: Balbir Singh <balbirs@nvidia.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Leon Romanovsky <leon@kernel.org>
+Cc: Liam R. Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes <ljs@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memory.c                            |    2 -
+ tools/testing/selftests/mm/hmm-tests.c |   50 +++++++++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+), 1 deletion(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1735,7 +1735,7 @@ static inline int zap_nonpresent_ptes(st
+                * consider uffd-wp bit when zap. For more information,
+                * see zap_install_uffd_wp_if_needed().
+                */
+-              WARN_ON_ONCE(!vma_is_anonymous(vma));
++              WARN_ON_ONCE(!folio_test_anon(folio));
+               rss[mm_counter(folio)]--;
+               folio_remove_rmap_pte(folio, page, vma);
+               folio_put(folio);
+--- a/tools/testing/selftests/mm/hmm-tests.c
++++ b/tools/testing/selftests/mm/hmm-tests.c
+@@ -999,6 +999,56 @@ TEST_F(hmm, migrate)
+ }
+ /*
++ * Migrate private file memory to device private memory.
++ */
++TEST_F(hmm, migrate_file_private)
++{
++      struct hmm_buffer *buffer;
++      unsigned long npages;
++      unsigned long size;
++      unsigned long i;
++      int *ptr;
++      int ret;
++      int fd;
++
++      npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
++      ASSERT_NE(npages, 0);
++      size = npages << self->page_shift;
++
++      fd = hmm_create_file(size);
++      ASSERT_GE(fd, 0);
++
++      buffer = malloc(sizeof(*buffer));
++      ASSERT_NE(buffer, NULL);
++
++      buffer->fd = fd;
++      buffer->size = size;
++      buffer->mirror = malloc(size);
++      ASSERT_NE(buffer->mirror, NULL);
++
++      buffer->ptr = mmap(NULL, size,
++                         PROT_READ | PROT_WRITE,
++                         MAP_PRIVATE,
++                         buffer->fd, 0);
++      ASSERT_NE(buffer->ptr, MAP_FAILED);
++
++      /* Initialize buffer in system memory. */
++      for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
++              ptr[i] = i;
++
++      /* Migrate memory to device. */
++      ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
++      ASSERT_EQ(ret, 0);
++      ASSERT_EQ(buffer->cpages, npages);
++
++      /* Check what the device read. */
++      for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
++              ASSERT_EQ(ptr[i], i);
++
++      hmm_buffer_free(buffer);
++}
++
++/*
+  * Migrate anonymous memory to device private memory and fault some of it back
+  * to system memory, then try migrating the resulting mix of system and device
+  * private memory to the device.
diff --git a/queue-6.18/mm-memory_hotplug-fix-memory-block-reference-leak-on-remove.patch b/queue-6.18/mm-memory_hotplug-fix-memory-block-reference-leak-on-remove.patch
new file mode 100644 (file)
index 0000000..f721921
--- /dev/null
@@ -0,0 +1,57 @@
+From 93866f55f7e292fe3d47d36c9efe5ee10213a06b Mon Sep 17 00:00:00 2001
+From: Muchun Song <songmuchun@bytedance.com>
+Date: Tue, 28 Apr 2026 16:52:17 +0800
+Subject: mm/memory_hotplug: fix memory block reference leak on remove
+
+From: Muchun Song <songmuchun@bytedance.com>
+
+commit 93866f55f7e292fe3d47d36c9efe5ee10213a06b upstream.
+
+Patch series "mm: Fix memory block leaks and locking", v2.
+
+This series fixes two memory block device reference leaks and one locking
+issue around the per-memory_block hwpoison counter.
+
+
+This patch (of 2):
+
+remove_memory_blocks_and_altmaps() looks up each memory block with
+find_memory_block(), which acquires a reference to the memory block
+device.
+
+That reference is never dropped on this path, resulting in a leaked device
+reference when removing memory blocks and their altmaps.  Drop the
+reference after retrieving mem->altmap and clearing mem->altmap, before
+removing the memory block device.
+
+Link: https://lore.kernel.org/20260428085219.1316047-1-songmuchun@bytedance.com
+Link: https://lore.kernel.org/20260428085219.1316047-2-songmuchun@bytedance.com
+Fixes: 6b8f0798b85a ("mm/memory_hotplug: split memmap_on_memory requests across memblocks")
+Signed-off-by: Muchun Song <songmuchun@bytedance.com>
+Acked-by: Oscar Salvador <osalvador@suse.de>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Cc: Danilo Krummrich <dakr@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: "Huang, Ying" <huang.ying.caritas@gmail.com>
+Cc: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Vishal Verma <vishal.l.verma@intel.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/memory_hotplug.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -1439,6 +1439,8 @@ static void remove_memory_blocks_and_alt
+               altmap = mem->altmap;
+               mem->altmap = NULL;
++              /* drop the ref. we got via find_memory_block() */
++              put_device(&mem->dev);
+               remove_memory_block_devices(cur_start, memblock_size);
diff --git a/queue-6.18/mm-page_alloc-fix-initialization-of-tags-of-the-huge-zero-folio-with-init_on_free.patch b/queue-6.18/mm-page_alloc-fix-initialization-of-tags-of-the-huge-zero-folio-with-init_on_free.patch
new file mode 100644 (file)
index 0000000..ece2277
--- /dev/null
@@ -0,0 +1,189 @@
+From 6a288a4ddb4a994490505ab5f41c445f8e6b6467 Mon Sep 17 00:00:00 2001
+From: "David Hildenbrand (Arm)" <david@kernel.org>
+Date: Tue, 21 Apr 2026 17:39:07 +0200
+Subject: mm/page_alloc: fix initialization of tags of the huge zero folio with init_on_free
+
+From: David Hildenbrand (Arm) <david@kernel.org>
+
+commit 6a288a4ddb4a994490505ab5f41c445f8e6b6467 upstream.
+
+__GFP_ZEROTAGS semantics are currently a bit weird, but effectively this
+flag is only ever set alongside __GFP_ZERO and __GFP_SKIP_KASAN.
+
+If we run with init_on_free, we will zero out pages during
+__free_pages_prepare(), to skip zeroing on the allocation path.
+
+However, when allocating with __GFP_ZEROTAG set, post_alloc_hook() will
+consequently not only skip clearing page content, but also skip clearing
+tag memory.
+
+Not clearing tags through __GFP_ZEROTAGS is irrelevant for most pages that
+will get mapped to user space through set_pte_at() later: set_pte_at() and
+friends will detect that the tags have not been initialized yet
+(PG_mte_tagged not set), and initialize them.
+
+However, for the huge zero folio, which will be mapped through a PMD
+marked as special, this initialization will not be performed, ending up
+exposing whatever tags were still set for the pages.
+
+The docs (Documentation/arch/arm64/memory-tagging-extension.rst) state
+that allocation tags are set to 0 when a page is first mapped to user
+space.  That no longer holds with the huge zero folio when init_on_free is
+enabled.
+
+Fix it by decoupling __GFP_ZEROTAGS from __GFP_ZERO, passing to
+tag_clear_highpages() whether we want to also clear page content.
+
+Invert the meaning of the tag_clear_highpages() return value to have
+clearer semantics.
+
+Reproduced with the huge zero folio by modifying the check_buffer_fill
+arm64/mte selftest to use a 2 MiB area, after making sure that pages have
+a non-0 tag set when freeing (note that, during boot, we will not actually
+initialize tags, but only set KASAN_TAG_KERNEL in the page flags).
+
+       $ ./check_buffer_fill
+       1..20
+       ...
+       not ok 17 Check initial tags with private mapping, sync error mode and mmap memory
+       not ok 18 Check initial tags with private mapping, sync error mode and mmap/mprotect memory
+       ...
+
+This code needs more cleanups; we'll tackle that next, like
+decoupling __GFP_ZEROTAGS from __GFP_SKIP_KASAN.
+
+[akpm@linux-foundation.org: s/__GPF_ZERO/__GFP_ZERO/, per David]
+Link: https://lore.kernel.org/20260421-zerotags-v2-1-05cb1035482e@kernel.org
+Fixes: adfb6609c680 ("mm/huge_memory: initialise the tags of the huge zero folio")
+Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Tested-by: Lance Yang <lance.yang@linux.dev>
+Cc: Brendan Jackman <jackmanb@google.com>
+Cc: Dev Jain <dev.jain@arm.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Liam Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Zi Yan <ziy@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/page.h |    2 +-
+ arch/arm64/mm/fault.c         |   11 +++++++----
+ include/linux/gfp_types.h     |   10 +++++-----
+ include/linux/highmem.h       |    7 ++++---
+ mm/page_alloc.c               |    8 ++++----
+ 5 files changed, 21 insertions(+), 17 deletions(-)
+
+--- a/arch/arm64/include/asm/page.h
++++ b/arch/arm64/include/asm/page.h
+@@ -33,7 +33,7 @@ struct folio *vma_alloc_zeroed_movable_f
+                                               unsigned long vaddr);
+ #define vma_alloc_zeroed_movable_folio vma_alloc_zeroed_movable_folio
+-bool tag_clear_highpages(struct page *to, int numpages);
++bool tag_clear_highpages(struct page *to, int numpages, bool clear_pages);
+ #define __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
+ #define clear_user_page(page, vaddr, pg)      clear_page(page)
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -967,7 +967,7 @@ struct folio *vma_alloc_zeroed_movable_f
+       return vma_alloc_folio(flags, 0, vma, vaddr);
+ }
+-bool tag_clear_highpages(struct page *page, int numpages)
++bool tag_clear_highpages(struct page *page, int numpages, bool clear_pages)
+ {
+       /*
+        * Check if MTE is supported and fall back to clear_highpage().
+@@ -975,13 +975,16 @@ bool tag_clear_highpages(struct page *pa
+        * post_alloc_hook() will invoke tag_clear_highpages().
+        */
+       if (!system_supports_mte())
+-              return false;
++              return clear_pages;
+       /* Newly allocated pages, shouldn't have been tagged yet */
+       for (int i = 0; i < numpages; i++, page++) {
+               WARN_ON_ONCE(!try_page_mte_tagging(page));
+-              mte_zero_clear_page_tags(page_address(page));
++              if (clear_pages)
++                      mte_zero_clear_page_tags(page_address(page));
++              else
++                      mte_clear_page_tags(page_address(page));
+               set_page_mte_tagged(page);
+       }
+-      return true;
++      return false;
+ }
+--- a/include/linux/gfp_types.h
++++ b/include/linux/gfp_types.h
+@@ -277,11 +277,11 @@ enum {
+  *
+  * %__GFP_ZERO returns a zeroed page on success.
+  *
+- * %__GFP_ZEROTAGS zeroes memory tags at allocation time if the memory itself
+- * is being zeroed (either via __GFP_ZERO or via init_on_alloc, provided that
+- * __GFP_SKIP_ZERO is not set). This flag is intended for optimization: setting
+- * memory tags at the same time as zeroing memory has minimal additional
+- * performance impact.
++ * %__GFP_ZEROTAGS zeroes memory tags at allocation time. Setting memory tags at
++ * the same time as zeroing memory (e.g., with __GFP_ZERO) has minimal
++ * additional performance impact. However, __GFP_ZEROTAGS also zeroes the tags
++ * even if memory is not getting zeroed at allocation time (e.g.,
++ * with init_on_free).
+  *
+  * %__GFP_SKIP_KASAN makes KASAN skip unpoisoning on page allocation.
+  * Used for userspace and vmalloc pages; the latter are unpoisoned by
+--- a/include/linux/highmem.h
++++ b/include/linux/highmem.h
+@@ -251,10 +251,11 @@ static inline void clear_highpage_kasan_
+ #ifndef __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
+-/* Return false to let people know we did not initialize the pages */
+-static inline bool tag_clear_highpages(struct page *page, int numpages)
++/* Returns true if the caller has to initialize the pages */
++static inline bool tag_clear_highpages(struct page *page, int numpages,
++              bool clear_pages)
+ {
+-      return false;
++      return clear_pages;
+ }
+ #endif
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1847,9 +1847,9 @@ static inline bool should_skip_init(gfp_
+ inline void post_alloc_hook(struct page *page, unsigned int order,
+                               gfp_t gfp_flags)
+ {
++      const bool zero_tags = gfp_flags & __GFP_ZEROTAGS;
+       bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) &&
+                       !should_skip_init(gfp_flags);
+-      bool zero_tags = init && (gfp_flags & __GFP_ZEROTAGS);
+       int i;
+       set_page_private(page, 0);
+@@ -1871,11 +1871,11 @@ inline void post_alloc_hook(struct page
+        */
+       /*
+-       * If memory tags should be zeroed
+-       * (which happens only when memory should be initialized as well).
++       * Clearing tags can efficiently clear the memory for us as well, if
++       * required.
+        */
+       if (zero_tags)
+-              init = !tag_clear_highpages(page, 1 << order);
++              init = tag_clear_highpages(page, 1 << order, /* clear_pages= */init);
+       if (!should_skip_kasan_unpoison(gfp_flags) &&
+           kasan_unpoison_pages(page, order, init)) {
diff --git a/queue-6.18/net-bcmgenet-keep-rbuf-eee-pm-disabled.patch b/queue-6.18/net-bcmgenet-keep-rbuf-eee-pm-disabled.patch
new file mode 100644 (file)
index 0000000..10a264d
--- /dev/null
@@ -0,0 +1,62 @@
+From 9a1730245e416d11ad5c0f2c100061d61cc43f60 Mon Sep 17 00:00:00 2001
+From: Nicolai Buchwitz <nb@tipi-net.de>
+Date: Wed, 20 May 2026 20:43:20 +0200
+Subject: net: bcmgenet: keep RBUF EEE/PM disabled
+
+From: Nicolai Buchwitz <nb@tipi-net.de>
+
+commit 9a1730245e416d11ad5c0f2c100061d61cc43f60 upstream.
+
+Setting RBUF_EEE_EN | RBUF_PM_EN in RBUF_ENERGY_CTRL breaks the RX
+path on GENET hardware once MAC EEE becomes active. RX traffic stops
+flowing while the link stays up and the usual descriptor/RX error
+counters remain quiet. In that state the MAC still accepts frames
+(rbuf_ovflow_cnt keeps climbing) but RBUF no longer forwards them to
+DMA, so rx_packets is no longer incremented at the netdev level. On
+some boards the corruption ends up as a paging fault in
+skb_release_data via bcmgenet_rx_poll on an LPI exit.
+
+Reproduced on Pi 4B (BCM2711 + BCM54213PE) and confirmed by Florian
+Fainelli on an internal Broadcom 4908-family board with the same crash
+signature. RBUF_PM_EN is not publicly documented.
+
+This shows up more often now that phy_support_eee() enables EEE by
+default, but it also affects older kernels as soon as TX LPI is
+turned on via ethtool, so it is not specific to recent changes.
+
+Always clear RBUF_EEE_EN | RBUF_PM_EN in bcmgenet_eee_enable_set so
+the bits stay off across resets. UMAC and TBUF setup is left alone so
+TX-side EEE keeps working.
+
+Link: https://github.com/raspberrypi/linux/issues/7304
+Fixes: 6ef398ea60d9 ("net: bcmgenet: add EEE support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20260520184320.652053-1-nb@tipi-net.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmgenet.c |    9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -1369,13 +1369,12 @@ void bcmgenet_eee_enable_set(struct net_
+               reg &= ~(TBUF_EEE_EN | TBUF_PM_EN);
+       bcmgenet_writel(reg, priv->base + off);
+-      /* Do the same for thing for RBUF */
++      /* RBUF EEE/PM can break the RX path on GENET. Keep it disabled. */
+       reg = bcmgenet_rbuf_readl(priv, RBUF_ENERGY_CTRL);
+-      if (enable)
+-              reg |= RBUF_EEE_EN | RBUF_PM_EN;
+-      else
++      if (reg & (RBUF_EEE_EN | RBUF_PM_EN)) {
+               reg &= ~(RBUF_EEE_EN | RBUF_PM_EN);
+-      bcmgenet_rbuf_writel(priv, reg, RBUF_ENERGY_CTRL);
++              bcmgenet_rbuf_writel(priv, reg, RBUF_ENERGY_CTRL);
++      }
+       if (!enable && priv->clk_eee_enabled) {
+               clk_disable_unprepare(priv->clk_eee);
diff --git a/queue-6.18/net-ifb-report-ethtool-stats-over-num_tx_queues.patch b/queue-6.18/net-ifb-report-ethtool-stats-over-num_tx_queues.patch
new file mode 100644 (file)
index 0000000..9770fe3
--- /dev/null
@@ -0,0 +1,101 @@
+From 5db89c99566fc4728cc92e941d8e1975711e24b5 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Wed, 13 May 2026 21:37:39 -0400
+Subject: net: ifb: report ethtool stats over num_tx_queues
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 5db89c99566fc4728cc92e941d8e1975711e24b5 upstream.
+
+ifb_dev_init() allocates dp->tx_private to dev->num_tx_queues
+entries via kzalloc_objs(*txp, dev->num_tx_queues). Both IFB
+per-queue RX and TX stats live in those entries: ifb_xmit() updates
+txp->rx_stats using the skb queue mapping, ifb_ri_tasklet() updates
+txp->tx_stats, and ifb_stats64() aggregates both over
+dev->num_tx_queues.
+
+The ethtool stats callbacks instead size and walk the per-queue
+stats with dev->real_num_rx_queues and dev->real_num_tx_queues. With
+an asymmetric device where the RX queue count exceeds the TX queue
+count, for example:
+
+    ip link add name ifb10 numtxqueues 1 numrxqueues 8 type ifb
+    ethtool -S ifb10
+
+ifb_get_ethtool_stats() indexes past the tx_private allocation and
+copies adjacent slab data through ETHTOOL_GSTATS.
+
+Use dev->num_tx_queues consistently for the stats strings, the
+stats count, and the stats data walks. This reports one RX stats
+group and one TX stats group for each backing ifb_q_private entry,
+which is the queue set IFB can actually populate.
+
+Reproduced under UML+KASAN at v7.1-rc2:
+
+  BUG: KASAN: slab-out-of-bounds in ifb_fill_stats_data+0x3c/0xae
+  Read of size 8 at addr 0000000062dbd228 by task ethtool/36
+  ifb_fill_stats_data+0x3c/0xae
+  ifb_get_ethtool_stats+0xc0/0x129
+  __dev_ethtool+0x1ca5/0x363c
+  dev_ethtool+0x123/0x1b3
+  dev_ioctl+0x56c/0x744
+  sock_do_ioctl+0x15f/0x1b2
+  sock_ioctl+0x4d5/0x50a
+  sys_ioctl+0xd8b/0xde9
+
+With the patch applied, the same UML+KASAN repro is silent and
+ethtool -S ifb10 reports only the stats backed by the single
+allocated tx_private entry.
+
+Fixes: a21ee5b2fcb8 ("net: ifb: support ethtools stats")
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/20260514013739.3549624-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ifb.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ifb.c
++++ b/drivers/net/ifb.c
+@@ -211,12 +211,12 @@ static void ifb_get_strings(struct net_d
+       switch (stringset) {
+       case ETH_SS_STATS:
+-              for (i = 0; i < dev->real_num_rx_queues; i++)
++              for (i = 0; i < dev->num_tx_queues; i++)
+                       for (j = 0; j < IFB_Q_STATS_LEN; j++)
+                               ethtool_sprintf(&p, "rx_queue_%u_%.18s",
+                                               i, ifb_q_stats_desc[j].desc);
+-              for (i = 0; i < dev->real_num_tx_queues; i++)
++              for (i = 0; i < dev->num_tx_queues; i++)
+                       for (j = 0; j < IFB_Q_STATS_LEN; j++)
+                               ethtool_sprintf(&p, "tx_queue_%u_%.18s",
+                                               i, ifb_q_stats_desc[j].desc);
+@@ -229,8 +229,7 @@ static int ifb_get_sset_count(struct net
+ {
+       switch (sset) {
+       case ETH_SS_STATS:
+-              return IFB_Q_STATS_LEN * (dev->real_num_rx_queues +
+-                                        dev->real_num_tx_queues);
++              return IFB_Q_STATS_LEN * dev->num_tx_queues * 2;
+       default:
+               return -EOPNOTSUPP;
+       }
+@@ -262,12 +261,12 @@ static void ifb_get_ethtool_stats(struct
+       struct ifb_q_private *txp;
+       int i;
+-      for (i = 0; i < dev->real_num_rx_queues; i++) {
++      for (i = 0; i < dev->num_tx_queues; i++) {
+               txp = dp->tx_private + i;
+               ifb_fill_stats_data(&data, &txp->rx_stats);
+       }
+-      for (i = 0; i < dev->real_num_tx_queues; i++) {
++      for (i = 0; i < dev->num_tx_queues; i++) {
+               txp = dp->tx_private + i;
+               ifb_fill_stats_data(&data, &txp->tx_stats);
+       }
diff --git a/queue-6.18/net-mlx5e-fix-use-after-free-in-mlx5e_tx_reporter_timeout_recover.patch b/queue-6.18/net-mlx5e-fix-use-after-free-in-mlx5e_tx_reporter_timeout_recover.patch
new file mode 100644 (file)
index 0000000..f95d6ea
--- /dev/null
@@ -0,0 +1,73 @@
+From 7d260c5d2d89eb2c8c528d54b576b3aae3e20231 Mon Sep 17 00:00:00 2001
+From: Matt Fleming <mfleming@cloudflare.com>
+Date: Wed, 13 May 2026 12:22:26 +0100
+Subject: net/mlx5e: Fix use-after-free in mlx5e_tx_reporter_timeout_recover
+
+From: Matt Fleming <mfleming@cloudflare.com>
+
+commit 7d260c5d2d89eb2c8c528d54b576b3aae3e20231 upstream.
+
+mlx5e_tx_reporter_timeout_recover() accesses sq->netdev after
+mlx5e_safe_reopen_channels() has torn down and freed the channel (and
+its embedded SQs). Replace the three sq->netdev references with
+priv->netdev which is safe because priv outlives channel teardown.
+
+The netdev_err() call already used priv->netdev for this reason; make
+the trylock/unlock and health_channel_eq_recover calls consistent.
+
+This fixes the following KASAN splat:
+
+  BUG: KASAN: use-after-free in mlx5e_tx_reporter_timeout_recover+0x1dd/0x360 [mlx5_core]
+  Read of size 8 at addr ffff889860ed0b28 by task kworker/u113:2/5277
+
+  Call Trace:
+   mlx5e_tx_reporter_timeout_recover+0x1dd/0x360 [mlx5_core]
+   devlink_health_reporter_recover+0xa2/0x150
+   devlink_health_report+0x254/0x7c0
+   mlx5e_reporter_tx_timeout+0x297/0x380 [mlx5_core]
+   mlx5e_tx_timeout_work+0x109/0x170 [mlx5_core]
+   process_one_work+0x677/0xf20
+   worker_thread+0x51f/0xd90
+   kthread+0x3a5/0x810
+   ret_from_fork+0x208/0x400
+   ret_from_fork_asm+0x1a/0x30
+
+Fixes: 83ac0304a2d7 ("net/mlx5e: Fix deadlocks between devlink and netdev instance locks")
+Cc: stable@vger.kernel.org
+Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Matt Fleming <mfleming@cloudflare.com>
+Link: https://patch.msgid.link/20260513112226.140512-1-matt@readmodwrite.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+@@ -159,13 +159,13 @@ static int mlx5e_tx_reporter_timeout_rec
+        * channels are being closed for other reason and this work is not
+        * relevant anymore.
+        */
+-      while (!netdev_trylock(sq->netdev)) {
++      while (!netdev_trylock(priv->netdev)) {
+               if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state))
+                       return 0;
+               msleep(20);
+       }
+-      err = mlx5e_health_channel_eq_recover(sq->netdev, eq, sq->cq.ch_stats);
++      err = mlx5e_health_channel_eq_recover(priv->netdev, eq, sq->cq.ch_stats);
+       if (!err) {
+               to_ctx->status = 0; /* this sq recovered */
+               goto out;
+@@ -185,7 +185,7 @@ static int mlx5e_tx_reporter_timeout_rec
+                  "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
+                  err);
+ out:
+-      netdev_unlock(sq->netdev);
++      netdev_unlock(priv->netdev);
+       return err;
+ }
diff --git a/queue-6.18/net-phy-skip-eee-advertisement-write-when-autoneg-is-disabled.patch b/queue-6.18/net-phy-skip-eee-advertisement-write-when-autoneg-is-disabled.patch
new file mode 100644 (file)
index 0000000..12e2c78
--- /dev/null
@@ -0,0 +1,67 @@
+From 960e77ce14a83ef7f226e8e4b4d75765633ba48b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nerijus=20Bend=C5=BEi=C5=ABnas?=
+ <nerijus.bendziunas@gmail.com>
+Date: Sat, 16 May 2026 18:02:51 +0300
+Subject: net: phy: skip EEE advertisement write when autoneg is disabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nerijus Bendžiūnas <nerijus.bendziunas@gmail.com>
+
+commit 960e77ce14a83ef7f226e8e4b4d75765633ba48b upstream.
+
+genphy_c45_an_config_eee_aneg() writes the EEE advertisement to the
+auto-negotiation device's MMD register space (MDIO_MMD_AN, register
+MDIO_AN_EEE_ADV).  These registers are read by the link partner only
+during auto-negotiation, so writing them while autoneg is disabled
+cannot influence the link.  On some PHYs (e.g. Broadcom BCM54213PE)
+the write nevertheless reaches the chip and disturbs the receive
+datapath.
+
+Concretely, running
+
+    ethtool -s eth0 speed 100 duplex full autoneg off
+    ethtool --set-eee eth0 eee off
+
+leaves eth0 with TX working and RX completely silent on a
+Raspberry Pi 4 / CM4 board (bcmgenet + BCM54213PE in rgmii-rxid).
+Switching back to autoneg recovers the link.
+
+Prior to commit f26a29a038ee ("net: phy: ensure that genphy_c45_an_config_eee_aneg() sees new value of phydev->eee_cfg.eee_enabled"),
+the disable path was effectively a no-op because the helper read
+the stale eee_cfg.eee_enabled, so the underlying PHY behavior never
+surfaced.
+
+Bisected on rpi-6.12.y between commits 83943264 (good) and
+effcbc88 (bad) to f26a29a038ee.
+
+Fixes: f26a29a038ee ("net: phy: ensure that genphy_c45_an_config_eee_aneg() sees new value of phydev->eee_cfg.eee_enabled")
+Cc: stable@vger.kernel.org
+Signed-off-by: Nerijus Bendžiūnas <nerijus.bendziunas@gmail.com>
+Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
+Tested-by: Nicolai Buchwitz <nb@tipi-net.de>
+Link: https://patch.msgid.link/20260516150251.879680-1-nerijus.bendziunas@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/phy-c45.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/phy/phy-c45.c
++++ b/drivers/net/phy/phy-c45.c
+@@ -939,6 +939,14 @@ EXPORT_SYMBOL_GPL(genphy_c45_read_eee_ab
+  */
+ int genphy_c45_an_config_eee_aneg(struct phy_device *phydev)
+ {
++      /* Writing MMD AN advertisements while autoneg is disabled has no
++       * effect on link-partner negotiation, but on some PHYs (e.g. the
++       * Broadcom BCM54213PE) the write itself disturbs the receive
++       * datapath. Skip it.
++       */
++      if (phydev->autoneg == AUTONEG_DISABLE)
++              return 0;
++
+       if (!phydev->eee_cfg.eee_enabled) {
+               __ETHTOOL_DECLARE_LINK_MODE_MASK(adv) = {};
diff --git a/queue-6.18/net-pse-pd-fix-sign-on-enoent-check-in-of_load_pse_pis.patch b/queue-6.18/net-pse-pd-fix-sign-on-enoent-check-in-of_load_pse_pis.patch
new file mode 100644 (file)
index 0000000..be77f3a
--- /dev/null
@@ -0,0 +1,41 @@
+From 33d35975cbead3fa6b738ee57e5e45e14fbe0886 Mon Sep 17 00:00:00 2001
+From: Jonas Jelonek <jelonek.jonas@gmail.com>
+Date: Fri, 15 May 2026 14:31:03 +0000
+Subject: net: pse-pd: fix sign on -ENOENT check in of_load_pse_pis()
+
+From: Jonas Jelonek <jelonek.jonas@gmail.com>
+
+commit 33d35975cbead3fa6b738ee57e5e45e14fbe0886 upstream.
+
+of_count_phandle_with_args() returns the count on success and a negative
+errno on failure, including -ENOENT when the "pairsets" property is
+absent. The existing comparison in of_load_pse_pis() checks against
+ENOENT (positive 2) instead of -ENOENT, so the branch is taken for any
+error return: legitimate DTs that omit "pairsets" trigger a spurious
+"wrong number of pairsets" error and probe fails with -EINVAL.
+
+Compare against -ENOENT so a missing "pairsets" property is correctly
+treated as "this PI has no pairsets, continue".
+
+Fixes: 9be9567a7c59 ("net: pse-pd: Add support for PSE PIs")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260515143103.1721888-1-jelonek.jonas@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/pse-pd/pse_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/pse-pd/pse_core.c
++++ b/drivers/net/pse-pd/pse_core.c
+@@ -210,7 +210,7 @@ static int of_load_pse_pis(struct pse_co
+                       ret = of_load_pse_pi_pairsets(node, &pi, ret);
+                       if (ret)
+                               goto out;
+-              } else if (ret != ENOENT) {
++              } else if (ret != -ENOENT) {
+                       dev_err(pcdev->dev,
+                               "error: wrong number of pairsets. Should be 1 or 2, got %d (%pOF)\n",
+                               ret, node);
diff --git a/queue-6.18/net-wwan-iosm-fix-potential-memory-leaks-in-ipc_imem_init.patch b/queue-6.18/net-wwan-iosm-fix-potential-memory-leaks-in-ipc_imem_init.patch
new file mode 100644 (file)
index 0000000..9c6df31
--- /dev/null
@@ -0,0 +1,34 @@
+From c5d93b2c40355e999715262a824965aac025a427 Mon Sep 17 00:00:00 2001
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Date: Tue, 19 May 2026 11:57:39 +0530
+Subject: net: wwan: iosm: fix potential memory leaks in ipc_imem_init()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+commit c5d93b2c40355e999715262a824965aac025a427 upstream.
+
+The memory allocated in ipc_protocol_init() is not freed on the error
+paths that follow in ipc_imem_init(). Fix that by calling the
+corresponding release function ipc_protocol_deinit() in the error path.
+
+Fixes: 3670970dd8c6 ("net: iosm: shared memory IPC interface")
+Cc: stable@vger.kernel.org
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260519062815.55545-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wwan/iosm/iosm_ipc_imem.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/wwan/iosm/iosm_ipc_imem.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_imem.c
+@@ -1426,6 +1426,8 @@ imem_config_fail:
+ protocol_init_fail:
+       cancel_work_sync(&ipc_imem->run_state_worker);
+       ipc_task_deinit(ipc_imem->ipc_task);
++      if (ipc_imem->ipc_protocol)
++              ipc_protocol_deinit(ipc_imem->ipc_protocol);
+ ipc_task_init_fail:
+       kfree(ipc_imem->ipc_task);
+ ipc_task_fail:
diff --git a/queue-6.18/netfilter-ip6t_hbh-reject-oversized-option-lists.patch b/queue-6.18/netfilter-ip6t_hbh-reject-oversized-option-lists.patch
new file mode 100644 (file)
index 0000000..89f34c5
--- /dev/null
@@ -0,0 +1,51 @@
+From 4322dcde6b4173c2d8e8e6118ed290794263bcc8 Mon Sep 17 00:00:00 2001
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+Date: Wed, 13 May 2026 15:57:17 +0800
+Subject: netfilter: ip6t_hbh: reject oversized option lists
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+commit 4322dcde6b4173c2d8e8e6118ed290794263bcc8 upstream.
+
+struct ip6t_opts stores at most IP6T_OPTS_OPTSNR option descriptors,
+but hbh_mt6_check() does not reject larger optsnr values supplied from
+userspace.
+
+Validate optsnr in the rule setup path so only match data that fits the
+fixed-size opts array can be installed. This follows the existing xtables
+pattern of rejecting invalid user-provided counts in checkentry() and
+keeps the packet matching path unchanged.
+
+`struct ip6t_opts` has a fixed `opts[IP6T_OPTS_OPTSNR]` array,
+where `IP6T_OPTS_OPTSNR` is 16, then off-by-one array access is possible:
+
+[  137.924693][ T8692] UBSAN: array-index-out-of-bounds in ../net/ipv6/netfilter/ip6t_hbh.c:110:29
+[  137.926167][ T8692] index 16 is out of range for type '__u16 [16]'
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/netfilter/ip6t_hbh.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/ipv6/netfilter/ip6t_hbh.c
++++ b/net/ipv6/netfilter/ip6t_hbh.c
+@@ -168,6 +168,10 @@ static int hbh_mt6_check(const struct xt
+               pr_debug("unknown flags %X\n", optsinfo->invflags);
+               return -EINVAL;
+       }
++      if (optsinfo->optsnr > IP6T_OPTS_OPTSNR) {
++              pr_debug("too many supported opts specified\n");
++              return -EINVAL;
++      }
+       if (optsinfo->flags & IP6T_OPTS_NSTRICT) {
+               pr_debug("Not strict - not implemented");
diff --git a/queue-6.18/netfilter-ipset-stop-hash-range-iteration-at-end.patch b/queue-6.18/netfilter-ipset-stop-hash-range-iteration-at-end.patch
new file mode 100644 (file)
index 0000000..1e328a5
--- /dev/null
@@ -0,0 +1,130 @@
+From 0d3a282ab5f165fc207ff49ea5b6ad8f54616bd6 Mon Sep 17 00:00:00 2001
+From: Nan Li <tonanli66@gmail.com>
+Date: Tue, 12 May 2026 16:50:01 +0800
+Subject: netfilter: ipset: stop hash:* range iteration at end
+
+From: Nan Li <tonanli66@gmail.com>
+
+commit 0d3a282ab5f165fc207ff49ea5b6ad8f54616bd6 upstream.
+
+The following hash set variants:
+
+hash:ip,mark
+hash:ip,port
+hash:ip,port,ip
+hash:ip,port,net
+
+iterate IPv4 ranges with a 32-bit iterator.
+
+The iterator must stop once the last address in the requested range has
+been processed. Advancing it once more can move the traversal state past
+the end of the request, so a later retry may continue from an unintended
+position.
+
+Handle the iterator increment explicitly at the end of the loop and stop
+once the upper bound has been processed. This keeps the existing retry
+behaviour intact for valid ranges while preventing traversal from
+continuing past the original boundary.
+
+Fixes: 48596a8ddc46 ("netfilter: ipset: Fix adding an IPv4 range containing more than 2^31 addresses")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Nan Li <tonanli66@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/ipset/ip_set_hash_ipmark.c    |    6 +++++-
+ net/netfilter/ipset/ip_set_hash_ipport.c    |    5 ++++-
+ net/netfilter/ipset/ip_set_hash_ipportip.c  |    5 ++++-
+ net/netfilter/ipset/ip_set_hash_ipportnet.c |    5 ++++-
+ 4 files changed, 17 insertions(+), 4 deletions(-)
+
+--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
+@@ -150,7 +150,7 @@ hash_ipmark4_uadt(struct ip_set *set, st
+       if (retried)
+               ip = ntohl(h->next.ip);
+-      for (; ip <= ip_to; ip++, i++) {
++      for (; ip <= ip_to; i++) {
+               e.ip = htonl(ip);
+               if (i > IPSET_MAX_RANGE) {
+                       hash_ipmark4_data_next(&h->next, &e);
+@@ -162,6 +162,10 @@ hash_ipmark4_uadt(struct ip_set *set, st
+                       return ret;
+               ret = 0;
++
++              if (ip == ip_to)
++                      break;
++              ip++;
+       }
+       return ret;
+ }
+--- a/net/netfilter/ipset/ip_set_hash_ipport.c
++++ b/net/netfilter/ipset/ip_set_hash_ipport.c
+@@ -186,7 +186,7 @@ hash_ipport4_uadt(struct ip_set *set, st
+       if (retried)
+               ip = ntohl(h->next.ip);
+-      for (; ip <= ip_to; ip++) {
++      for (; ip <= ip_to;) {
+               p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
+                                                      : port;
+               for (; p <= port_to; p++, i++) {
+@@ -203,6 +203,9 @@ hash_ipport4_uadt(struct ip_set *set, st
+                       ret = 0;
+               }
++              if (ip == ip_to)
++                      break;
++              ip++;
+       }
+       return ret;
+ }
+--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
+@@ -182,7 +182,7 @@ hash_ipportip4_uadt(struct ip_set *set,
+       if (retried)
+               ip = ntohl(h->next.ip);
+-      for (; ip <= ip_to; ip++) {
++      for (; ip <= ip_to;) {
+               p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
+                                                      : port;
+               for (; p <= port_to; p++, i++) {
+@@ -199,6 +199,9 @@ hash_ipportip4_uadt(struct ip_set *set,
+                       ret = 0;
+               }
++              if (ip == ip_to)
++                      break;
++              ip++;
+       }
+       return ret;
+ }
+--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+@@ -274,7 +274,7 @@ hash_ipportnet4_uadt(struct ip_set *set,
+               p = port;
+               ip2 = ip2_from;
+       }
+-      for (; ip <= ip_to; ip++) {
++      for (; ip <= ip_to;) {
+               e.ip = htonl(ip);
+               for (; p <= port_to; p++) {
+                       e.port = htons(p);
+@@ -298,6 +298,9 @@ hash_ipportnet4_uadt(struct ip_set *set,
+                       ip2 = ip2_from;
+               }
+               p = port;
++              if (ip == ip_to)
++                      break;
++              ip++;
+       }
+       return ret;
+ }
diff --git a/queue-6.18/netfilter-nf_queue-hold-bridge-skb-dev-while-queued.patch b/queue-6.18/netfilter-nf_queue-hold-bridge-skb-dev-while-queued.patch
new file mode 100644 (file)
index 0000000..9d854c8
--- /dev/null
@@ -0,0 +1,90 @@
+From e196115ec330a18de415bdb9f5071aa9f08e53ce Mon Sep 17 00:00:00 2001
+From: Haoze Xie <royenheart@gmail.com>
+Date: Fri, 15 May 2026 11:19:02 +0800
+Subject: netfilter: nf_queue: hold bridge skb->dev while queued
+
+From: Haoze Xie <royenheart@gmail.com>
+
+commit e196115ec330a18de415bdb9f5071aa9f08e53ce upstream.
+
+br_pass_frame_up() rewrites skb->dev from the ingress port to the bridge
+master before queueing bridge LOCAL_IN packets. NFQUEUE only holds
+references on state.in/out and bridge physdevs, so a queued bridge
+packet can retain a freed bridge master in skb->dev until reinjection.
+
+When the verdict is reinjected later, br_netif_receive_skb() re-enters
+the receive path with skb->dev still pointing at the freed bridge master,
+triggering a use-after-free.
+
+Store skb->dev in the queue entry, hold a reference on it for the queue
+lifetime, and use the saved device when dropping queued packets during
+NETDEV_DOWN handling.
+
+Fixes: ac2863445686 ("netfilter: bridge: add nf_afinfo to enable queuing to userspace")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Haoze Xie <royenheart@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/netfilter/nf_queue.h |    1 +
+ net/netfilter/nf_queue.c         |    4 +++-
+ net/netfilter/nfnetlink_queue.c  |    2 ++
+ 3 files changed, 6 insertions(+), 1 deletion(-)
+
+--- a/include/net/netfilter/nf_queue.h
++++ b/include/net/netfilter/nf_queue.h
+@@ -14,6 +14,7 @@ struct nf_queue_entry {
+       struct list_head        list;
+       struct rhash_head       hash_node;
+       struct sk_buff          *skb;
++      struct net_device       *skb_dev;
+       unsigned int            id;
+       unsigned int            hook_index;     /* index in hook_entries->hook[] */
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+--- a/net/netfilter/nf_queue.c
++++ b/net/netfilter/nf_queue.c
+@@ -60,6 +60,7 @@ static void nf_queue_entry_release_refs(
+       struct nf_hook_state *state = &entry->state;
+       /* Release those devices we held, or Alexey will kill me. */
++      dev_put(entry->skb_dev);
+       dev_put(state->in);
+       dev_put(state->out);
+       if (state->sk)
+@@ -101,6 +102,7 @@ bool nf_queue_entry_get_refs(struct nf_q
+       if (state->sk && !refcount_inc_not_zero(&state->sk->sk_refcnt))
+               return false;
++      dev_hold(entry->skb_dev);
+       dev_hold(state->in);
+       dev_hold(state->out);
+@@ -201,11 +203,11 @@ static int __nf_queue(struct sk_buff *sk
+       *entry = (struct nf_queue_entry) {
+               .skb    = skb,
++              .skb_dev = skb->dev,
+               .state  = *state,
+               .hook_index = index,
+               .size   = sizeof(*entry) + route_key_size,
+       };
+-
+       __nf_queue_entry_init_physdevs(entry);
+       if (!nf_queue_entry_get_refs(entry)) {
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -1198,6 +1198,8 @@ dev_cmp(struct nf_queue_entry *entry, un
+       if (physinif == ifindex || physoutif == ifindex)
+               return 1;
+ #endif
++      if (entry->skb_dev && entry->skb_dev->ifindex == ifindex)
++              return 1;
+       if (entry->state.in)
+               if (entry->state.in->ifindex == ifindex)
+                       return 1;
diff --git a/queue-6.18/netfilter-nft_inner-fix-ipv6-inner_thoff-desync.patch b/queue-6.18/netfilter-nft_inner-fix-ipv6-inner_thoff-desync.patch
new file mode 100644 (file)
index 0000000..1003f4b
--- /dev/null
@@ -0,0 +1,53 @@
+From b6a91f68ebfed9c38e0e9150f58a9b85da07181c Mon Sep 17 00:00:00 2001
+From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+Date: Tue, 12 May 2026 01:30:41 +0800
+Subject: netfilter: nft_inner: Fix IPv6 inner_thoff desync
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+
+commit b6a91f68ebfed9c38e0e9150f58a9b85da07181c upstream.
+
+In nft_inner_parse_l2l3(), when processing inner IPv6 packets,
+ipv6_find_hdr() correctly computes the transport header offset
+traversing all extension headers, but the result is immediately
+overwritten with nhoff + sizeof(_ip6h) (40 bytes), which only
+accounts for the IPv6 base header. This creates a desync between
+inner_thoff (wrong — points to extension header start) and l4proto
+(correct — e.g., IPPROTO_TCP), enabling transport header forgery
+and potential firewall bypass. This issue affects stable versions
+from Linux 6.2.
+
+For comparison, the normal (non-inner) IPv6 path correctly
+preserves ipv6_find_hdr()'s result. Removing the incorrect overwrite
+ensures that ipv6_find_hdr()'s calculated transport header offset is
+preserved, thereby fixing the desynchronization.
+
+Fixes: 3a07327d10a0 ("netfilter: nft_inner: support for inner tunnel header matching")
+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: Xuewei Feng <fengxw06@126.com>
+Reported-by: Qi Li <qli01@tsinghua.edu.cn>
+Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
+Assisted-by: GLM:5.1 Z.ai
+Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nft_inner.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/net/netfilter/nft_inner.c
++++ b/net/netfilter/nft_inner.c
+@@ -163,7 +163,6 @@ static int nft_inner_parse_l2l3(const st
+                       return -1;
+               if (fragoff == 0) {
+-                      thoff = nhoff + sizeof(_ip6h);
+                       ctx->flags |= NFT_PAYLOAD_CTX_INNER_TH;
+                       ctx->inner_thoff = thoff;
+                       ctx->l4proto = l4proto;
diff --git a/queue-6.18/phonet-pep-disable-bh-around-forwarded-sk_receive_skb.patch b/queue-6.18/phonet-pep-disable-bh-around-forwarded-sk_receive_skb.patch
new file mode 100644 (file)
index 0000000..ebcd607
--- /dev/null
@@ -0,0 +1,105 @@
+From dbc81608e3a653dea6cf403f20cae35468b8ab9c Mon Sep 17 00:00:00 2001
+From: Zijing Yin <yzjaurora@gmail.com>
+Date: Tue, 19 May 2026 10:26:33 -0700
+Subject: phonet/pep: disable BH around forwarded sk_receive_skb()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zijing Yin <yzjaurora@gmail.com>
+
+commit dbc81608e3a653dea6cf403f20cae35468b8ab9c upstream.
+
+The networking receive path is usually run from softirq context, but
+protocols that take the socket lock may have packets stored in the
+backlog and processed later from process context. In that case
+release_sock() -> __release_sock() drops the slock with spin_unlock_bh()
+and then calls sk->sk_backlog_rcv() with bottom halves enabled.
+
+Typical sk_backlog_rcv handlers process the socket whose backlog is
+being drained, so the BH state at entry is irrelevant for the slocks
+they touch. pep_do_rcv() is different: when the inbound skb targets an
+existing PEP pipe, it forwards the skb to a different *child* socket
+via sk_receive_skb(). That helper takes the child slock with
+bh_lock_sock_nested(), which is just spin_lock_nested() and assumes BH
+is already off. The same child slock therefore ends up acquired with
+BH on (process path) and with BH off (softirq path):
+
+  process context                   softirq context
+  ---------------                   ---------------
+  release_sock(listener)            __netif_receive_skb()
+   __release_sock()                  phonet_rcv()
+    spin_unlock_bh()                  __sk_receive_skb(listener)
+    [BH now ENABLED]                  [BH already disabled]
+    sk_backlog_rcv:                   sk_backlog_rcv:
+     pep_do_rcv()                      pep_do_rcv()
+      sk_receive_skb(child)             sk_receive_skb(child)
+       bh_lock_sock_nested(child)        bh_lock_sock_nested(child)
+       => SOFTIRQ-ON-W                   => IN-SOFTIRQ-W
+
+Lockdep flags this as inconsistent lock state, and it can become a real
+self-deadlock if a softirq on the same CPU tries to receive to the same
+child socket while its slock is held in the BH-enabled path:
+
+  WARNING: inconsistent lock state
+  inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
+   (slock-AF_PHONET/1){+.?.}-{3:3}, at: __sk_receive_skb+0x1cf/0x900
+    __sk_receive_skb              net/core/sock.c:563
+    sk_receive_skb                include/net/sock.h:2022 [inline]
+    pep_do_rcv                    net/phonet/pep.c:675
+    sk_backlog_rcv                include/net/sock.h:1190
+    __release_sock                net/core/sock.c:3216
+    release_sock                  net/core/sock.c:3815
+    pep_sock_accept               net/phonet/pep.c:879
+
+Wrap the forwarded sk_receive_skb() in local_bh_disable() /
+local_bh_enable() so the child slock is always acquired with BH off.
+local_bh_disable() nests safely on the softirq path.
+
+Discovered via in-house syzkaller fuzzing; the same root cause also
+on the linux-6.1.y syzbot dashboard as extid 44f0626dd6284f02663c.
+Reproduced under KASAN + LOCKDEP + PROVE_LOCKING, reproducer:
+https://pastebin.com/A3t8xzCR
+
+Fixes: 9641458d3ec4 ("Phonet: Pipe End Point for Phonet Pipes protocol")
+Link: https://syzkaller.appspot.com/bug?extid=44f0626dd6284f02663c
+Cc: stable@vger.kernel.org
+Signed-off-by: Zijing Yin <yzjaurora@gmail.com>
+Acked-by: Rémi Denis-Courmont <remi@remlab.net>
+Reported-by: syzbot+9f4a135646b66c509935@syzkaller.appspotmail.com
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20260519172635.86304-1-yzjaurora@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/phonet/pep.c |   19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/net/phonet/pep.c
++++ b/net/phonet/pep.c
+@@ -671,8 +671,23 @@ static int pep_do_rcv(struct sock *sk, s
+       /* Look for an existing pipe handle */
+       sknode = pep_find_pipe(&pn->hlist, &dst, pipe_handle);
+-      if (sknode)
+-              return sk_receive_skb(sknode, skb, 1);
++      if (sknode) {
++              int rc;
++
++              /* pep_do_rcv() runs from two contexts: from softirq via
++               * phonet_rcv() -> __sk_receive_skb() with BH disabled,
++               * and from process context via
++               * release_sock() -> __release_sock(), which drops
++               * the listener slock with spin_unlock_bh() before draining
++               * the backlog.  The child pipe slock is taken below via
++               * bh_lock_sock_nested(), which does not itself disable BH, so
++               * disable BH here to keep both acquire contexts consistent.
++               */
++              local_bh_disable();
++              rc = sk_receive_skb(sknode, skb, 1);
++              local_bh_enable();
++              return rc;
++      }
+       switch (hdr->message_id) {
+       case PNS_PEP_CONNECT_REQ:
diff --git a/queue-6.18/regulator-tps65219-fix-irq_data.rdev-not-being-assigned.patch b/queue-6.18/regulator-tps65219-fix-irq_data.rdev-not-being-assigned.patch
new file mode 100644 (file)
index 0000000..599639c
--- /dev/null
@@ -0,0 +1,231 @@
+From f9b2d3b703d13df50c630997dfdc25648e96db0d Mon Sep 17 00:00:00 2001
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Date: Mon, 18 May 2026 10:31:11 +0200
+Subject: regulator: tps65219: fix irq_data.rdev not being assigned
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+commit f9b2d3b703d13df50c630997dfdc25648e96db0d upstream.
+
+Commit 64a6b577490c ("regulator: tps65219: Remove debugging helper
+function") removed the tps65219_get_rdev_by_name() helper along with
+the irq_data.rdev assignment that depended on it. This left
+irq_data.rdev uninitialized for all IRQs, causing undefined behavior
+when regulator_notifier_call_chain() is called from the IRQ handler:
+
+  Internal error: Oops: 0000000096000004
+  pc : regulator_notifier_call_chain
+  lr : tps65219_regulator_irq_handler
+  Call trace:
+   regulator_notifier_call_chain
+   tps65219_regulator_irq_handler
+   handle_nested_irq
+   regmap_irq_thread
+   irq_thread_fn
+   irq_thread
+   kthread
+   ret_from_fork
+
+Instead of restoring a dedicated lookup array, restructure the probe
+function to combine regulator registration with IRQ registration in
+the same loop. This way the rdev returned by devm_regulator_register()
+is naturally available for assigning to irq_data.rdev without any
+auxiliary data structure.
+
+Non-regulator IRQs (SENSOR, TIMEOUT) that don't correspond to any
+registered regulator are registered with rdev=NULL, and the IRQ handler
+is protected with a NULL check to avoid crashing.
+
+Cc: stable@vger.kernel.org
+Closes: https://lore.kernel.org/all/aBDSTxALaOc-PD7X@gaggiata.pivistrello.it/
+Reported-by: Francesco Dolcini <francesco@dolcini.it>
+Fixes: 64a6b577490c ("regulator: tps65219: Remove debugging helper function")
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Link: https://patch.msgid.link/20260518083113.2063368-1-alexander.sverdlin@siemens.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/regulator/tps65219-regulator.c |  135 +++++++++++++++++++++++----------
+ 1 file changed, 95 insertions(+), 40 deletions(-)
+
+--- a/drivers/regulator/tps65219-regulator.c
++++ b/drivers/regulator/tps65219-regulator.c
+@@ -346,8 +346,9 @@ static irqreturn_t tps65219_regulator_ir
+               return IRQ_HANDLED;
+       }
+-      regulator_notifier_call_chain(irq_data->rdev,
+-                                    irq_data->type->event, NULL);
++      if (irq_data->rdev)
++              regulator_notifier_call_chain(irq_data->rdev,
++                                            irq_data->type->event, NULL);
+       dev_err(irq_data->dev, "Error IRQ trap %s for %s\n",
+               irq_data->type->event_name, irq_data->type->regulator_name);
+@@ -398,14 +399,65 @@ static struct tps65219_chip_data chip_in
+       },
+ };
+-static int tps65219_regulator_probe(struct platform_device *pdev)
++static bool tps65219_is_regulator_name(const struct tps65219_chip_data *pmic,
++                                     const char *name)
++{
++      int i;
++
++      for (i = 0; i < pmic->common_rdesc_size; i++)
++              if (!strcmp(pmic->common_rdesc[i].name, name))
++                      return true;
++      for (i = 0; i < pmic->rdesc_size; i++)
++              if (!strcmp(pmic->rdesc[i].name, name))
++                      return true;
++      return false;
++}
++
++static int tps65219_register_irqs(struct platform_device *pdev,
++                                struct tps65219 *tps,
++                                struct regulator_dev *rdev,
++                                struct tps65219_regulator_irq_type *irq_types,
++                                int nirqs,
++                                const char *regulator_name)
+ {
+       struct tps65219_regulator_irq_data *irq_data;
++      int i, irq, error;
++
++      for (i = 0; i < nirqs; i++) {
++              if (strcmp(irq_types[i].regulator_name, regulator_name))
++                      continue;
++
++              irq = platform_get_irq_byname(pdev, irq_types[i].irq_name);
++              if (irq < 0)
++                      return -EINVAL;
++
++              irq_data = devm_kmalloc(tps->dev, sizeof(*irq_data), GFP_KERNEL);
++              if (!irq_data)
++                      return -ENOMEM;
++
++              irq_data->dev = tps->dev;
++              irq_data->type = &irq_types[i];
++              irq_data->rdev = rdev;
++
++              error = devm_request_threaded_irq(tps->dev, irq, NULL,
++                                                tps65219_regulator_irq_handler,
++                                                IRQF_ONESHOT,
++                                                irq_types[i].irq_name,
++                                                irq_data);
++              if (error)
++                      return dev_err_probe(tps->dev, error,
++                                           "Failed to request %s IRQ %d\n",
++                                           irq_types[i].irq_name, irq);
++      }
++      return 0;
++}
++
++static int tps65219_regulator_probe(struct platform_device *pdev)
++{
+       struct tps65219_regulator_irq_type *irq_type;
+       struct tps65219_chip_data *pmic;
+       struct regulator_dev *rdev;
+       int error;
+-      int irq;
+       int i;
+       struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
+@@ -425,6 +477,19 @@ static int tps65219_regulator_probe(stru
+                       return dev_err_probe(tps->dev, PTR_ERR(rdev),
+                                             "Failed to register %s regulator\n",
+                                             pmic->common_rdesc[i].name);
++
++              error = tps65219_register_irqs(pdev, tps, rdev,
++                                             pmic->common_irq_types,
++                                             pmic->common_irq_size,
++                                             pmic->common_rdesc[i].name);
++              if (error)
++                      return error;
++              error = tps65219_register_irqs(pdev, tps, rdev,
++                                             pmic->irq_types,
++                                             pmic->dev_irq_size,
++                                             pmic->common_rdesc[i].name);
++              if (error)
++                      return error;
+       }
+       for (i = 0; i <  pmic->rdesc_size; i++) {
+@@ -434,52 +499,42 @@ static int tps65219_regulator_probe(stru
+                       return dev_err_probe(tps->dev, PTR_ERR(rdev),
+                                            "Failed to register %s regulator\n",
+                                            pmic->rdesc[i].name);
++
++              error = tps65219_register_irqs(pdev, tps, rdev,
++                                             pmic->common_irq_types,
++                                             pmic->common_irq_size,
++                                             pmic->rdesc[i].name);
++              if (error)
++                      return error;
++              error = tps65219_register_irqs(pdev, tps, rdev,
++                                             pmic->irq_types,
++                                             pmic->dev_irq_size,
++                                             pmic->rdesc[i].name);
++              if (error)
++                      return error;
+       }
++      /* Register non-regulator IRQs (TIMEOUT, SENSOR) with rdev=NULL */
+       for (i = 0; i < pmic->common_irq_size; ++i) {
+               irq_type = &pmic->common_irq_types[i];
+-              irq = platform_get_irq_byname(pdev, irq_type->irq_name);
+-              if (irq < 0)
+-                      return -EINVAL;
+-
+-              irq_data = devm_kmalloc(tps->dev, sizeof(*irq_data), GFP_KERNEL);
+-              if (!irq_data)
+-                      return -ENOMEM;
+-
+-              irq_data->dev = tps->dev;
+-              irq_data->type = irq_type;
+-              error = devm_request_threaded_irq(tps->dev, irq, NULL,
+-                                                tps65219_regulator_irq_handler,
+-                                                IRQF_ONESHOT,
+-                                                irq_type->irq_name,
+-                                                irq_data);
++              if (tps65219_is_regulator_name(pmic, irq_type->regulator_name))
++                      continue;
++              error = tps65219_register_irqs(pdev, tps, NULL,
++                                             irq_type, 1,
++                                             irq_type->regulator_name);
+               if (error)
+-                      return dev_err_probe(tps->dev, error,
+-                                           "Failed to request %s IRQ %d\n",
+-                                           irq_type->irq_name, irq);
++                      return error;
+       }
+       for (i = 0; i < pmic->dev_irq_size; ++i) {
+               irq_type = &pmic->irq_types[i];
+-              irq = platform_get_irq_byname(pdev, irq_type->irq_name);
+-              if (irq < 0)
+-                      return -EINVAL;
+-
+-              irq_data = devm_kmalloc(tps->dev, sizeof(*irq_data), GFP_KERNEL);
+-              if (!irq_data)
+-                      return -ENOMEM;
+-
+-              irq_data->dev = tps->dev;
+-              irq_data->type = irq_type;
+-              error = devm_request_threaded_irq(tps->dev, irq, NULL,
+-                                                tps65219_regulator_irq_handler,
+-                                                IRQF_ONESHOT,
+-                                                irq_type->irq_name,
+-                                                irq_data);
++              if (tps65219_is_regulator_name(pmic, irq_type->regulator_name))
++                      continue;
++              error = tps65219_register_irqs(pdev, tps, NULL,
++                                             irq_type, 1,
++                                             irq_type->regulator_name);
+               if (error)
+-                      return dev_err_probe(tps->dev, error,
+-                                           "Failed to request %s IRQ %d\n",
+-                                           irq_type->irq_name, irq);
++                      return error;
+       }
+       return 0;
diff --git a/queue-6.18/selftests-mm-run_vmtests.sh-fix-destructive-tests-invocation.patch b/queue-6.18/selftests-mm-run_vmtests.sh-fix-destructive-tests-invocation.patch
new file mode 100644 (file)
index 0000000..aa15291
--- /dev/null
@@ -0,0 +1,43 @@
+From 3432cbb291aabf85f8af4b9d1ec37179168ff999 Mon Sep 17 00:00:00 2001
+From: Luiz Capitulino <luizcap@redhat.com>
+Date: Mon, 27 Apr 2026 12:03:51 -0400
+Subject: selftests/mm: run_vmtests.sh: fix destructive tests invocation
+
+From: Luiz Capitulino <luizcap@redhat.com>
+
+commit 3432cbb291aabf85f8af4b9d1ec37179168ff999 upstream.
+
+Destructive tests should be invoked with -d command-line option, but this
+won't work today since 'd' is missing in getopts command-line.  This
+commit fixes it.
+
+Link: https://lore.kernel.org/214fd9e4-5398-4c26-859e-c982c2e277c3@redhat.com
+Fixes: f16ff3b692ad ("selftests/mm: run_vmtests.sh: add missing tests")
+Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
+Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Reviewed-by: SeongJae Park <sj@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Liam R. Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes <ljs@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/mm/run_vmtests.sh |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/tools/testing/selftests/mm/run_vmtests.sh
++++ b/tools/testing/selftests/mm/run_vmtests.sh
+@@ -97,7 +97,7 @@ RUN_ALL=false
+ RUN_DESTRUCTIVE=false
+ TAP_PREFIX="# "
+-while getopts "aht:n" OPT; do
++while getopts "aht:nd" OPT; do
+       case ${OPT} in
+               "a") RUN_ALL=true ;;
+               "h") usage ;;
index 0aa542dba6fa6c012f8b46b35581b353ae0e0461..a1433e75d227e75821798157bc69465bf462fc36 100644 (file)
@@ -23,3 +23,46 @@ drm-vblank-add-crtc-helpers-for-simple-use-cases.patch
 drm-vkms-convert-to-drm-s-vblank-timer.patch
 drm-atomic-increase-timeout-in-drm_atomic_helper_wai.patch
 drm-vblank-fix-kernel-docs-for-vblank-timer.patch
+sysfs-don-t-remove-existing-directory-on-update-failure.patch
+mm-damon-sysfs-schemes-call-missing-mem_cgroup_iter_break.patch
+ksmbd-fix-null-pointer-dereference-in-compare_guid_key.patch
+ksmbd-fix-sid-memory-leak-in-set_posix_acl_entries_dacl-on-overflow.patch
+ksmbd-validate-sid-in-parent-security-descriptor-during-acl-inheritance.patch
+regulator-tps65219-fix-irq_data.rdev-not-being-assigned.patch
+smb-client-require-net-admin-for-cifs-swn-netlink.patch
+smb-client-protect-tc_count-increment-in-smb2_find_smb_sess_tcon_unlocked.patch
+smb-client-use-data_len-for-smb2-read-encrypted-folioq-copy.patch
+smb-server-promote-s_del_on_cls-to-s_del_pending-when-close.patch
+hwmon-pmbus-adm1266-widen-blackbox-info-buffer-to-i2c_smbus_block_max.patch
+alsa-ua101-reject-too-short-usb-descriptors.patch
+alsa-pcm-don-t-setup-bogus-iov_iter-for-silencing.patch
+alsa-asihpi-fix-potential-oob-array-access-at-reading-cache.patch
+alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch
+efi-allocate-runtime-workqueue-before-acpi-init.patch
+spi-amd-set-correct-bus-number-in-acpi-probe-path.patch
+io_uring-waitid-clear-waitid-info-before-copying-it-to-userspace.patch
+drivers-base-memory-fix-memory-block-reference-leak-in-poison-accounting.patch
+ipv6-ioam-refresh-hdr-pointer-before-ioam6_event.patch
+mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
+mm-fix-__vm_normal_page-to-handle-missing-support-for-pmd_special-pud_special.patch
+mm-memory_hotplug-fix-memory-block-reference-leak-on-remove.patch
+mm-page_alloc-fix-initialization-of-tags-of-the-huge-zero-folio-with-init_on_free.patch
+selftests-mm-run_vmtests.sh-fix-destructive-tests-invocation.patch
+net-wwan-iosm-fix-potential-memory-leaks-in-ipc_imem_init.patch
+bluetooth-fix-uaf-in-l2cap_sock_cleanup_listen-vs-l2cap_conn_del.patch
+bluetooth-iso-drop-iso_end-frames-received-without-prior-iso_start.patch
+bluetooth-bnep-fix-uaf-read-of-dev-name.patch
+bluetooth-hci_uart-fix-uafs-and-race-conditions-in-close-and-init-paths.patch
+bluetooth-l2cap-ecred_reconfigure-send-packed-pdu-not-stack-pointer.patch
+bluetooth-mgmt-validate-add-extended-advertising-data-length.patch
+bluetooth-serialize-accept_q-access.patch
+phonet-pep-disable-bh-around-forwarded-sk_receive_skb.patch
+net-bcmgenet-keep-rbuf-eee-pm-disabled.patch
+net-phy-skip-eee-advertisement-write-when-autoneg-is-disabled.patch
+net-mlx5e-fix-use-after-free-in-mlx5e_tx_reporter_timeout_recover.patch
+net-ifb-report-ethtool-stats-over-num_tx_queues.patch
+net-pse-pd-fix-sign-on-enoent-check-in-of_load_pse_pis.patch
+netfilter-ip6t_hbh-reject-oversized-option-lists.patch
+netfilter-nf_queue-hold-bridge-skb-dev-while-queued.patch
+netfilter-ipset-stop-hash-range-iteration-at-end.patch
+netfilter-nft_inner-fix-ipv6-inner_thoff-desync.patch
diff --git a/queue-6.18/smb-client-protect-tc_count-increment-in-smb2_find_smb_sess_tcon_unlocked.patch b/queue-6.18/smb-client-protect-tc_count-increment-in-smb2_find_smb_sess_tcon_unlocked.patch
new file mode 100644 (file)
index 0000000..00fa6b2
--- /dev/null
@@ -0,0 +1,38 @@
+From 4d8690dace005a38e6dbde9ecce2da3ad85c7c41 Mon Sep 17 00:00:00 2001
+From: Henrique Carvalho <henrique.carvalho@suse.com>
+Date: Thu, 14 May 2026 20:18:25 -0300
+Subject: smb: client: protect tc_count increment in smb2_find_smb_sess_tcon_unlocked()
+
+From: Henrique Carvalho <henrique.carvalho@suse.com>
+
+commit 4d8690dace005a38e6dbde9ecce2da3ad85c7c41 upstream.
+
+Commit 96c4af418586 ("cifs: Fix locking usage for tcon fields")
+refactored cifs code to change cifs_tcp_ses_lock for tc_lock around
+tc_count changes.
+
+There was missing lock around tc_count increment inside
+smb2_find_smb_sess_tcon_unlocked().
+
+Cc: stable@vger.kernel.org
+Fixes: 96c4af418586 ("cifs: Fix locking usage for tcon fields")
+Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2transport.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/smb/client/smb2transport.c
++++ b/fs/smb/client/smb2transport.c
+@@ -176,7 +176,9 @@ smb2_find_smb_sess_tcon_unlocked(struct
+       list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+               if (tcon->tid != tid)
+                       continue;
++              spin_lock(&tcon->tc_lock);
+               ++tcon->tc_count;
++              spin_unlock(&tcon->tc_lock);
+               trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
+                                   netfs_trace_tcon_ref_get_find_sess_tcon);
+               return tcon;
diff --git a/queue-6.18/smb-client-require-net-admin-for-cifs-swn-netlink.patch b/queue-6.18/smb-client-require-net-admin-for-cifs-swn-netlink.patch
new file mode 100644 (file)
index 0000000..109e19f
--- /dev/null
@@ -0,0 +1,58 @@
+From d1ebfce2c1d161186a82e77590bf7da2ea1bce91 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Sun, 17 May 2026 20:11:50 -0400
+Subject: smb: client: require net admin for CIFS SWN netlink
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit d1ebfce2c1d161186a82e77590bf7da2ea1bce91 upstream.
+
+CIFS_GENL_CMD_SWN_NOTIFY is the userspace witness-notify command.  The
+intended sender is the cifs.witness helper, but the generic-netlink
+operation currently has no capability flag, so any local process can send
+RESOURCE_CHANGE or CLIENT_MOVE notifications to the in-kernel witness
+handler.
+
+The same family exposes CIFS_GENL_MCGRP_SWN without multicast-group
+capability flags.  Register messages sent to that group include the witness
+registration id and, for NTLM-authenticated mounts, the username, domain,
+and password attributes copied from the CIFS session.  An unprivileged
+local process should not be able to join that group and receive those
+messages.
+
+Require CAP_NET_ADMIN for incoming SWN_NOTIFY commands with
+GENL_ADMIN_PERM, and require CAP_NET_ADMIN over the network namespace for
+joining the SWN multicast group with GENL_MCAST_CAP_NET_ADMIN.  The
+cifs.witness service runs with the privileges needed for both operations.
+
+Fixes: fed979a7e082 ("cifs: Set witness notification handler for messages from userspace daemon")
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/netlink.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/smb/client/netlink.c
++++ b/fs/smb/client/netlink.c
+@@ -33,13 +33,17 @@ static const struct nla_policy cifs_genl
+ static const struct genl_ops cifs_genl_ops[] = {
+       {
+               .cmd = CIFS_GENL_CMD_SWN_NOTIFY,
++              .flags = GENL_ADMIN_PERM,
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+               .doit = cifs_swn_notify,
+       },
+ };
+ static const struct genl_multicast_group cifs_genl_mcgrps[] = {
+-      [CIFS_GENL_MCGRP_SWN] = { .name = CIFS_GENL_MCGRP_SWN_NAME },
++      [CIFS_GENL_MCGRP_SWN] = {
++              .name = CIFS_GENL_MCGRP_SWN_NAME,
++              .flags = GENL_MCAST_CAP_NET_ADMIN,
++      },
+ };
+ struct genl_family cifs_genl_family = {
diff --git a/queue-6.18/smb-client-use-data_len-for-smb2-read-encrypted-folioq-copy.patch b/queue-6.18/smb-client-use-data_len-for-smb2-read-encrypted-folioq-copy.patch
new file mode 100644 (file)
index 0000000..5855ae6
--- /dev/null
@@ -0,0 +1,79 @@
+From d4d76c9ee1997cc8c977a63f6c43551c253c1066 Mon Sep 17 00:00:00 2001
+From: Jeremy Erazo <mendozayt13@gmail.com>
+Date: Fri, 15 May 2026 19:31:41 +0000
+Subject: smb: client: use data_len for SMB2 READ encrypted folioq copy
+
+From: Jeremy Erazo <mendozayt13@gmail.com>
+
+commit d4d76c9ee1997cc8c977a63f6c43551c253c1066 upstream.
+
+In handle_read_data() the encrypted/folioq branch
+(buf_len <= data_offset, reached via receive_encrypted_read for
+transform PDUs > CIFSMaxBufSize + MAX_HEADER_SIZE) copies the READ
+payload using buffer_len rather than data_len:
+
+       rdata->result = cifs_copy_folioq_to_iter(buffer, buffer_len,
+                                                cur_off,
+                                                &rdata->subreq.io_iter);
+       ...
+       rdata->got_bytes = buffer_len;
+
+buffer_len comes from the SMB3 transform header OriginalMessageSize
+field (OriginalMessageSize - read_rsp_size); it represents the size
+of the decrypted message after the SMB2 header.  data_len comes from
+the SMB2 READ response DataLength field; it represents the actual
+READ payload size and may be smaller than buffer_len when the
+decrypted message contains padding or other trailing bytes after the
+READ payload.  The existing check `data_len > buffer_len - pad_len`
+only enforces an upper bound, so a server that emits
+OriginalMessageSize larger than read_rsp_size + pad_len + data_len
+passes the check and the kernel copies buffer_len bytes per response,
+ignoring the server-asserted DataLength.
+
+Two observable failures with a crafted server (DataLength=4,
+buffer_len=20000):
+
+  - the kernel returns 20000 bytes per sub-request to userspace and
+    sets got_bytes = buffer_len, even though the response claimed
+    only 4 bytes of payload;
+
+  - on a partial netfs sub-request whose iterator is sized to
+    data_len, the over-large copy_folio_to_iter() short-reads,
+    cifs_copy_folioq_to_iter() returns -EIO via the n != len path,
+    and the entire netfs read collapses to -EIO even though the
+    leading sub-requests succeeded.
+
+Use data_len for the copy length and for got_bytes so the kernel
+honours the server-asserted READ payload size.  For well-formed
+servers (where buffer_len == pad_len + data_len) the change is
+behaviour-equivalent.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeremy Erazo <mendozayt13@gmail.com>
+Acked-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2ops.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -4842,7 +4842,7 @@ handle_read_data(struct TCP_Server_Info
+               }
+               /* Copy the data to the output I/O iterator. */
+-              rdata->result = cifs_copy_folioq_to_iter(buffer, buffer_len,
++              rdata->result = cifs_copy_folioq_to_iter(buffer, data_len,
+                                                        cur_off, &rdata->subreq.io_iter);
+               if (rdata->result != 0) {
+                       if (is_offloaded)
+@@ -4851,7 +4851,7 @@ handle_read_data(struct TCP_Server_Info
+                               dequeue_mid(mid, rdata->result);
+                       return 0;
+               }
+-              rdata->got_bytes = buffer_len;
++              rdata->got_bytes = data_len;
+       } else if (buf_len >= data_offset + data_len) {
+               /* read response payload is in buf */
diff --git a/queue-6.18/smb-server-promote-s_del_on_cls-to-s_del_pending-when-close.patch b/queue-6.18/smb-server-promote-s_del_on_cls-to-s_del_pending-when-close.patch
new file mode 100644 (file)
index 0000000..e1de135
--- /dev/null
@@ -0,0 +1,76 @@
+From 4ec9c8e023c79f613fe4d5ad8cc737112efb2e44 Mon Sep 17 00:00:00 2001
+From: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Date: Mon, 18 May 2026 15:23:22 +0000
+Subject: smb/server: promote S_DEL_ON_CLS to S_DEL_PENDING when close
+
+From: ChenXiaoSong <chenxiaosong@kylinos.cn>
+
+commit 4ec9c8e023c79f613fe4d5ad8cc737112efb2e44 upstream.
+
+Reproducer:
+
+  1. server: systemctl start ksmbd
+  2. client: mount -t cifs //${server_ip}/export /mnt
+  3. client: C program: openat(AT_FDCWD, "/mnt", O_RDWR | O_TMPFILE, 0600)
+
+Do not treat `FILE_DELETE_ON_CLOSE_LE` as delete pending while files
+remain open.
+
+This patch fixes xfstests generic/004.
+
+Cc: stable@vger.kernel.org
+Link: https://chenxiaosong.com/en/smb-xfstests-generic-004.html
+Co-developed-by: Huiwen He <hehuiwen@kylinos.cn>
+Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
+Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Tested-by: Steve French <stfrench@microsoft.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/vfs_cache.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/fs/smb/server/vfs_cache.c
++++ b/fs/smb/server/vfs_cache.c
+@@ -118,7 +118,7 @@ int ksmbd_query_inode_status(struct dent
+               return ret;
+       down_read(&ci->m_lock);
+-      if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS))
++      if (ci->m_flags & S_DEL_PENDING)
+               ret = KSMBD_INODE_STATUS_PENDING_DELETE;
+       else
+               ret = KSMBD_INODE_STATUS_OK;
+@@ -134,7 +134,7 @@ bool ksmbd_inode_pending_delete(struct k
+       int ret;
+       down_read(&ci->m_lock);
+-      ret = (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS));
++      ret = (ci->m_flags & S_DEL_PENDING);
+       up_read(&ci->m_lock);
+       return ret;
+@@ -302,12 +302,20 @@ static void __ksmbd_inode_close(struct k
+               }
+       }
++      down_write(&ci->m_lock);
++      /* Promote S_DEL_ON_CLS to S_DEL_PENDING when close */
++      if (ci->m_flags & S_DEL_ON_CLS) {
++              ci->m_flags &= ~S_DEL_ON_CLS;
++              ci->m_flags |= S_DEL_PENDING;
++      }
++      up_write(&ci->m_lock);
++
+       if (atomic_dec_and_test(&ci->m_count)) {
+               bool do_unlink = false;
+               down_write(&ci->m_lock);
+-              if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) {
+-                      ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
++              if (ci->m_flags & S_DEL_PENDING) {
++                      ci->m_flags &= ~S_DEL_PENDING;
+                       do_unlink = true;
+               }
+               up_write(&ci->m_lock);
diff --git a/queue-6.18/spi-amd-set-correct-bus-number-in-acpi-probe-path.patch b/queue-6.18/spi-amd-set-correct-bus-number-in-acpi-probe-path.patch
new file mode 100644 (file)
index 0000000..7e79390
--- /dev/null
@@ -0,0 +1,43 @@
+From 422bd00b71ab42163aa3b8f8370276fe4c1581e7 Mon Sep 17 00:00:00 2001
+From: Krishnamoorthi M <krishnamoorthi.m@amd.com>
+Date: Thu, 7 May 2026 23:30:51 +0530
+Subject: spi: amd: Set correct bus number in ACPI probe path
+
+From: Krishnamoorthi M <krishnamoorthi.m@amd.com>
+
+commit 422bd00b71ab42163aa3b8f8370276fe4c1581e7 upstream.
+
+On platforms where the HID2 SPI controller (AMDI0063) is enumerated via
+ACPI instead of PCI, amd_spi_probe() unconditionally sets bus_num to 0,
+while the PCI probe path assigns bus_num 2 for HID2 controller.
+
+Align the ACPI probe path to use the same bus number so that userspace
+and SPI client drivers see a consistent bus assignment regardless of the
+enumeration method.
+
+Fixes: b644c2776652 ("spi: spi_amd: Add PCI-based driver for AMD HID2 SPI controller")
+Cc: stable@vger.kernel.org # v6.16+
+Signed-off-by: Krishnamoorthi M <krishnamoorthi.m@amd.com>
+Link: https://patch.msgid.link/20260507180051.4158674-1-krishnamoorthi.m@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-amd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c
+index 4d1dce4f4974..71a6e5c475b0 100644
+--- a/drivers/spi/spi-amd.c
++++ b/drivers/spi/spi-amd.c
+@@ -868,7 +868,7 @@ static int amd_spi_probe(struct platform_device *pdev)
+       dev_dbg(dev, "io_remap_address: %p\n", amd_spi->io_remap_addr);
+       amd_spi->version = (uintptr_t)device_get_match_data(dev);
+-      host->bus_num = 0;
++      host->bus_num = (amd_spi->version == AMD_HID2_SPI) ? 2 : 0;
+       return amd_spi_probe_common(dev, host);
+ }
+-- 
+2.54.0
+
diff --git a/queue-6.18/sysfs-don-t-remove-existing-directory-on-update-failure.patch b/queue-6.18/sysfs-don-t-remove-existing-directory-on-update-failure.patch
new file mode 100644 (file)
index 0000000..81b50a0
--- /dev/null
@@ -0,0 +1,43 @@
+From 237557b8a81ab948e8332f7c0058e758f081c0a3 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Wed, 20 May 2026 15:05:04 +0200
+Subject: sysfs: don't remove existing directory on update failure
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 237557b8a81ab948e8332f7c0058e758f081c0a3 upstream.
+
+When sysfs_update_group() is called for a named group and create_files()
+fails (e.g. -ENOMEM), internal_create_group() calls kernfs_remove(kn) on
+the group directory.  In the update path, kn was obtained via
+kernfs_find_and_get() and refers to a directory that already existed
+before this call.  Removing it silently destroys a sysfs group that the
+caller did not create.
+
+Only remove the directory if we created it ourselves.  On update failure
+the directory remains as it is left empty by remove_files() inside
+create_files(), but can be repopulated by a retry.
+
+Cc: Rajat Jain <rajatja@google.com>
+Fixes: c855cf2759d2 ("sysfs: Fix internal_create_group() for named group updates")
+Cc: stable <stable@kernel.org>
+Assisted-by: gkh_clanker_t1000
+Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
+Reviewed-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://patch.msgid.link/2026052003-uniquely-hastily-c093@gregkh
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/sysfs/group.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/sysfs/group.c
++++ b/fs/sysfs/group.c
+@@ -182,7 +182,7 @@ static int internal_create_group(struct
+       kernfs_get(kn);
+       error = create_files(kn, kobj, uid, gid, grp, update);
+       if (error) {
+-              if (grp->name)
++              if (grp->name && !update)
+                       kernfs_remove(kn);
+       }
+       kernfs_put(kn);