--- /dev/null
+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",
--- /dev/null
+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
+@@ -2074,6 +2074,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);
+ }
--- /dev/null
+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
+@@ -914,8 +914,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) &&
--- /dev/null
+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:
--- /dev/null
+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
+@@ -306,6 +306,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
+@@ -692,6 +692,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 stands for a PA sync connection,
+@@ -1146,8 +1148,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
+@@ -348,8 +348,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;
+@@ -1441,22 +1446,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
+@@ -432,6 +432,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;
+@@ -704,8 +706,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;
--- /dev/null
+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;
+@@ -528,6 +540,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);
+
+@@ -537,24 +550,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);
+
+@@ -622,11 +649,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);
+ }
+
+@@ -692,6 +720,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);
--- /dev/null
+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
+@@ -2107,6 +2107,11 @@ void iso_recv(struct hci_conn *hcon, str
+ 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;
--- /dev/null
+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
+@@ -9140,9 +9140,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);
--- /dev/null
+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
+@@ -380,6 +380,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
+@@ -151,6 +151,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);
+
+@@ -211,6 +212,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);
+
+@@ -221,9 +223,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.
+ */
+@@ -241,8 +247,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);
+
+@@ -251,45 +255,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);
+
+@@ -317,6 +348,8 @@ restart:
+ sock_hold(sk);
+
+ release_sock(sk);
++ if (next)
++ sock_put(next);
+ return sk;
+ }
+
+@@ -518,18 +551,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,
--- /dev/null
+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
+@@ -1211,8 +1211,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)
+@@ -1220,8 +1222,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)
--- /dev/null
+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
+@@ -371,21 +371,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
+@@ -397,9 +387,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);
--- /dev/null
+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);
--- /dev/null
+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))
--- /dev/null
+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(-)
+
+diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
+index c1d1f34581d6..9161e9d7ed24 100644
+--- a/fs/smb/server/smbacl.c
++++ b/fs/smb/server/smbacl.c
+@@ -643,8 +643,10 @@ static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap,
+ 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(struct mnt_idmap *idmap,
+ 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 |=
+--
+2.54.0
+
--- /dev/null
+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
+@@ -1539,6 +1539,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;
+ }
+ }
--- /dev/null
+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
+@@ -1326,13 +1326,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);
--- /dev/null
+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);
+ }
--- /dev/null
+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
+@@ -1430,6 +1430,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:
--- /dev/null
+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");
--- /dev/null
+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;
+ }
--- /dev/null
+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
+@@ -12,6 +12,7 @@
+ struct nf_queue_entry {
+ struct list_head list;
+ 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
+@@ -972,6 +972,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;
--- /dev/null
+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
+@@ -156,7 +156,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;
--- /dev/null
+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:
revert-s390-cio-update-purge-function-to-unregister-.patch
revert-af_unix-reject-siocatmark-on-non-stream-socke.patch
i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.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
+smb-client-protect-tc_count-increment-in-smb2_find_smb_sess_tcon_unlocked.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
+efi-allocate-runtime-workqueue-before-acpi-init.patch
+drivers-base-memory-fix-memory-block-reference-leak-in-poison-accounting.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-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-ifb-report-ethtool-stats-over-num_tx_queues.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
--- /dev/null
+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
+@@ -214,7 +214,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;
--- /dev/null
+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);
--- /dev/null
+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
+@@ -151,7 +151,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);