]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 May 2026 13:02:50 +0000 (15:02 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 May 2026 13:02:50 +0000 (15:02 +0200)
added patches:
alsa-aloop-fix-peer-runtime-uaf-during-format-change-stop.patch
alsa-caiaq-fix-usb_dev-refcount-leak-on-probe-failure.patch
drm-amdgpu-fix-zero-size-gds-range-init-on-rdna4.patch
ipv6-rpl-reserve-mac_len-headroom-when-recompressed-srh-grows.patch
mm-page_alloc-return-null-early-from-alloc_frozen_pages_nolock-in-nmi-on-up.patch
mm-slab-return-null-early-from-kmalloc_nolock-in-nmi-on-up.patch
net-ipv6-fix-noref-dst-use-in-seg6-and-rpl-lwtunnels.patch
netfilter-reject-zero-shift-in-nft_bitwise.patch
vmalloc-fix-buffer-overflow-in-vrealloc_node_align.patch

queue-6.18/alsa-aloop-fix-peer-runtime-uaf-during-format-change-stop.patch [new file with mode: 0644]
queue-6.18/alsa-caiaq-fix-usb_dev-refcount-leak-on-probe-failure.patch [new file with mode: 0644]
queue-6.18/drm-amdgpu-fix-zero-size-gds-range-init-on-rdna4.patch [new file with mode: 0644]
queue-6.18/ipv6-rpl-reserve-mac_len-headroom-when-recompressed-srh-grows.patch [new file with mode: 0644]
queue-6.18/mm-page_alloc-return-null-early-from-alloc_frozen_pages_nolock-in-nmi-on-up.patch [new file with mode: 0644]
queue-6.18/mm-slab-return-null-early-from-kmalloc_nolock-in-nmi-on-up.patch [new file with mode: 0644]
queue-6.18/net-ipv6-fix-noref-dst-use-in-seg6-and-rpl-lwtunnels.patch [new file with mode: 0644]
queue-6.18/netfilter-reject-zero-shift-in-nft_bitwise.patch [new file with mode: 0644]
queue-6.18/series
queue-6.18/vmalloc-fix-buffer-overflow-in-vrealloc_node_align.patch [new file with mode: 0644]

diff --git a/queue-6.18/alsa-aloop-fix-peer-runtime-uaf-during-format-change-stop.patch b/queue-6.18/alsa-aloop-fix-peer-runtime-uaf-during-format-change-stop.patch
new file mode 100644 (file)
index 0000000..ba27d20
--- /dev/null
@@ -0,0 +1,128 @@
+From e5c33cdc6f402eab8abd36ecf436b22c9d3a8aff Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= <cassiogabrielcontato@gmail.com>
+Date: Fri, 24 Apr 2026 09:48:41 -0300
+Subject: ALSA: aloop: Fix peer runtime UAF during format-change stop
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+commit e5c33cdc6f402eab8abd36ecf436b22c9d3a8aff upstream.
+
+loopback_check_format() may stop the capture side when playback starts
+with parameters that no longer match a running capture stream. Commit
+826af7fa62e3 ("ALSA: aloop: Fix racy access at PCM trigger") moved
+the peer lookup under cable->lock, but the actual snd_pcm_stop() still
+runs after dropping that lock.
+
+A concurrent close can clear the capture entry from cable->streams[] and
+detach or free its runtime while the playback trigger path still holds a
+stale peer substream pointer.
+
+Keep a per-cable count of in-flight peer stops before dropping
+cable->lock, and make free_cable() wait for those stops before
+detaching the runtime. This preserves the existing behavior while
+making the peer runtime lifetime explicit.
+
+Reported-by: syzbot+8fa95c41eafbc9d2ff6f@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=8fa95c41eafbc9d2ff6f
+Fixes: 597603d615d2 ("ALSA: introduce the snd-aloop module for the PCM loopback")
+Cc: stable@vger.kernel.org
+Suggested-by: Takashi Iwai <tiwai@suse.com>
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260424-alsa-aloop-peer-stop-uaf-v2-1-94e68101db8a@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/drivers/aloop.c |   43 ++++++++++++++++++++++++++++++-------------
+ 1 file changed, 30 insertions(+), 13 deletions(-)
+
+--- a/sound/drivers/aloop.c
++++ b/sound/drivers/aloop.c
+@@ -99,6 +99,9 @@ struct loopback_ops {
+ struct loopback_cable {
+       spinlock_t lock;
+       struct loopback_pcm *streams[2];
++      /* in-flight peer stops running outside cable->lock */
++      atomic_t stop_count;
++      wait_queue_head_t stop_wait;
+       struct snd_pcm_hardware hw;
+       /* flags */
+       unsigned int valid;
+@@ -366,8 +369,11 @@ static int loopback_check_format(struct
+                               return 0;
+                       if (stream == SNDRV_PCM_STREAM_CAPTURE)
+                               return -EIO;
+-                      else if (cruntime->state == SNDRV_PCM_STATE_RUNNING)
++                      else if (cruntime->state == SNDRV_PCM_STATE_RUNNING) {
++                              /* close must not free the peer runtime below */
++                              atomic_inc(&cable->stop_count);
+                               stop_capture = true;
++                      }
+               }
+               setup = get_setup(dpcm_play);
+@@ -396,8 +402,11 @@ static int loopback_check_format(struct
+               }
+       }
+-      if (stop_capture)
++      if (stop_capture) {
+               snd_pcm_stop(dpcm_capt->substream, SNDRV_PCM_STATE_DRAINING);
++              if (atomic_dec_and_test(&cable->stop_count))
++                      wake_up(&cable->stop_wait);
++      }
+       return 0;
+ }
+@@ -1049,23 +1058,29 @@ static void free_cable(struct snd_pcm_su
+       struct loopback *loopback = substream->private_data;
+       int dev = get_cable_index(substream);
+       struct loopback_cable *cable;
++      struct loopback_pcm *dpcm;
++      bool other_alive;
+       cable = loopback->cables[substream->number][dev];
+       if (!cable)
+               return;
+-      if (cable->streams[!substream->stream]) {
+-              /* other stream is still alive */
+-              guard(spinlock_irq)(&cable->lock);
+-              cable->streams[substream->stream] = NULL;
+-      } else {
+-              struct loopback_pcm *dpcm = substream->runtime->private_data;
+-              if (cable->ops && cable->ops->close_cable && dpcm)
+-                      cable->ops->close_cable(dpcm);
+-              /* free the cable */
+-              loopback->cables[substream->number][dev] = NULL;
+-              kfree(cable);
++      scoped_guard(spinlock_irq, &cable->lock) {
++              cable->streams[substream->stream] = NULL;
++              other_alive = cable->streams[!substream->stream];
+       }
++
++      /* Pair with the stop_count increment in loopback_check_format(). */
++      wait_event(cable->stop_wait, !atomic_read(&cable->stop_count));
++      if (other_alive)
++              return;
++
++      dpcm = substream->runtime->private_data;
++      if (cable->ops && cable->ops->close_cable && dpcm)
++              cable->ops->close_cable(dpcm);
++      /* free the cable */
++      loopback->cables[substream->number][dev] = NULL;
++      kfree(cable);
+ }
+ static int loopback_jiffies_timer_open(struct loopback_pcm *dpcm)
+@@ -1260,6 +1275,8 @@ static int loopback_open(struct snd_pcm_
+                       goto unlock;
+               }
+               spin_lock_init(&cable->lock);
++              atomic_set(&cable->stop_count, 0);
++              init_waitqueue_head(&cable->stop_wait);
+               cable->hw = loopback_pcm_hardware;
+               if (loopback->timer_source)
+                       cable->ops = &loopback_snd_timer_ops;
diff --git a/queue-6.18/alsa-caiaq-fix-usb_dev-refcount-leak-on-probe-failure.patch b/queue-6.18/alsa-caiaq-fix-usb_dev-refcount-leak-on-probe-failure.patch
new file mode 100644 (file)
index 0000000..3eca6d5
--- /dev/null
@@ -0,0 +1,63 @@
+From 7a5f1cd22d47f8ca4b760b6334378ae42c1bd24b Mon Sep 17 00:00:00 2001
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+Date: Sun, 26 Apr 2026 05:49:34 +0530
+Subject: ALSA: caiaq: fix usb_dev refcount leak on probe failure
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+commit 7a5f1cd22d47f8ca4b760b6334378ae42c1bd24b upstream.
+
+create_card() takes a reference on the USB device with usb_get_dev()
+and stores the matching usb_put_dev() in card_free(), which is
+installed as the snd_card's ->private_free destructor.
+
+However, ->private_free is only assigned near the end of init_card(),
+after several failure points (usb_set_interface(), EP type checks,
+usb_submit_urb(), the EP1_CMD_GET_DEVICE_INFO exchange, and its
+timeout). When any of those fail, init_card() returns an error to
+snd_probe(), which calls snd_card_free(card). Because ->private_free
+is still NULL, card_free() never runs, the usb_get_dev() reference
+is not dropped, and the struct usb_device leaks along with its
+descriptor allocations and device_private.
+
+syzbot reproduces this with a malformed UAC3 device whose only valid
+altsetting is 0; init_card()'s usb_set_interface(usb_dev, 0, 1) call
+fails with -EIO and triggers the leak.
+
+Move the ->private_free assignment into create_card(), immediately
+after usb_get_dev(), so that every error path reaching snd_card_free()
+balances the reference. card_free()'s callees (snd_usb_caiaq_input_free,
+free_urbs, kfree) already tolerate the partially-initialized state
+because the chip private area is zero-initialized by snd_card_new().
+
+Fixes: 80bb50e2d459 ("ALSA: caiaq: take a reference on the USB device in create_card()")
+Reported-by: syzbot+2afd7e71155c7e241560@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=2afd7e71155c7e241560
+Tested-by: syzbot+2afd7e71155c7e241560@syzkaller.appspotmail.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
+Link: https://patch.msgid.link/20260426001934.70813-1-kartikey406@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/caiaq/device.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/usb/caiaq/device.c
++++ b/sound/usb/caiaq/device.c
+@@ -423,6 +423,7 @@ static int create_card(struct usb_device
+       cdev = caiaqdev(card);
+       cdev->chip.dev = usb_get_dev(usb_dev);
++      card->private_free = card_free;
+       cdev->chip.card = card;
+       cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor),
+                                 le16_to_cpu(usb_dev->descriptor.idProduct));
+@@ -511,7 +512,6 @@ static int init_card(struct snd_usb_caia
+       scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
+                      cdev->vendor_name, cdev->product_name, usbpath);
+-      card->private_free = card_free;
+       err = setup_card(cdev);
+       if (err < 0)
+               goto err_kill_urb;
diff --git a/queue-6.18/drm-amdgpu-fix-zero-size-gds-range-init-on-rdna4.patch b/queue-6.18/drm-amdgpu-fix-zero-size-gds-range-init-on-rdna4.patch
new file mode 100644 (file)
index 0000000..9cb3623
--- /dev/null
@@ -0,0 +1,64 @@
+From 095a8b0ad3c3b5cdc3850d961adb8a8f735220bb Mon Sep 17 00:00:00 2001
+From: Arjan van de Ven <arjan@linux.intel.com>
+Date: Mon, 20 Apr 2026 14:57:15 -0700
+Subject: drm/amdgpu: fix zero-size GDS range init on RDNA4
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arjan van de Ven <arjan@linux.intel.com>
+
+commit 095a8b0ad3c3b5cdc3850d961adb8a8f735220bb upstream.
+
+RDNA4 (GFX 12) hardware removes the GDS, GWS, and OA on-chip memory
+resources. The gfx_v12_0 initialisation code correctly leaves
+adev->gds.gds_size, adev->gds.gws_size, and adev->gds.oa_size at
+zero to reflect this.
+
+amdgpu_ttm_init() unconditionally calls amdgpu_ttm_init_on_chip() for
+each of these resources regardless of size. When the size is zero,
+amdgpu_ttm_init_on_chip() forwards the call to ttm_range_man_init(),
+which calls drm_mm_init(mm, 0, 0). drm_mm_init() immediately fires
+DRM_MM_BUG_ON(start + size <= start) -- trivially true when size is
+zero -- crashing the kernel during modprobe of amdgpu on an RX 9070 XT.
+
+Guard against this by returning 0 early from
+amdgpu_ttm_init_on_chip() when size_in_page is zero. This skips TTM
+resource manager registration for hardware resources that are absent,
+without affecting any other GPU type.
+
+DRM_MM_BUG_ON() only asserts if CONFIG_DRM_DEBUG_MM is enabled in
+the kernel config.  This is apparently rarely enabled as these chips
+have been in the market for over a year and this issue was only reported
+now.
+
+Link: https://lore.kernel.org/all/bug-221376-2300@https.bugzilla.kernel.org%2F/
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221376
+Oops-Analysis: http://oops.fenrus.org/reports/bugzilla.korg/221376/report.html
+Assisted-by: GitHub Copilot:Claude Sonnet 4.6 linux-kernel-oops-x86.
+Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: "Christian König" <christian.koenig@amd.com>
+Cc: amd-gfx@lists.freedesktop.org
+Cc: dri-devel@lists.freedesktop.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 5719ce5865279cad4fd5f01011fe037168503f2d)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -75,6 +75,9 @@ static int amdgpu_ttm_init_on_chip(struc
+                                   unsigned int type,
+                                   uint64_t size_in_page)
+ {
++      if (!size_in_page)
++              return 0;
++
+       return ttm_range_man_init(&adev->mman.bdev, type,
+                                 false, size_in_page);
+ }
diff --git a/queue-6.18/ipv6-rpl-reserve-mac_len-headroom-when-recompressed-srh-grows.patch b/queue-6.18/ipv6-rpl-reserve-mac_len-headroom-when-recompressed-srh-grows.patch
new file mode 100644 (file)
index 0000000..f05ce88
--- /dev/null
@@ -0,0 +1,78 @@
+From 9e6bf146b55999a095bb14f73a843942456d1adc Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Tue, 21 Apr 2026 15:16:33 +0200
+Subject: ipv6: rpl: reserve mac_len headroom when recompressed SRH grows
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 9e6bf146b55999a095bb14f73a843942456d1adc upstream.
+
+ipv6_rpl_srh_rcv() decompresses an RFC 6554 Source Routing Header, swaps
+the next segment into ipv6_hdr->daddr, recompresses, then pulls the old
+header and pushes the new one plus the IPv6 header back.  The
+recompressed header can be larger than the received one when the swap
+reduces the common-prefix length the segments share with daddr (CmprI=0,
+CmprE>0, seg[0][0] != daddr[0] gives the maximum +8 bytes).
+
+pskb_expand_head() was gated on segments_left == 0, so on earlier
+segments the push consumed unchecked headroom.  Once skb_push() leaves
+fewer than skb->mac_len bytes in front of data,
+skb_mac_header_rebuild()'s call to:
+
+       skb_set_mac_header(skb, -skb->mac_len);
+
+will store (data - head) - mac_len into the u16 mac_header field, which
+wraps to ~65530, and the following memmove() writes mac_len bytes ~64KiB
+past skb->head.
+
+A single AF_INET6/SOCK_RAW/IPV6_HDRINCL packet over lo with a two
+segment type-3 SRH (CmprI=0, CmprE=15) reaches headroom 8 after one
+pass; KASAN reports a 14-byte OOB write in ipv6_rthdr_rcv.
+
+Fix this by expanding the head whenever the remaining room is less than
+the push size plus mac_len, and request that much extra so the rebuilt
+MAC header fits afterwards.
+
+Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
+Cc: stable <stable@kernel.org>
+Reported-by: Anthropic
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/2026042133-gout-unvented-1bd9@gregkh
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/exthdrs.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -491,6 +491,7 @@ static int ipv6_rpl_srh_rcv(struct sk_bu
+       struct net *net = dev_net(skb->dev);
+       struct inet6_dev *idev;
+       struct ipv6hdr *oldhdr;
++      unsigned int chdr_len;
+       unsigned char *buf;
+       int accept_rpl_seg;
+       int i, err;
+@@ -592,8 +593,10 @@ looped_back:
+       skb_pull(skb, ((hdr->hdrlen + 1) << 3));
+       skb_postpull_rcsum(skb, oldhdr,
+                          sizeof(struct ipv6hdr) + ((hdr->hdrlen + 1) << 3));
+-      if (unlikely(!hdr->segments_left)) {
+-              if (pskb_expand_head(skb, sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3), 0,
++      chdr_len = sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3);
++      if (unlikely(!hdr->segments_left ||
++                   skb_headroom(skb) < chdr_len + skb->mac_len)) {
++              if (pskb_expand_head(skb, chdr_len + skb->mac_len, 0,
+                                    GFP_ATOMIC)) {
+                       __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_OUTDISCARDS);
+                       kfree_skb(skb);
+@@ -603,7 +606,7 @@ looped_back:
+               oldhdr = ipv6_hdr(skb);
+       }
+-      skb_push(skb, ((chdr->hdrlen + 1) << 3) + sizeof(struct ipv6hdr));
++      skb_push(skb, chdr_len);
+       skb_reset_network_header(skb);
+       skb_mac_header_rebuild(skb);
+       skb_set_transport_header(skb, sizeof(struct ipv6hdr));
diff --git a/queue-6.18/mm-page_alloc-return-null-early-from-alloc_frozen_pages_nolock-in-nmi-on-up.patch b/queue-6.18/mm-page_alloc-return-null-early-from-alloc_frozen_pages_nolock-in-nmi-on-up.patch
new file mode 100644 (file)
index 0000000..f2937e8
--- /dev/null
@@ -0,0 +1,61 @@
+From 620b46ed6ae17c8438d889c8c0cfddab36a1476c Mon Sep 17 00:00:00 2001
+From: "Harry Yoo (Oracle)" <harry@kernel.org>
+Date: Mon, 27 Apr 2026 16:09:52 +0900
+Subject: mm/page_alloc: return NULL early from alloc_frozen_pages_nolock() in NMI on UP
+
+From: Harry Yoo (Oracle) <harry@kernel.org>
+
+commit 620b46ed6ae17c8438d889c8c0cfddab36a1476c upstream.
+
+On UP kernels (!CONFIG_SMP), spin_trylock() is a no-op that
+unconditionally succeeds even when the lock is already held. As a
+result, alloc_frozen_pages_nolock() called from NMI context can
+re-enter rmqueue() and acquire the zone lock that the interrupted
+context is already holding, corrupting the freelists.
+
+With CONFIG_DEBUG_SPINLOCK on UP, the following BUG is triggered with
+the slub_kunit test module:
+
+  BUG: spinlock trylock failure on UP on CPU#0, kunit_try_catch/243
+  [...]
+  Call Trace:
+   <NMI>
+   dump_stack_lvl+0x3f/0x60
+   do_raw_spin_trylock+0x41/0x50
+   _raw_spin_trylock+0x24/0x50
+   rmqueue.isra.0+0x2a9/0xa70
+   get_page_from_freelist+0xeb/0x450
+   alloc_frozen_pages_nolock_noprof+0x111/0x1e0
+   allocate_slab+0x42a/0x500
+   ___slab_alloc+0xa7/0x4c0
+   kmalloc_nolock_noprof+0x164/0x310
+   [...]
+   </NMI>
+
+Fix this by returning NULL early when invoked from NMI on a UP kernel.
+
+Link: https://lore.kernel.org/linux-mm/ad_cqe51pvr1WaDg@hyeyoo
+Cc: stable@vger.kernel.org
+Fixes: d7242af86434 ("mm: Introduce alloc_frozen_pages_nolock()")
+Signed-off-by: Harry Yoo (Oracle) <harry@kernel.org>
+Link: https://patch.msgid.link/20260427-nolock-api-fix-v2-1-a6b83a92d9a4@kernel.org
+Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/page_alloc.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -7641,6 +7641,11 @@ struct page *alloc_frozen_pages_nolock_n
+        */
+       if (IS_ENABLED(CONFIG_PREEMPT_RT) && (in_nmi() || in_hardirq()))
+               return NULL;
++
++      /* On UP, spin_trylock() always succeeds even when it is locked */
++      if (!IS_ENABLED(CONFIG_SMP) && in_nmi())
++              return NULL;
++
+       if (!pcp_allowed_order(order))
+               return NULL;
diff --git a/queue-6.18/mm-slab-return-null-early-from-kmalloc_nolock-in-nmi-on-up.patch b/queue-6.18/mm-slab-return-null-early-from-kmalloc_nolock-in-nmi-on-up.patch
new file mode 100644 (file)
index 0000000..7a13049
--- /dev/null
@@ -0,0 +1,58 @@
+From 5b31044e649e3e54c2caef135c09b371c2fbcd08 Mon Sep 17 00:00:00 2001
+From: "Harry Yoo (Oracle)" <harry@kernel.org>
+Date: Mon, 27 Apr 2026 16:09:53 +0900
+Subject: mm/slab: return NULL early from kmalloc_nolock() in NMI on UP
+
+From: Harry Yoo (Oracle) <harry@kernel.org>
+
+commit 5b31044e649e3e54c2caef135c09b371c2fbcd08 upstream.
+
+On UP kernels (!CONFIG_SMP), spin_trylock() is a no-op that
+unconditionally succeeds even when the lock is already held. As a
+result, kmalloc_nolock() called from NMI context can re-enter the slab
+allocator and acquire n->list_lock that the interrupted context is
+already holding, corrupting slab state.
+
+With CONFIG_DEBUG_SPINLOCK on UP, the following BUG is triggered with
+the slub_kunit test module:
+
+  BUG: spinlock trylock failure on UP on CPU#0, kunit_try_catch/243
+  [...]
+  Call Trace:
+   <NMI>
+   dump_stack_lvl+0x3f/0x60
+   do_raw_spin_trylock+0x41/0x50
+   _raw_spin_trylock+0x24/0x50
+   get_from_partial_node+0x120/0x4d0
+   ___slab_alloc+0x8a/0x4c0
+   kmalloc_nolock_noprof+0x164/0x310
+   [...]
+   </NMI>
+
+Fix this by returning NULL early when invoked from NMI on a UP kernel.
+
+Link: https://lore.kernel.org/linux-mm/ad_cqe51pvr1WaDg@hyeyoo
+Cc: stable@vger.kernel.org
+Fixes: af92793e52c3 ("slab: Introduce kmalloc_nolock() and kfree_nolock().")
+Signed-off-by: Harry Yoo (Oracle) <harry@kernel.org>
+Link: https://patch.msgid.link/20260427-nolock-api-fix-v2-2-a6b83a92d9a4@kernel.org
+Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/slub.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -5752,6 +5752,11 @@ void *kmalloc_nolock_noprof(size_t size,
+                * sleeping lock on RT.
+                */
+               return NULL;
++
++      /* On UP, spin_trylock() always succeeds even when it is locked */
++      if (!IS_ENABLED(CONFIG_SMP) && in_nmi())
++              return NULL;
++
+ retry:
+       if (unlikely(size > KMALLOC_MAX_CACHE_SIZE))
+               return NULL;
diff --git a/queue-6.18/net-ipv6-fix-noref-dst-use-in-seg6-and-rpl-lwtunnels.patch b/queue-6.18/net-ipv6-fix-noref-dst-use-in-seg6-and-rpl-lwtunnels.patch
new file mode 100644 (file)
index 0000000..7984570
--- /dev/null
@@ -0,0 +1,122 @@
+From f9c52a6ba9780bd27e0bf4c044fd91c13c778b6e Mon Sep 17 00:00:00 2001
+From: Andrea Mayer <andrea.mayer@uniroma2.it>
+Date: Tue, 21 Apr 2026 11:47:35 +0200
+Subject: net: ipv6: fix NOREF dst use in seg6 and rpl lwtunnels
+
+From: Andrea Mayer <andrea.mayer@uniroma2.it>
+
+commit f9c52a6ba9780bd27e0bf4c044fd91c13c778b6e upstream.
+
+seg6_input_core() and rpl_input() call ip6_route_input() which sets a
+NOREF dst on the skb, then pass it to dst_cache_set_ip6() invoking
+dst_hold() unconditionally.
+On PREEMPT_RT, ksoftirqd is preemptible and a higher-priority task can
+release the underlying pcpu_rt between the lookup and the caching
+through a concurrent FIB lookup on a shared nexthop.
+Simplified race sequence:
+
+  ksoftirqd/X                       higher-prio task (same CPU X)
+  -----------                       --------------------------------
+  seg6_input_core(,skb)/rpl_input(skb)
+    dst_cache_get()
+      -> miss
+    ip6_route_input(skb)
+      -> ip6_pol_route(,skb,flags)
+         [RT6_LOOKUP_F_DST_NOREF in flags]
+        -> FIB lookup resolves fib6_nh
+           [nhid=N route]
+        -> rt6_make_pcpu_route()
+           [creates pcpu_rt, refcount=1]
+             pcpu_rt->sernum = fib6_sernum
+             [fib6_sernum=W]
+           -> cmpxchg(fib6_nh.rt6i_pcpu,
+                      NULL, pcpu_rt)
+              [slot was empty, store succeeds]
+      -> skb_dst_set_noref(skb, dst)
+         [dst is pcpu_rt, refcount still 1]
+
+                                    rt_genid_bump_ipv6()
+                                      -> bumps fib6_sernum
+                                         [fib6_sernum from W to Z]
+                                    ip6_route_output()
+                                      -> ip6_pol_route()
+                                        -> FIB lookup resolves fib6_nh
+                                           [nhid=N]
+                                        -> rt6_get_pcpu_route()
+                                             pcpu_rt->sernum != fib6_sernum
+                                             [W <> Z, stale]
+                                          -> prev = xchg(rt6i_pcpu, NULL)
+                                          -> dst_release(prev)
+                                             [prev is pcpu_rt,
+                                              refcount 1->0, dead]
+
+    dst = skb_dst(skb)
+    [dst is the dead pcpu_rt]
+    dst_cache_set_ip6(dst)
+      -> dst_hold() on dead dst
+      -> WARN / use-after-free
+
+For the race to occur, ksoftirqd must be preemptible (PREEMPT_RT without
+PREEMPT_RT_NEEDS_BH_LOCK) and a concurrent task must be able to release
+the pcpu_rt. Shared nexthop objects provide such a path, as two routes
+pointing to the same nhid share the same fib6_nh and its rt6i_pcpu
+entry.
+
+Fix seg6_input_core() and rpl_input() by calling skb_dst_force() after
+ip6_route_input() to force the NOREF dst into a refcounted one before
+caching.
+The output path is not affected as ip6_route_output() already returns a
+refcounted dst.
+
+Fixes: af4a2209b134 ("ipv6: sr: use dst_cache in seg6_input")
+Fixes: a7a29f9c361f ("net: ipv6: add rpl sr tunnel")
+Cc: stable@vger.kernel.org
+Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Justin Iurman <justin.iurman@gmail.com>
+Link: https://patch.msgid.link/20260421094735.20997-1-andrea.mayer@uniroma2.it
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/rpl_iptunnel.c  |    9 +++++++++
+ net/ipv6/seg6_iptunnel.c |    9 +++++++++
+ 2 files changed, 18 insertions(+)
+
+--- a/net/ipv6/rpl_iptunnel.c
++++ b/net/ipv6/rpl_iptunnel.c
+@@ -287,7 +287,16 @@ static int rpl_input(struct sk_buff *skb
+       if (!dst) {
+               ip6_route_input(skb);
++
++              /* ip6_route_input() sets a NOREF dst; force a refcount on it
++               * before caching or further use.
++               */
++              skb_dst_force(skb);
+               dst = skb_dst(skb);
++              if (unlikely(!dst)) {
++                      err = -ENETUNREACH;
++                      goto drop;
++              }
+               /* cache only if we don't create a dst reference loop */
+               if (!dst->error && lwtst != dst->lwtstate) {
+--- a/net/ipv6/seg6_iptunnel.c
++++ b/net/ipv6/seg6_iptunnel.c
+@@ -500,7 +500,16 @@ static int seg6_input_core(struct net *n
+       if (!dst) {
+               ip6_route_input(skb);
++
++              /* ip6_route_input() sets a NOREF dst; force a refcount on it
++               * before caching or further use.
++               */
++              skb_dst_force(skb);
+               dst = skb_dst(skb);
++              if (unlikely(!dst)) {
++                      err = -ENETUNREACH;
++                      goto drop;
++              }
+               /* cache only if we don't create a dst reference loop */
+               if (!dst->error && lwtst != dst->lwtstate) {
diff --git a/queue-6.18/netfilter-reject-zero-shift-in-nft_bitwise.patch b/queue-6.18/netfilter-reject-zero-shift-in-nft_bitwise.patch
new file mode 100644 (file)
index 0000000..eb9429a
--- /dev/null
@@ -0,0 +1,47 @@
+From fe11e5c40817b84abaa5d83bfb6586d8412bfd07 Mon Sep 17 00:00:00 2001
+From: Kai Ma <k4729.23098@gmail.com>
+Date: Wed, 22 Apr 2026 22:54:18 +0800
+Subject: netfilter: reject zero shift in nft_bitwise
+
+From: Kai Ma <k4729.23098@gmail.com>
+
+commit fe11e5c40817b84abaa5d83bfb6586d8412bfd07 upstream.
+
+Reject zero shift operands for nft_bitwise left and right shift
+expressions during initialization.
+
+The carry propagation logic computes the carry from the adjacent 32-bit
+word using BITS_PER_TYPE(u32) - shift. A zero shift operand turns this
+into a 32-bit shift, which is undefined behaviour.
+
+Reject zero shift operands in the control plane, alongside the existing
+check for values greater than or equal to 32, so malformed rules never
+reach the packet path.
+
+Fixes: 567d746b55bc ("netfilter: bitwise: add support for shifts.")
+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: Kai Ma <k4729.23098@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.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_bitwise.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/netfilter/nft_bitwise.c
++++ b/net/netfilter/nft_bitwise.c
+@@ -196,7 +196,8 @@ static int nft_bitwise_init_shift(struct
+       if (err < 0)
+               return err;
+-      if (priv->data.data[0] >= BITS_PER_TYPE(u32)) {
++      if (!priv->data.data[0] ||
++          priv->data.data[0] >= BITS_PER_TYPE(u32)) {
+               nft_data_release(&priv->data, desc.type);
+               return -EINVAL;
+       }
index 0473b0b48ca979b15fc9c186b912001cc92e53e3..db2bd2eb685ced31cf8ffa53cfafec7789f8ac53 100644 (file)
@@ -264,3 +264,12 @@ crypto-authencesn-reject-short-ahash-digests-during-instance-creation.patch
 driver-core-add-kernel-doc-for-dev_flag_count-enum-value.patch
 alsa-caiaq-fix-potentially-leftover-ep1_in_urb-at-error-path.patch
 alsa-caiaq-don-t-abort-when-no-input-device-is-available.patch
+ipv6-rpl-reserve-mac_len-headroom-when-recompressed-srh-grows.patch
+drm-amdgpu-fix-zero-size-gds-range-init-on-rdna4.patch
+alsa-caiaq-fix-usb_dev-refcount-leak-on-probe-failure.patch
+alsa-aloop-fix-peer-runtime-uaf-during-format-change-stop.patch
+vmalloc-fix-buffer-overflow-in-vrealloc_node_align.patch
+mm-page_alloc-return-null-early-from-alloc_frozen_pages_nolock-in-nmi-on-up.patch
+mm-slab-return-null-early-from-kmalloc_nolock-in-nmi-on-up.patch
+net-ipv6-fix-noref-dst-use-in-seg6-and-rpl-lwtunnels.patch
+netfilter-reject-zero-shift-in-nft_bitwise.patch
diff --git a/queue-6.18/vmalloc-fix-buffer-overflow-in-vrealloc_node_align.patch b/queue-6.18/vmalloc-fix-buffer-overflow-in-vrealloc_node_align.patch
new file mode 100644 (file)
index 0000000..18cafd5
--- /dev/null
@@ -0,0 +1,46 @@
+From 82d1f01292d3f09bf063f829f8ab8de12b4280a1 Mon Sep 17 00:00:00 2001
+From: Marco Elver <elver@google.com>
+Date: Mon, 20 Apr 2026 13:47:26 +0200
+Subject: vmalloc: fix buffer overflow in vrealloc_node_align()
+
+From: Marco Elver <elver@google.com>
+
+commit 82d1f01292d3f09bf063f829f8ab8de12b4280a1 upstream.
+
+Commit 4c5d3365882d ("mm/vmalloc: allow to set node and align in
+vrealloc") added the ability to force a new allocation if the current
+pointer is on the wrong NUMA node, or if an alignment constraint is not
+met, even if the user is shrinking the allocation.
+
+On this path (need_realloc), the code allocates a new object of 'size'
+bytes and then memcpy()s 'old_size' bytes into it.  If the request is to
+shrink the object (size < old_size), this results in an out-of-bounds
+write on the new buffer.
+
+Fix this by bounding the copy length by the new allocation size.
+
+Link: https://lore.kernel.org/20260420114805.3572606-2-elver@google.com
+Fixes: 4c5d3365882d ("mm/vmalloc: allow to set node and align in vrealloc")
+Signed-off-by: Marco Elver <elver@google.com>
+Reported-by: Harry Yoo (Oracle) <harry@kernel.org>
+Reviewed-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
+Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Reviewed-by: Harry Yoo (Oracle) <harry@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/vmalloc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -4201,7 +4201,7 @@ need_realloc:
+               return NULL;
+       if (p) {
+-              memcpy(n, p, old_size);
++              memcpy(n, p, min(size, old_size));
+               vfree(p);
+       }