]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 Jun 2026 10:36:50 +0000 (12:36 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 Jun 2026 10:36:50 +0000 (12:36 +0200)
added patches:
alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
alsa-hda-realtek-fix-speaker-output-on-asus-rog-strix-g615lp.patch
alsa-scarlett2-fix-2i2-gen-4-direct-monitor-gain-on-firmware-2417.patch
asoc-qcom-q6asm-dai-close-stream-only-when-running.patch
asoc-qcom-q6asm-dai-do-not-set-stream-state-in-event-and-trigger-callbacks.patch
asoc-qcom-q6asm-dai-fix-error-handling-in-prepare-and-set_params.patch
bpf-sockmap-fix-tail-fragment-offset-in-bpf_msg_push_data.patch
hid-wacom-fix-oob-write-in-wacom_hid_set_device_mode.patch
iommu-debugobjects-avoid-gcc-16.1-section-mismatch-warnings.patch
ip6-vti-use-ip6_tnl.net-in-vti6_changelink.patch
ip6-vti-use-ip6_tnl.net-in-vti6_siocdevprivate.patch
ipv6-exthdrs-refresh-nh-after-handling-hao-option.patch
ipv6-exthdrs-refresh-nh-pointer-after-ipv6_hop_jumbo.patch
ipv6-validate-extension-header-length-before-copying-to-cmsg.patch
l2tp-use-refcount_inc_not_zero-in-l2tp_session_get_by_ifname.patch
macsec-fix-replay-protection-at-xpn-lower-pn-wrap.patch
net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch
netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-check.patch
nfc-hci-fix-out-of-bounds-read-in-hcp-header-parsing.patch
spi-spi-mem-avoid-mutating-op-template-in-spi_mem_supports_op.patch
wireguard-send-append-trailer-after-expanding-head.patch
xfrm-ah-use-skb_to_full_sk-in-async-output-callbacks.patch
xfrm-esp-restore-combined-single-frag-length-gate.patch
xfrm-input-hold-netns-during-deferred-transport-reinjection.patch
xfrm-ipcomp-free-destination-pages-on-acomp-errors.patch
xfrm-route-migrate-notifications-to-caller-s-netns.patch

27 files changed:
queue-6.18/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch [new file with mode: 0644]
queue-6.18/alsa-hda-realtek-fix-speaker-output-on-asus-rog-strix-g615lp.patch [new file with mode: 0644]
queue-6.18/alsa-scarlett2-fix-2i2-gen-4-direct-monitor-gain-on-firmware-2417.patch [new file with mode: 0644]
queue-6.18/asoc-qcom-q6asm-dai-close-stream-only-when-running.patch [new file with mode: 0644]
queue-6.18/asoc-qcom-q6asm-dai-do-not-set-stream-state-in-event-and-trigger-callbacks.patch [new file with mode: 0644]
queue-6.18/asoc-qcom-q6asm-dai-fix-error-handling-in-prepare-and-set_params.patch [new file with mode: 0644]
queue-6.18/bpf-sockmap-fix-tail-fragment-offset-in-bpf_msg_push_data.patch [new file with mode: 0644]
queue-6.18/hid-wacom-fix-oob-write-in-wacom_hid_set_device_mode.patch [new file with mode: 0644]
queue-6.18/iommu-debugobjects-avoid-gcc-16.1-section-mismatch-warnings.patch [new file with mode: 0644]
queue-6.18/ip6-vti-use-ip6_tnl.net-in-vti6_changelink.patch [new file with mode: 0644]
queue-6.18/ip6-vti-use-ip6_tnl.net-in-vti6_siocdevprivate.patch [new file with mode: 0644]
queue-6.18/ipv6-exthdrs-refresh-nh-after-handling-hao-option.patch [new file with mode: 0644]
queue-6.18/ipv6-exthdrs-refresh-nh-pointer-after-ipv6_hop_jumbo.patch [new file with mode: 0644]
queue-6.18/ipv6-validate-extension-header-length-before-copying-to-cmsg.patch [new file with mode: 0644]
queue-6.18/l2tp-use-refcount_inc_not_zero-in-l2tp_session_get_by_ifname.patch [new file with mode: 0644]
queue-6.18/macsec-fix-replay-protection-at-xpn-lower-pn-wrap.patch [new file with mode: 0644]
queue-6.18/net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch [new file with mode: 0644]
queue-6.18/netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-check.patch [new file with mode: 0644]
queue-6.18/nfc-hci-fix-out-of-bounds-read-in-hcp-header-parsing.patch [new file with mode: 0644]
queue-6.18/series
queue-6.18/spi-spi-mem-avoid-mutating-op-template-in-spi_mem_supports_op.patch [new file with mode: 0644]
queue-6.18/wireguard-send-append-trailer-after-expanding-head.patch [new file with mode: 0644]
queue-6.18/xfrm-ah-use-skb_to_full_sk-in-async-output-callbacks.patch [new file with mode: 0644]
queue-6.18/xfrm-esp-restore-combined-single-frag-length-gate.patch [new file with mode: 0644]
queue-6.18/xfrm-input-hold-netns-during-deferred-transport-reinjection.patch [new file with mode: 0644]
queue-6.18/xfrm-ipcomp-free-destination-pages-on-acomp-errors.patch [new file with mode: 0644]
queue-6.18/xfrm-route-migrate-notifications-to-caller-s-netns.patch [new file with mode: 0644]

diff --git a/queue-6.18/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch b/queue-6.18/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
new file mode 100644 (file)
index 0000000..7cc53e5
--- /dev/null
@@ -0,0 +1,63 @@
+From 98fb1c1bb11e29eb609b7200a25e136e05aa4498 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= <cassiogabrielcontato@gmail.com>
+Date: Thu, 21 May 2026 08:01:23 -0300
+Subject: ALSA: firewire-motu: Protect register DSP event queue positions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+commit 98fb1c1bb11e29eb609b7200a25e136e05aa4498 upstream.
+
+The register DSP event queue is updated under parser->lock, but
+snd_motu_register_dsp_message_parser_count_event() reads pull_pos and
+push_pos without the lock.
+snd_motu_register_dsp_message_parser_copy_event() also reads both queue
+positions before taking the lock.
+
+Protect these accesses with parser->lock as well. This keeps the hwdep
+poll/read path consistent with the producer side and with the cached
+meter/parameter accessors.
+
+Fixes: 634ec0b2906e ("ALSA: firewire-motu: notify event for parameter change in register DSP model")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260521-alsa-firewire-motu-event-locking-v1-1-708e1c2b5e56@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/firewire/motu/motu-register-dsp-message-parser.c |   11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/sound/firewire/motu/motu-register-dsp-message-parser.c
++++ b/sound/firewire/motu/motu-register-dsp-message-parser.c
+@@ -386,6 +386,8 @@ unsigned int snd_motu_register_dsp_messa
+ {
+       struct msg_parser *parser = motu->message_parser;
++      guard(spinlock_irqsave)(&parser->lock);
++
+       if (parser->pull_pos > parser->push_pos)
+               return EVENT_QUEUE_SIZE - parser->pull_pos + parser->push_pos;
+       else
+@@ -395,13 +397,14 @@ unsigned int snd_motu_register_dsp_messa
+ bool snd_motu_register_dsp_message_parser_copy_event(struct snd_motu *motu, u32 *event)
+ {
+       struct msg_parser *parser = motu->message_parser;
+-      unsigned int pos = parser->pull_pos;
+-
+-      if (pos == parser->push_pos)
+-              return false;
++      unsigned int pos;
+       guard(spinlock_irqsave)(&parser->lock);
++      if (parser->pull_pos == parser->push_pos)
++              return false;
++
++      pos = parser->pull_pos;
+       *event = parser->event_queue[pos];
+       ++pos;
diff --git a/queue-6.18/alsa-hda-realtek-fix-speaker-output-on-asus-rog-strix-g615lp.patch b/queue-6.18/alsa-hda-realtek-fix-speaker-output-on-asus-rog-strix-g615lp.patch
new file mode 100644 (file)
index 0000000..5ae673b
--- /dev/null
@@ -0,0 +1,33 @@
+From 20587302f8d700f26ee2c8a60ffb0a69ae0edf16 Mon Sep 17 00:00:00 2001
+From: Zhang Heng <zhangheng@kylinos.cn>
+Date: Tue, 26 May 2026 09:36:11 +0800
+Subject: ALSA: hda/realtek: Fix speaker output on ASUS ROG Strix G615LP
+
+From: Zhang Heng <zhangheng@kylinos.cn>
+
+commit 20587302f8d700f26ee2c8a60ffb0a69ae0edf16 upstream.
+
+Add quirk for ALC294 codec on ASUS ROG Strix G615LP
+(SSID 1043:1214) using ALC287_FIXUP_TXNW2781_I2C_ASUS to
+fix speaker output.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221173
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
+Link: https://patch.msgid.link/20260526013611.1954949-1-zhangheng@kylinos.cn
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/codecs/realtek/alc269.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/hda/codecs/realtek/alc269.c
++++ b/sound/hda/codecs/realtek/alc269.c
+@@ -7053,6 +7053,7 @@ static const struct hda_quirk alc269_fix
+       SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
+       HDA_CODEC_QUIRK(0x1043, 0x1204, "ASUS Strix G16 G615JMR", ALC287_FIXUP_TXNW2781_I2C_ASUS),
+       SND_PCI_QUIRK(0x1043, 0x1204, "ASUS Strix G615JHR_JMR_JPR", ALC287_FIXUP_TAS2781_I2C),
++      HDA_CODEC_QUIRK(0x1043, 0x1214, "ASUS ROG Strix G615LP", ALC287_FIXUP_TXNW2781_I2C_ASUS),
+       SND_PCI_QUIRK(0x1043, 0x1214, "ASUS Strix G615LH_LM_LP", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
diff --git a/queue-6.18/alsa-scarlett2-fix-2i2-gen-4-direct-monitor-gain-on-firmware-2417.patch b/queue-6.18/alsa-scarlett2-fix-2i2-gen-4-direct-monitor-gain-on-firmware-2417.patch
new file mode 100644 (file)
index 0000000..405d211
--- /dev/null
@@ -0,0 +1,109 @@
+From db37cf47b67e38ade40de5cd74a4d4d772ff1416 Mon Sep 17 00:00:00 2001
+From: "Geoffrey D. Bennett" <g@b4.vu>
+Date: Sun, 24 May 2026 06:34:14 +0930
+Subject: ALSA: scarlett2: Fix 2i2 Gen 4 direct monitor gain on firmware 2417
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+commit db37cf47b67e38ade40de5cd74a4d4d772ff1416 upstream.
+
+Firmware 2417 for the Scarlett 4th Gen 2i2 moved the direct monitor
+gain parameter by 4 bytes, from offset 0x2a0 to 0x2a4, breaking the
+"Direct Monitor X Mix Y" controls.
+
+Special-case the offset in the get/set config helpers when the
+running firmware is 2417 or later.
+
+Fixes: 4e809a299677 ("ALSA: scarlett2: Add support for Solo, 2i2, and 4i4 Gen 4")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Link: https://patch.msgid.link/ahIWTueUlWA5xiV+@m.b4.vu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/mixer_scarlett2.c |   33 +++++++++++++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+--- a/sound/usb/mixer_scarlett2.c
++++ b/sound/usb/mixer_scarlett2.c
+@@ -2504,6 +2504,27 @@ static int scarlett2_has_config_item(
+       return !!private->config_set->items[config_item_num].offset;
+ }
++/* Return the configuration item's offset, applying any per-firmware
++ * overrides.
++ *
++ * Firmware 2417 for the 2i2 Gen 4 moved DIRECT_MONITOR_GAIN by 4
++ * bytes. Apply that shift here so that the rest of the driver can
++ * keep using the single config set. This override can be removed
++ * once the multi-config-set framework lands.
++ */
++static int scarlett2_config_item_offset(
++      struct scarlett2_data *private, int config_item_num)
++{
++      int offset = private->config_set->items[config_item_num].offset;
++
++      if (config_item_num == SCARLETT2_CONFIG_DIRECT_MONITOR_GAIN &&
++          private->info == &s2i2_gen4_info &&
++          private->firmware_version >= 2417)
++              offset = 0x2a4;
++
++      return offset;
++}
++
+ /* Send a USB message to get configuration parameters; result placed in *buf */
+ static int scarlett2_usb_get_config(
+       struct usb_mixer_interface *mixer,
+@@ -2513,6 +2534,7 @@ static int scarlett2_usb_get_config(
+       const struct scarlett2_config *config_item =
+               &private->config_set->items[config_item_num];
+       int size, err, i;
++      int item_offset;
+       u8 *buf_8;
+       u8 value;
+@@ -2522,13 +2544,15 @@ static int scarlett2_usb_get_config(
+       if (!config_item->offset)
+               return -EFAULT;
++      item_offset = scarlett2_config_item_offset(private, config_item_num);
++
+       /* Writes to the parameter buffer are always 1 byte */
+       size = config_item->size ? config_item->size : 8;
+       /* For byte-sized parameters, retrieve directly into buf */
+       if (size >= 8) {
+               size = size / 8 * count;
+-              err = scarlett2_usb_get(mixer, config_item->offset, buf, size);
++              err = scarlett2_usb_get(mixer, item_offset, buf, size);
+               if (err < 0)
+                       return err;
+               if (config_item->size == 16) {
+@@ -2546,7 +2570,7 @@ static int scarlett2_usb_get_config(
+       }
+       /* For bit-sized parameters, retrieve into value */
+-      err = scarlett2_usb_get(mixer, config_item->offset, &value, 1);
++      err = scarlett2_usb_get(mixer, item_offset, &value, 1);
+       if (err < 0)
+               return err;
+@@ -2696,7 +2720,8 @@ static int scarlett2_usb_set_config(
+        */
+       if (config_item->size >= 8) {
+               size = config_item->size / 8;
+-              offset = config_item->offset + index * size;
++              offset = scarlett2_config_item_offset(private, config_item_num) +
++                       index * size;
+       /* If updating a bit, retrieve the old value, set/clear the
+        * bit as needed, and update value
+@@ -2705,7 +2730,7 @@ static int scarlett2_usb_set_config(
+               u8 tmp;
+               size = 1;
+-              offset = config_item->offset;
++              offset = scarlett2_config_item_offset(private, config_item_num);
+               err = scarlett2_usb_get(mixer, offset, &tmp, 1);
+               if (err < 0)
diff --git a/queue-6.18/asoc-qcom-q6asm-dai-close-stream-only-when-running.patch b/queue-6.18/asoc-qcom-q6asm-dai-close-stream-only-when-running.patch
new file mode 100644 (file)
index 0000000..f4979fe
--- /dev/null
@@ -0,0 +1,72 @@
+From 048c540ee76ded666bda74f9dae1ca3254e0633c Mon Sep 17 00:00:00 2001
+From: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+Date: Mon, 18 May 2026 09:23:44 +0000
+Subject: ASoC: qcom: q6asm-dai: close stream only when running
+
+From: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+
+commit 048c540ee76ded666bda74f9dae1ca3254e0633c upstream.
+
+q6asm_dai_close() and q6asm_dai_compr_free() currently issue CMD_CLOSE
+whenever prtd->state is non-zero.
+
+After prepare() closes an existing stream, the state is updated to
+Q6ASM_STREAM_STOPPED. Since this state is also non-zero, the close and
+free paths can send CMD_CLOSE again for a stream that has already been
+closed.
+
+Restrict CMD_CLOSE to the Q6ASM_STREAM_RUNNING state so the command is
+sent only when the ASM stream is still active.
+
+Fixes: 2a9e92d371db ("ASoC: qdsp6: q6asm: Add q6asm dai driver")
+Cc: Stable@vger.kernel.org
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260518092347.3446946-3-srinivas.kandagatla@oss.qualcomm.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/qcom/qdsp6/q6asm-dai.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
++++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
+@@ -447,12 +447,12 @@ static int q6asm_dai_close(struct snd_so
+       struct q6asm_dai_rtd *prtd = runtime->private_data;
+       if (prtd->audio_client) {
+-              if (prtd->state)
++              if (prtd->state == Q6ASM_STREAM_RUNNING) {
+                       q6asm_cmd(prtd->audio_client, prtd->stream_id,
+                                 CMD_CLOSE);
+-
+-              q6asm_unmap_memory_regions(substream->stream,
++                      q6asm_unmap_memory_regions(substream->stream,
+                                          prtd->audio_client);
++              }
+               q6asm_audio_client_free(prtd->audio_client);
+               prtd->audio_client = NULL;
+       }
+@@ -669,7 +669,7 @@ static int q6asm_dai_compr_free(struct s
+       struct snd_soc_pcm_runtime *rtd = stream->private_data;
+       if (prtd->audio_client) {
+-              if (prtd->state) {
++              if (prtd->state == Q6ASM_STREAM_RUNNING) {
+                       q6asm_cmd(prtd->audio_client, prtd->stream_id,
+                                 CMD_CLOSE);
+                       if (prtd->next_track_stream_id) {
+@@ -677,11 +677,11 @@ static int q6asm_dai_compr_free(struct s
+                                         prtd->next_track_stream_id,
+                                         CMD_CLOSE);
+                       }
+-              }
+-              snd_dma_free_pages(&prtd->dma_buffer);
+-              q6asm_unmap_memory_regions(stream->direction,
++                      q6asm_unmap_memory_regions(stream->direction,
+                                          prtd->audio_client);
++              }
++              snd_dma_free_pages(&prtd->dma_buffer);
+               q6asm_audio_client_free(prtd->audio_client);
+               prtd->audio_client = NULL;
+       }
diff --git a/queue-6.18/asoc-qcom-q6asm-dai-do-not-set-stream-state-in-event-and-trigger-callbacks.patch b/queue-6.18/asoc-qcom-q6asm-dai-do-not-set-stream-state-in-event-and-trigger-callbacks.patch
new file mode 100644 (file)
index 0000000..679f5ac
--- /dev/null
@@ -0,0 +1,67 @@
+From cee3e63e7106c3c81b2053371fdf14240bfba2fc Mon Sep 17 00:00:00 2001
+From: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+Date: Mon, 18 May 2026 09:23:43 +0000
+Subject: ASoC: qcom: q6asm-dai: do not set stream state in event and trigger callbacks
+
+From: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+
+commit cee3e63e7106c3c81b2053371fdf14240bfba2fc upstream.
+
+The q6asm-dai stream state is used by prepare() to decide whether an
+existing stream setup needs to be closed before opening/configuring a new
+one. Updating the state from trigger or asynchronous DSP callbacks can make
+that state stale or incorrect relative to the actual setup lifetime.
+
+In particular, setting Q6ASM_STREAM_STOPPED on STOP or EOS completion can
+make prepare() believe there is no active setup to close, which can result
+in opening/configuring the same stream more than once.
+
+Keep stream state updates tied to prepare(), where the stream is actually
+closed and reopened, and stop changing it from trigger and EOS callbacks.
+
+Fixes: bfbb12dfa144 ("ASoC: qcom: q6asm-dai: perform correct state check before closing")
+Cc: Stable@vger.kernel.org
+Closes: https://lore.kernel.org/all/afS7rTHdc9TyIeLx@rdacayan/
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260518092347.3446946-2-srinivas.kandagatla@oss.qualcomm.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/qcom/qdsp6/q6asm-dai.c |    5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
++++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
+@@ -187,7 +187,6 @@ static void event_handler(uint32_t opcod
+                                  prtd->pcm_count, 0, 0, 0);
+               break;
+       case ASM_CLIENT_EVENT_CMD_EOS_DONE:
+-              prtd->state = Q6ASM_STREAM_STOPPED;
+               break;
+       case ASM_CLIENT_EVENT_DATA_WRITE_DONE: {
+               prtd->pcm_irq_pos += prtd->pcm_count;
+@@ -334,7 +333,6 @@ static int q6asm_dai_trigger(struct snd_
+                                      0, 0, 0);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+-              prtd->state = Q6ASM_STREAM_STOPPED;
+               ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id,
+                                      CMD_EOS);
+               break;
+@@ -545,8 +543,6 @@ static void compress_event_handler(uint3
+                       snd_compr_drain_notify(prtd->cstream);
+                       prtd->notify_on_drain = false;
+-              } else {
+-                      prtd->state = Q6ASM_STREAM_STOPPED;
+               }
+               spin_unlock_irqrestore(&prtd->lock, flags);
+               break;
+@@ -1009,7 +1005,6 @@ static int q6asm_dai_compr_trigger(struc
+                                      0, 0, 0);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+-              prtd->state = Q6ASM_STREAM_STOPPED;
+               ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id,
+                                      CMD_EOS);
+               break;
diff --git a/queue-6.18/asoc-qcom-q6asm-dai-fix-error-handling-in-prepare-and-set_params.patch b/queue-6.18/asoc-qcom-q6asm-dai-fix-error-handling-in-prepare-and-set_params.patch
new file mode 100644 (file)
index 0000000..5681c87
--- /dev/null
@@ -0,0 +1,83 @@
+From 4b4db09f283df65d780bc7cee66cb4a7e9bf4770 Mon Sep 17 00:00:00 2001
+From: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+Date: Mon, 18 May 2026 09:23:45 +0000
+Subject: ASoC: qcom: q6asm-dai: fix error handling in prepare and set_params
+
+From: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+
+commit 4b4db09f283df65d780bc7cee66cb4a7e9bf4770 upstream.
+
+Fix error handling in q6asm_dai_compr_set_params() and q6asm_dai_prepare()
+for both CMD_CLOSE and q6asm_unmap_memory_regions().
+
+In both the functions, we are doing q6asm_audio_client_free in failure
+cases, which means if prepare or set_params fail, we can never recover.
+Now open and close are done in respective dai_open/close functions.
+
+Fixes: 2a9e92d371db ("ASoC: qdsp6: q6asm: Add q6asm dai driver")
+Cc: Stable@vger.kernel.org
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260518092347.3446946-4-srinivas.kandagatla@oss.qualcomm.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/qcom/qdsp6/q6asm-dai.c |   24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
++++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
+@@ -235,9 +235,19 @@ static int q6asm_dai_prepare(struct snd_
+       /* rate and channels are sent to audio driver */
+       if (prtd->state == Q6ASM_STREAM_RUNNING) {
+               /* clear the previous setup if any  */
+-              q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
+-              q6asm_unmap_memory_regions(substream->stream,
+-                                         prtd->audio_client);
++              ret = q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
++              if (ret < 0) {
++                      dev_err(dev, "Failed to close q6asm stream %d\n", prtd->stream_id);
++                      return ret;
++              }
++
++              ret = q6asm_unmap_memory_regions(substream->stream, prtd->audio_client);
++              if (ret < 0) {
++                      dev_err(dev, "Failed to unmap memory regions for q6asm stream %d\n",
++                              prtd->stream_id);
++                      return ret;
++              }
++
+               q6routing_stream_close(soc_prtd->dai_link->id,
+                                        substream->stream);
+               prtd->state = Q6ASM_STREAM_STOPPED;
+@@ -305,8 +315,6 @@ routing_err:
+       q6asm_cmd(prtd->audio_client, prtd->stream_id,  CMD_CLOSE);
+ open_err:
+       q6asm_unmap_memory_regions(substream->stream, prtd->audio_client);
+-      q6asm_audio_client_free(prtd->audio_client);
+-      prtd->audio_client = NULL;
+       return ret;
+ }
+@@ -903,7 +911,7 @@ static int q6asm_dai_compr_set_params(st
+                             prtd->session_id, dir);
+       if (ret) {
+               dev_err(dev, "Stream reg failed ret:%d\n", ret);
+-              goto q6_err;
++              goto routing_err;
+       }
+       ret = __q6asm_dai_compr_set_codec_params(component, stream,
+@@ -929,11 +937,11 @@ static int q6asm_dai_compr_set_params(st
+       return 0;
+ q6_err:
++      q6routing_stream_close(rtd->dai_link->id, dir);
++routing_err:
+       q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
+ open_err:
+-      q6asm_audio_client_free(prtd->audio_client);
+-      prtd->audio_client = NULL;
+       return ret;
+ }
diff --git a/queue-6.18/bpf-sockmap-fix-tail-fragment-offset-in-bpf_msg_push_data.patch b/queue-6.18/bpf-sockmap-fix-tail-fragment-offset-in-bpf_msg_push_data.patch
new file mode 100644 (file)
index 0000000..3145e41
--- /dev/null
@@ -0,0 +1,47 @@
+From f72eed9b84fb771019a955908132410a9ba9ea3f Mon Sep 17 00:00:00 2001
+From: Yuqi Xu <xuyq21@lenovo.com>
+Date: Wed, 27 May 2026 11:48:15 +0800
+Subject: bpf: sockmap: fix tail fragment offset in bpf_msg_push_data
+
+From: Yuqi Xu <xuyq21@lenovo.com>
+
+commit f72eed9b84fb771019a955908132410a9ba9ea3f upstream.
+
+When bpf_msg_push_data() inserts data in the middle of a scatterlist
+entry, it splits the original entry into a left fragment and a right
+fragment.
+
+The right fragment offset is page-local, but the code advances it with
+`start`, which is the message-global insertion point. For inserts into a
+non-first SG entry, this over-advances the offset and leaves the split
+layout inconsistent.
+
+Advance the right fragment offset by the fragment-local delta,
+`start - offset`, which matches the length removed from the front of the
+original entry.
+
+Fixes: 6fff607e2f14 ("bpf: sk_msg program helper bpf_msg_push_data")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Yuqi Xu <xuyq21@lenovo.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Link: https://patch.msgid.link/8b129d10566aa3eb43f61a8f9757bcf51707d324.1779636774.git.xuyq21@lenovo.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/filter.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2859,7 +2859,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_
+               psge->length = start - offset;
+               rsge.length -= psge->length;
+-              rsge.offset += start;
++              rsge.offset += start - offset;
+               sk_msg_iter_var_next(i);
+               sg_unmark_end(psge);
diff --git a/queue-6.18/hid-wacom-fix-oob-write-in-wacom_hid_set_device_mode.patch b/queue-6.18/hid-wacom-fix-oob-write-in-wacom_hid_set_device_mode.patch
new file mode 100644 (file)
index 0000000..fb6a7b7
--- /dev/null
@@ -0,0 +1,81 @@
+From c0a8899e02ddebd51e2589835182c239c2e224ae Mon Sep 17 00:00:00 2001
+From: Lee Jones <lee@kernel.org>
+Date: Wed, 27 May 2026 17:05:26 +0100
+Subject: HID: wacom: Fix OOB write in wacom_hid_set_device_mode()
+
+From: Lee Jones <lee@kernel.org>
+
+commit c0a8899e02ddebd51e2589835182c239c2e224ae upstream.
+
+wacom_hid_set_device_mode() currently assumes that the HID_DG_INPUTMODE
+usage is always located in the first field (field[0]) of the feature report.
+However, a device can specify HID_DG_INPUTMODE in a different field.
+
+If HID_DG_INPUTMODE is in a field other than the first one and the first
+field has a report_count smaller than the usage_index of HID_DG_INPUTMODE,
+this leads to an out-of-bounds write to r->field[0]->value.
+
+Fix this by storing the field index of HID_DG_INPUTMODE in 'struct
+hid_data' during feature mapping.  In wacom_hid_set_device_mode(), use
+this stored field index to access the correct field and add bounds
+checks to ensure both the field index and the value index are within
+valid ranges before writing.
+
+Cc: stable@vger.kernel.org
+Fixes: 5ae6e89f7409 ("HID: wacom: implement the finger part of the HID generic handling")
+Tested-by: Ping Cheng <ping.cheng@wacom.com>
+Reviewed-by: Ping Cheng <ping.cheng@wacom.com>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/wacom_sys.c |   13 ++++++++++---
+ drivers/hid/wacom_wac.h |    1 +
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/hid/wacom_sys.c
++++ b/drivers/hid/wacom_sys.c
+@@ -356,6 +356,7 @@ static void wacom_feature_mapping(struct
+               hid_data->inputmode = field->report->id;
+               hid_data->inputmode_index = usage->usage_index;
++              hid_data->inputmode_field_index = field->index;
+               break;
+       case HID_UP_DIGITIZER:
+@@ -571,9 +572,14 @@ static int wacom_hid_set_device_mode(str
+       re = &(hdev->report_enum[HID_FEATURE_REPORT]);
+       r = re->report_id_hash[hid_data->inputmode];
+-      if (r) {
+-              r->field[0]->value[hid_data->inputmode_index] = 2;
+-              hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
++      if (r && hid_data->inputmode_field_index >= 0 &&
++          hid_data->inputmode_field_index < r->maxfield) {
++              struct hid_field *field = r->field[hid_data->inputmode_field_index];
++
++              if (field && hid_data->inputmode_index < field->report_count) {
++                      field->value[hid_data->inputmode_index] = 2;
++                      hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
++              }
+       }
+       return 0;
+ }
+@@ -2846,6 +2852,7 @@ static int wacom_probe(struct hid_device
+               return -ENODEV;
+       wacom_wac->hid_data.inputmode = -1;
++      wacom_wac->hid_data.inputmode_field_index = -1;
+       wacom_wac->mode_report = -1;
+       if (hid_is_usb(hdev)) {
+--- a/drivers/hid/wacom_wac.h
++++ b/drivers/hid/wacom_wac.h
+@@ -295,6 +295,7 @@ struct wacom_shared {
+ struct hid_data {
+       __s16 inputmode;        /* InputMode HID feature, -1 if non-existent */
+       __s16 inputmode_index;  /* InputMode HID feature index in the report */
++      __s16 inputmode_field_index; /* InputMode HID feature field index in the report */
+       bool sense_state;
+       bool inrange_state;
+       bool eraser;
diff --git a/queue-6.18/iommu-debugobjects-avoid-gcc-16.1-section-mismatch-warnings.patch b/queue-6.18/iommu-debugobjects-avoid-gcc-16.1-section-mismatch-warnings.patch
new file mode 100644 (file)
index 0000000..7a17765
--- /dev/null
@@ -0,0 +1,126 @@
+From 4c9ad387aa2d6785299722e54224d34764edaeb3 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Wed, 13 May 2026 16:53:54 +0200
+Subject: iommu, debugobjects: avoid gcc-16.1 section mismatch warnings
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 4c9ad387aa2d6785299722e54224d34764edaeb3 upstream.
+
+gcc-16 has gained some more advanced inter-procedual optimization
+techniques that enable it to inline the dummy_tlb_add_page() and
+dummy_tlb_flush() function pointers into a specialized version of
+__arm_v7s_unmap:
+
+WARNING: modpost: vmlinux: section mismatch in reference: __arm_v7s_unmap+0x2cc (section: .text) -> dummy_tlb_add_page (section: .init.text)
+ERROR: modpost: Section mismatches detected.
+
+>From what I can tell, the transformation is correct, as this is only
+called when __arm_v7s_unmap() is called from arm_v7s_do_selftests(),
+which is also __init. Since __arm_v7s_unmap() however is not __init,
+gcc cannot inline the inner function calls directly.
+
+In debug_objects_selftest(), the same thing happens. Both the
+caller and the leaf function are __init, but the IPA pulls
+it into a non-init one:
+
+WARNING: modpost: vmlinux: section mismatch in reference: lookup_object_or_alloc+0x7c (section: .text.lookup_object_or_alloc) -> is_static_object (section: .init.text)
+
+Marking the affected functions as not "__init" would reliably avoid this
+issue but is not a good solution because it removes an otherwise correct
+annotation. I tried marking the functions as 'noinline', but that ended
+up not covering all the affected configurations.
+
+With some more experimenting, I found that marking these functions as
+__attribute__((noipa)) is both logical and reliable.
+
+In order to keep the syntax readable, add a custom macro for this in
+include/linux/compiler_attributes.h next to other related macros and
+use it to annotate both files.
+
+Link: https://lore.kernel.org/all/abRB6g-48ZX6Yl2r@willie-the-truck/
+Cc: Will Deacon <will@kernel.org>
+Cc: Thomas Gleixner <tglx@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Miguel Ojeda <ojeda@kernel.org>
+Cc: linux-kbuild@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Will Deacon <will@kernel.org>
+Acked-by: Thomas Gleixner <tglx@kernel.org>
+Acked-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/io-pgtable-arm-v7s.c  |   18 ++++++++++++------
+ include/linux/compiler_attributes.h |   11 +++++++++++
+ lib/debugobjects.c                  |    2 +-
+ 3 files changed, 24 insertions(+), 7 deletions(-)
+
+--- a/drivers/iommu/io-pgtable-arm-v7s.c
++++ b/drivers/iommu/io-pgtable-arm-v7s.c
+@@ -777,21 +777,27 @@ struct io_pgtable_init_fns io_pgtable_ar
+ static struct io_pgtable_cfg *cfg_cookie __initdata;
+-static void __init dummy_tlb_flush_all(void *cookie)
++/*
++ * __noipa prevents gcc from turning indirect iommu_flush_ops calls
++ * into direct calls from a specialized __arm_v7s_unmap() that triggers
++ * a build time section mismatch assertion.
++ */
++static __noipa void __init dummy_tlb_flush_all(void *cookie)
+ {
+       WARN_ON(cookie != cfg_cookie);
+ }
+-static void __init dummy_tlb_flush(unsigned long iova, size_t size,
+-                                 size_t granule, void *cookie)
++static __noipa void __init dummy_tlb_flush(unsigned long iova, size_t size,
++                                         size_t granule, void *cookie)
+ {
+       WARN_ON(cookie != cfg_cookie);
+       WARN_ON(!(size & cfg_cookie->pgsize_bitmap));
+ }
+-static void __init dummy_tlb_add_page(struct iommu_iotlb_gather *gather,
+-                                    unsigned long iova, size_t granule,
+-                                    void *cookie)
++static __noipa void __init dummy_tlb_add_page(struct iommu_iotlb_gather *gather,
++                                            unsigned long iova,
++                                            size_t granule,
++                                            void *cookie)
+ {
+       dummy_tlb_flush(iova, granule, granule, cookie);
+ }
+--- a/include/linux/compiler_attributes.h
++++ b/include/linux/compiler_attributes.h
+@@ -397,6 +397,17 @@
+ #endif
+ /*
++ * Optional: not supported by clang
++ *
++ *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-noipa
++ */
++#if __has_attribute(noipa)
++# define __noipa __attribute__((noipa))
++#else
++# define __noipa
++#endif
++
++/*
+  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute
+  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute
+  */
+--- a/lib/debugobjects.c
++++ b/lib/debugobjects.c
+@@ -1212,7 +1212,7 @@ struct self_test {
+ static __initconst const struct debug_obj_descr descr_type_test;
+-static bool __init is_static_object(void *addr)
++static __noipa bool __init is_static_object(void *addr)
+ {
+       struct self_test *obj = addr;
diff --git a/queue-6.18/ip6-vti-use-ip6_tnl.net-in-vti6_changelink.patch b/queue-6.18/ip6-vti-use-ip6_tnl.net-in-vti6_changelink.patch
new file mode 100644 (file)
index 0000000..14e3b90
--- /dev/null
@@ -0,0 +1,76 @@
+From 11b326fb0a374f4654f9be22d0f0f7abd9f7d3fe Mon Sep 17 00:00:00 2001
+From: Kuniyuki Iwashima <kuniyu@google.com>
+Date: Thu, 21 May 2026 21:05:54 +0800
+Subject: ip6: vti: Use ip6_tnl.net in vti6_changelink().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+commit 11b326fb0a374f4654f9be22d0f0f7abd9f7d3fe upstream.
+
+ip netns add ns1
+ip netns add ns2
+ip -n ns1 link add vti6_test type vti6 remote ::1 local ::2 key 7
+ip -n ns1 link set vti6_test netns ns2
+ip -n ns2 link set vti6_test type vti6 remote ::3 local ::4 key 9
+ip netns del ns2
+ip netns del ns1
+[  132.495484] ------------[ cut here ]------------
+[  132.497609] kernel BUG at net/core/dev.c:12376!
+
+Commit 61220ab34948 ("vti6: Enable namespace changing") dropped
+NETIF_F_NETNS_LOCAL from vti6 devices. A vti6 tunnel can then
+move through IFLA_NET_NS_FD. After the move dev_net(dev) points
+at the new netns while t->net stays at the creation netns.
+
+vti6_changelink() and vti6_update() still use dev_net(dev) and
+dev_net(t->dev). They unlink from one per netns hash and relink
+into another. The creation netns is left with a stale entry.
+cleanup_net() of that netns later walks freed memory.
+
+Reachable from an unprivileged user namespace (unshare --user
+--map-root-user --net). Cross tenant scope on container hosts.
+
+Fixes: 61220ab34948 ("vti6: Enable namespace changing")
+Reported-by: Maoyi Xie <maoyi.xie@ntu.edu.sg>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Cc: stable@vger.kernel.org # v5.15+
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260521130555.3421684-2-maoyixie.tju@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_vti.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -722,10 +722,11 @@ vti6_tnl_change(struct ip6_tnl *t, const
+ static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p,
+                      bool keep_mtu)
+ {
+-      struct net *net = dev_net(t->dev);
+-      struct vti6_net *ip6n = net_generic(net, vti6_net_id);
++      struct net *net = t->net;
++      struct vti6_net *ip6n;
+       int err;
++      ip6n = net_generic(net, vti6_net_id);
+       vti6_tnl_unlink(ip6n, t);
+       synchronize_net();
+       err = vti6_tnl_change(t, p, keep_mtu);
+@@ -1038,11 +1039,12 @@ static int vti6_changelink(struct net_de
+                          struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
+ {
+-      struct ip6_tnl *t;
++      struct ip6_tnl *t = netdev_priv(dev);
++      struct net *net = t->net;
+       struct __ip6_tnl_parm p;
+-      struct net *net = dev_net(dev);
+-      struct vti6_net *ip6n = net_generic(net, vti6_net_id);
++      struct vti6_net *ip6n;
++      ip6n = net_generic(net, vti6_net_id);
+       if (dev == ip6n->fb_tnl_dev)
+               return -EINVAL;
diff --git a/queue-6.18/ip6-vti-use-ip6_tnl.net-in-vti6_siocdevprivate.patch b/queue-6.18/ip6-vti-use-ip6_tnl.net-in-vti6_siocdevprivate.patch
new file mode 100644 (file)
index 0000000..f10ca6a
--- /dev/null
@@ -0,0 +1,88 @@
+From 8b484efd5cb4eeef9021a661e198edc5349dacf6 Mon Sep 17 00:00:00 2001
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+Date: Thu, 21 May 2026 21:05:55 +0800
+Subject: ip6: vti: Use ip6_tnl.net in vti6_siocdevprivate().
+
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+
+commit 8b484efd5cb4eeef9021a661e198edc5349dacf6 upstream.
+
+After patch 1/2 in this series, vti6_update() unlinks and relinks
+the tunnel through t->net. vti6_siocdevprivate() still uses
+dev_net(dev) for the collision lookup. For a tunnel moved through
+IFLA_NET_NS_FD, dev_net(dev) is the new netns, not t->net.
+
+SIOCCHGTUNNEL on a migrated tunnel then runs:
+
+  net = dev_net(dev)                    /* migrated netns */
+  t   = vti6_locate(net, &p1, false)    /* misses target in t->net */
+  ...
+  t   = netdev_priv(dev)
+  vti6_update(t, &p1, false)            /* mutates t->net's hash */
+
+A caller in the migrated netns picks params that match a tunnel
+in the creation netns. The lookup in dev_net(dev) finds nothing.
+vti6_update() prepends the migrated tunnel at the head of the
+creation netns hash bucket for those params. Later lookups in
+the creation netns resolve to the migrated device. xfrm receive
+delivers the matched packets through a device the caller controls.
+
+Reachable from an unprivileged user namespace (unshare --user
+--map-root-user --net). Cross tenant scope on container hosts.
+
+Switch the SIOCCHGTUNNEL path on a non fallback device to use
+t->net for the lookup. The lookup now matches the netns
+vti6_update() operates on.
+
+Also add ns_capable(self->net->user_ns, CAP_NET_ADMIN) before
+the lookup. The check at the top of the case is against
+dev_net(dev)->user_ns, which after migration is the attacker's
+netns. A caller there can pick params absent from self->net,
+the lookup returns NULL, t becomes self, and vti6_update()
+inserts the device into the creation netns hash. The new check
+requires CAP_NET_ADMIN in the creation netns user_ns too.
+
+SIOCADDTUNNEL and SIOCCHGTUNNEL on the fallback device keep
+dev_net(dev), which equals init_net there.
+
+Fixes: 61220ab34948 ("vti6: Enable namespace changing")
+Suggested-by: Jakub Kicinski <kuba@kernel.org>
+Suggested-by: Xiao Liang <shaw.leon@gmail.com>
+Cc: stable@vger.kernel.org # v5.15+
+Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
+Link: https://patch.msgid.link/20260521130555.3421684-3-maoyixie.tju@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_vti.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -834,17 +834,24 @@ vti6_siocdevprivate(struct net_device *d
+               if (p.proto != IPPROTO_IPV6  && p.proto != 0)
+                       break;
+               vti6_parm_from_user(&p1, &p);
+-              t = vti6_locate(net, &p1, cmd == SIOCADDTUNNEL);
+               if (dev != ip6n->fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
++                      struct ip6_tnl *self = netdev_priv(dev);
++
++                      err = -EPERM;
++                      if (!ns_capable(self->net->user_ns, CAP_NET_ADMIN))
++                              break;
++                      t = vti6_locate(self->net, &p1, false);
+                       if (t) {
+                               if (t->dev != dev) {
+                                       err = -EEXIST;
+                                       break;
+                               }
+                       } else
+-                              t = netdev_priv(dev);
++                              t = self;
+                       err = vti6_update(t, &p1, false);
++              } else {
++                      t = vti6_locate(net, &p1, cmd == SIOCADDTUNNEL);
+               }
+               if (t) {
+                       err = 0;
diff --git a/queue-6.18/ipv6-exthdrs-refresh-nh-after-handling-hao-option.patch b/queue-6.18/ipv6-exthdrs-refresh-nh-after-handling-hao-option.patch
new file mode 100644 (file)
index 0000000..8729b27
--- /dev/null
@@ -0,0 +1,48 @@
+From f7b52afe3592eae66e160586b45a3f2242972c63 Mon Sep 17 00:00:00 2001
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+Date: Fri, 22 May 2026 17:42:26 +0800
+Subject: ipv6: exthdrs: refresh nh after handling HAO option
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+commit f7b52afe3592eae66e160586b45a3f2242972c63 upstream.
+
+ip6_parse_tlv() caches skb_network_header(skb) in nh while walking
+IPv6 TLVs.
+
+ipv6_dest_hao() may call pskb_expand_head() for a cloned skb, which can
+move the skb head and invalidate the cached network header pointer.
+Refresh nh after ipv6_dest_hao() returns so any trailing padding or TLVs
+are parsed from the current skb head.
+
+This matches the existing pattern used in ip6_parse_tlv() after helpers
+that can modify skb header storage.
+
+Fixes: a831f5bbc89a ("[IPV6] MIP6: Add inbound interface of home address option.")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Co-developed-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Justin Iurman <justin.iurman@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/7aba1debc2196189172499e5769802b026f8caf8.1779247873.git.zcliangcn@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/exthdrs.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -203,6 +203,8 @@ static bool ip6_parse_tlv(bool hopbyhop,
+                               case IPV6_TLV_HAO:
+                                       if (!ipv6_dest_hao(skb, off))
+                                               return false;
++
++                                      nh = skb_network_header(skb);
+                                       break;
+ #endif
+                               default:
diff --git a/queue-6.18/ipv6-exthdrs-refresh-nh-pointer-after-ipv6_hop_jumbo.patch b/queue-6.18/ipv6-exthdrs-refresh-nh-pointer-after-ipv6_hop_jumbo.patch
new file mode 100644 (file)
index 0000000..7c73288
--- /dev/null
@@ -0,0 +1,34 @@
+From d47548a36639095939f4747d4c43f2271366f565 Mon Sep 17 00:00:00 2001
+From: Justin Iurman <justin.iurman@gmail.com>
+Date: Fri, 22 May 2026 13:20:13 +0200
+Subject: ipv6: exthdrs: refresh nh pointer after ipv6_hop_jumbo()
+
+From: Justin Iurman <justin.iurman@gmail.com>
+
+commit d47548a36639095939f4747d4c43f2271366f565 upstream.
+
+ipv6_hop_jumbo() calls pskb_trim_rcsum(), which can change skb pointers.
+Let's recompute nh pointer to make sure any change won't mess things up.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Justin Iurman <justin.iurman@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260522112013.12342-1-justin.iurman@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/exthdrs.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -184,6 +184,8 @@ static bool ip6_parse_tlv(bool hopbyhop,
+                               case IPV6_TLV_JUMBO:
+                                       if (!ipv6_hop_jumbo(skb, off))
+                                               return false;
++
++                                      nh = skb_network_header(skb);
+                                       break;
+                               case IPV6_TLV_CALIPSO:
+                                       if (!ipv6_hop_calipso(skb, off))
diff --git a/queue-6.18/ipv6-validate-extension-header-length-before-copying-to-cmsg.patch b/queue-6.18/ipv6-validate-extension-header-length-before-copying-to-cmsg.patch
new file mode 100644 (file)
index 0000000..8c05466
--- /dev/null
@@ -0,0 +1,166 @@
+From dd433671fef381fdaf7b530c631e6b782d66e224 Mon Sep 17 00:00:00 2001
+From: Qi Tang <tpluszz77@gmail.com>
+Date: Sat, 23 May 2026 22:32:45 +0800
+Subject: ipv6: validate extension header length before copying to cmsg
+
+From: Qi Tang <tpluszz77@gmail.com>
+
+commit dd433671fef381fdaf7b530c631e6b782d66e224 upstream.
+
+ip6_datagram_recv_specific_ctl() builds IPV6_{HOPOPTS,DSTOPTS,RTHDR}
+cmsgs (and their IPV6_2292* legacy counterparts) by trusting the
+on-wire hdrlen byte (ptr[1]) when computing the put_cmsg() length.
+The length was validated only at parse time (ipv6_parse_hopopts(),
+etc.).  An nftables payload-write expression can rewrite hdrlen after
+parsing and before the skb reaches recvmsg; the write itself is
+in-bounds but put_cmsg() then reads up to ((hdrlen+1) << 3) = 2040
+bytes from an 8-byte header.  nftables is reachable from an
+unprivileged user namespace, so this is an unprivileged
+slab-out-of-bounds read:
+
+  BUG: KASAN: slab-out-of-bounds in put_cmsg+0x3ac/0x540
+   put_cmsg+0x3ac/0x540
+   udpv6_recvmsg+0xca0/0x1250
+   sock_recvmsg+0xdf/0x190
+   ____sys_recvmsg+0x1b1/0x620
+
+Add ipv6_get_exthdr_len() which validates that at least two bytes
+are accessible before reading the hdrlen field, then checks the
+computed length against skb_tail_pointer(skb), returning 0 on
+failure.  Extension headers are kept in the linear skb area by
+pskb_may_pull() during input, so skb_tail_pointer() is the correct
+bound.
+
+Use ipv6_get_exthdr_len() at all non-AH call sites: the five
+standalone cmsg blocks (HbH, 2292HbH, 2292DSTOPTS x2, 2292RTHDR)
+and the three standard cases in the extension-header walk loop
+(DSTOPTS, ROUTING, default).  AH retains an inline bounds check
+because its length formula differs ((ptr[1]+2)<<2).
+
+The walk loop also gets a pre-read bounds check at the top to
+validate ptr before any case accesses ptr[0] or ptr[1].
+
+When the walk loop detects a corrupted header, return from the
+function instead of continuing to process later socket options.
+
+Cc: stable@vger.kernel.org
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Qi Tang <tpluszz77@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260523143245.2281415-1-tpluszz77@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/datagram.c |   54 ++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 46 insertions(+), 8 deletions(-)
+
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -617,6 +617,18 @@ void ip6_datagram_recv_common_ctl(struct
+       }
+ }
++static u16 ipv6_get_exthdr_len(const struct sk_buff *skb, const u8 *ptr)
++{
++      u16 len;
++
++      if (ptr + 2 > skb_tail_pointer(skb))
++              return 0;
++
++      len = (ptr[1] + 1) << 3;
++
++      return (len <= skb_tail_pointer(skb) - ptr) ? len : 0;
++}
++
+ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
+                                   struct sk_buff *skb)
+ {
+@@ -643,7 +655,10 @@ void ip6_datagram_recv_specific_ctl(stru
+       /* HbH is allowed only once */
+       if (np->rxopt.bits.hopopts && (opt->flags & IP6SKB_HOPBYHOP)) {
+               u8 *ptr = nh + sizeof(struct ipv6hdr);
+-              put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
++              u16 len = ipv6_get_exthdr_len(skb, ptr);
++
++              if (len)
++                      put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, len, ptr);
+       }
+       if (opt->lastopt &&
+@@ -664,26 +679,37 @@ void ip6_datagram_recv_specific_ctl(stru
+                       unsigned int len;
+                       u8 *ptr = nh + off;
++                      if (ptr + 2 > skb_tail_pointer(skb))
++                              return;
++
+                       switch (nexthdr) {
+                       case IPPROTO_DSTOPTS:
+                               nexthdr = ptr[0];
+-                              len = (ptr[1] + 1) << 3;
++                              len = ipv6_get_exthdr_len(skb, ptr);
++                              if (!len)
++                                      return;
+                               if (np->rxopt.bits.dstopts)
+                                       put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, len, ptr);
+                               break;
+                       case IPPROTO_ROUTING:
+                               nexthdr = ptr[0];
+-                              len = (ptr[1] + 1) << 3;
++                              len = ipv6_get_exthdr_len(skb, ptr);
++                              if (!len)
++                                      return;
+                               if (np->rxopt.bits.srcrt)
+                                       put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, len, ptr);
+                               break;
+                       case IPPROTO_AH:
+                               nexthdr = ptr[0];
+                               len = (ptr[1] + 2) << 2;
++                              if (ptr + len > skb_tail_pointer(skb))
++                                      return;
+                               break;
+                       default:
+                               nexthdr = ptr[0];
+-                              len = (ptr[1] + 1) << 3;
++                              len = ipv6_get_exthdr_len(skb, ptr);
++                              if (!len)
++                                      return;
+                               break;
+                       }
+@@ -705,19 +731,31 @@ void ip6_datagram_recv_specific_ctl(stru
+       }
+       if (np->rxopt.bits.ohopopts && (opt->flags & IP6SKB_HOPBYHOP)) {
+               u8 *ptr = nh + sizeof(struct ipv6hdr);
+-              put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
++              u16 len = ipv6_get_exthdr_len(skb, ptr);
++
++              if (len)
++                      put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, len, ptr);
+       }
+       if (np->rxopt.bits.odstopts && opt->dst0) {
+               u8 *ptr = nh + opt->dst0;
+-              put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
++              u16 len = ipv6_get_exthdr_len(skb, ptr);
++
++              if (len)
++                      put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, len, ptr);
+       }
+       if (np->rxopt.bits.osrcrt && opt->srcrt) {
+               struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(nh + opt->srcrt);
+-              put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
++              u16 len = ipv6_get_exthdr_len(skb, (u8 *)rthdr);
++
++              if (len)
++                      put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, len, rthdr);
+       }
+       if (np->rxopt.bits.odstopts && opt->dst1) {
+               u8 *ptr = nh + opt->dst1;
+-              put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
++              u16 len = ipv6_get_exthdr_len(skb, ptr);
++
++              if (len)
++                      put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, len, ptr);
+       }
+       if (np->rxopt.bits.rxorigdstaddr) {
+               struct sockaddr_in6 sin6;
diff --git a/queue-6.18/l2tp-use-refcount_inc_not_zero-in-l2tp_session_get_by_ifname.patch b/queue-6.18/l2tp-use-refcount_inc_not_zero-in-l2tp_session_get_by_ifname.patch
new file mode 100644 (file)
index 0000000..446da3c
--- /dev/null
@@ -0,0 +1,73 @@
+From 05f95729ca844704d15e49ce14868af4b403b32b Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Fri, 22 May 2026 22:34:23 -0400
+Subject: l2tp: use refcount_inc_not_zero in l2tp_session_get_by_ifname
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 05f95729ca844704d15e49ce14868af4b403b32b upstream.
+
+A reader in l2tp_session_get_by_ifname() can return a pointer to a
+session whose refcount has reached zero. The getter takes its
+reference with plain refcount_inc(), but every other session getter
+in the same file (l2tp_v2_session_get, l2tp_v3_session_get, and the
+corresponding _get_next variants) uses refcount_inc_not_zero()
+because the IDR/RCU lookup can race with refcount_dec_and_test() ->
+l2tp_session_free() -> kfree_rcu(). The ifname getter is the only
+outlier; the inconsistency was raised on-list after 979c017803c4
+("l2tp: use list_del_rcu in l2tp_session_unhash").
+
+A reader inside rcu_read_lock_bh() that matches session->ifname can
+be preempted between the strcmp() and the refcount_inc(). If the
+last reference drops on another CPU in that window, the reader's
+refcount_inc() runs on a counter that has reached zero. refcount_t
+catches the addition-on-zero, prints "refcount_t: addition on 0;
+use-after-free", saturates the counter, and returns the saturated
+pointer to the caller. Session memory is held live by the in-flight
+RCU read section, but the kfree_rcu() callback queued from
+l2tp_session_free() will free it once the grace period closes; a
+caller that dereferences the returned session past that point hits
+a slab-use-after-free. On PREEMPT_RT local_bh_disable() is a per-CPU
+sleeping lock and the preemption window is real; on stock PREEMPT
+kernels local_bh_disable() is a preempt_count increment that closes
+the cross-CPU race in practice (see below).
+
+Use refcount_inc_not_zero() and continue the list walk on failure,
+matching the other session getters in the file. The ifname getter
+is the only session getter in net/l2tp/ that still uses the bare
+refcount_inc() pattern; this change restores file-internal
+consistency. The success path is unchanged.
+
+Fixes: abe7a1a7d0b6 ("l2tp: improve tunnel/session refcount helpers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Reviewed-by: James Chapman <jchapman@katalix.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260523023423.2568972-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/l2tp/l2tp_core.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -441,12 +441,13 @@ struct l2tp_session *l2tp_session_get_by
+       idr_for_each_entry_ul(&pn->l2tp_tunnel_idr, tunnel, tmp, tunnel_id) {
+               if (tunnel) {
+                       list_for_each_entry_rcu(session, &tunnel->session_list, list) {
+-                              if (!strcmp(session->ifname, ifname)) {
+-                                      refcount_inc(&session->ref_count);
+-                                      rcu_read_unlock_bh();
++                              if (strcmp(session->ifname, ifname))
++                                      continue;
++                              if (!refcount_inc_not_zero(&session->ref_count))
++                                      continue;
++                              rcu_read_unlock_bh();
+-                                      return session;
+-                              }
++                              return session;
+                       }
+               }
+       }
diff --git a/queue-6.18/macsec-fix-replay-protection-at-xpn-lower-pn-wrap.patch b/queue-6.18/macsec-fix-replay-protection-at-xpn-lower-pn-wrap.patch
new file mode 100644 (file)
index 0000000..53bbd66
--- /dev/null
@@ -0,0 +1,43 @@
+From e68842b3356471ba56c882209f324613dac47f64 Mon Sep 17 00:00:00 2001
+From: Junrui Luo <moonafterrain@outlook.com>
+Date: Wed, 20 May 2026 11:47:55 +0800
+Subject: macsec: fix replay protection at XPN lower-PN wrap
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+commit e68842b3356471ba56c882209f324613dac47f64 upstream.
+
+In macsec_post_decrypt(), when pn is U32_MAX, pn + 1 overflows u32 to 0
+and the first branch never fires. If next_pn_halves.lower is also in the
+upper half, pn_same_half(pn, lower) is true and the XPN else-if does not
+fire either, leaving next_pn_halves unchanged. An attacker that captures
+the legitimate frame carrying pn == 0xFFFFFFFF on an XPN association
+can then replay it indefinitely, since lowest_pn never rises above
+the captured pn and macsec_decrypt() reconstructs the same IV.
+
+Extend the XPN else-if to also fire when pn + 1 wraps to 0, so receipt
+of pn == U32_MAX advances next_pn_halves to (upper + 1, 0).
+
+Fixes: a21ecf0e0338 ("macsec: Support XPN frame handling - IEEE 802.1AEbw")
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Link: https://patch.msgid.link/SYBPR01MB78813FD49E58F253B989F197AF012@SYBPR01MB7881.ausprd01.prod.outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macsec.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -804,7 +804,8 @@ static bool macsec_post_decrypt(struct s
+               if (pn + 1 > rx_sa->next_pn_halves.lower) {
+                       rx_sa->next_pn_halves.lower = pn + 1;
+               } else if (secy->xpn &&
+-                         !pn_same_half(pn, rx_sa->next_pn_halves.lower)) {
++                         (pn + 1 == 0 ||
++                          !pn_same_half(pn, rx_sa->next_pn_halves.lower))) {
+                       rx_sa->next_pn_halves.upper++;
+                       rx_sa->next_pn_halves.lower = pn + 1;
+               }
diff --git a/queue-6.18/net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch b/queue-6.18/net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch
new file mode 100644 (file)
index 0000000..1808ccd
--- /dev/null
@@ -0,0 +1,88 @@
+From 98d0912e9f841e5529a5b89a972805f34cb1c69d Mon Sep 17 00:00:00 2001
+From: Minh Nguyen <minhnguyen.080505@gmail.com>
+Date: Tue, 26 May 2026 11:12:39 +0700
+Subject: net: skbuff: fix missing zerocopy reference in pskb_carve helpers
+
+From: Minh Nguyen <minhnguyen.080505@gmail.com>
+
+commit 98d0912e9f841e5529a5b89a972805f34cb1c69d upstream.
+
+pskb_carve_inside_header() and pskb_carve_inside_nonlinear() both copy
+the old skb_shared_info header into a new buffer via memcpy(), which
+includes the destructor_arg pointer (uarg) for MSG_ZEROCOPY skbs.
+Neither function calls net_zcopy_get() for the new shinfo, creating an
+unaccounted holder: every skb_shared_info with destructor_arg set will
+call skb_zcopy_clear() once when freed, but the corresponding
+net_zcopy_get() was never called for the new copy. Repeated calls
+drive uarg->refcnt to zero prematurely, freeing ubuf_info_msgzc while
+TX skbs still hold live destructor_arg pointers.
+
+KASAN reports use-after-free on a freed ubuf_info_msgzc:
+
+  BUG: KASAN: slab-use-after-free in skb_release_data+0x77b/0x810
+  Read of size 8 at addr ffff88801574d3e8 by task poc/220
+
+  Call Trace:
+   skb_release_data+0x77b/0x810
+   kfree_skb_list_reason+0x13e/0x610
+   skb_release_data+0x4cd/0x810
+   sk_skb_reason_drop+0xf3/0x340
+   skb_queue_purge_reason+0x282/0x440
+   rds_tcp_inc_free+0x1e/0x30
+   rds_recvmsg+0x354/0x1780
+   __sys_recvmsg+0xdf/0x180
+
+  Allocated by task 219:
+   msg_zerocopy_realloc+0x157/0x7b0
+   tcp_sendmsg_locked+0x2892/0x3ba0
+
+  Freed by task 219:
+   ip_recv_error+0x74a/0xb10
+   tcp_recvmsg+0x475/0x530
+
+The skb consuming the late access still referenced the same uarg via
+shinfo->destructor_arg copied by pskb_carve_inside_nonlinear() without
+a refcount bump. This has been verified to be reliably exploitable: a
+working proof-of-concept achieves full root privilege escalation from
+an unprivileged local user on a default kernel configuration.
+
+The fix follows the pattern of pskb_expand_head() which has the same
+memcpy/cloned structure. For pskb_carve_inside_header(), net_zcopy_get()
+is placed after skb_orphan_frags() succeeds, so the orphan error path
+needs no cleanup. For pskb_carve_inside_nonlinear(), net_zcopy_get() is
+placed after all failure points and just before skb_release_data(), so
+no error path needs cleanup at all -- matching pskb_expand_head() more
+closely and avoiding the need for a balancing net_zcopy_put().
+
+Fixes: 6fa01ccd8830 ("skbuff: Add pskb_extract() helper function")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-sonnet-4-6
+Signed-off-by: Minh Nguyen <minhnguyen.080505@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260526041240.329462-1-minhnguyen.080505@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/skbuff.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6787,6 +6787,8 @@ static int pskb_carve_inside_header(stru
+                       skb_kfree_head(data, size);
+                       return -ENOMEM;
+               }
++              if (skb_zcopy(skb))
++                      net_zcopy_get(skb_zcopy(skb));
+               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+                       skb_frag_ref(skb, i);
+               if (skb_has_frag_list(skb))
+@@ -6935,6 +6937,8 @@ static int pskb_carve_inside_nonlinear(s
+               skb_kfree_head(data, size);
+               return -ENOMEM;
+       }
++      if (skb_zcopy(skb))
++              net_zcopy_get(skb_zcopy(skb));
+       skb_release_data(skb, SKB_CONSUMED);
+       skb->head = data;
diff --git a/queue-6.18/netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-check.patch b/queue-6.18/netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-check.patch
new file mode 100644 (file)
index 0000000..ae3557d
--- /dev/null
@@ -0,0 +1,49 @@
+From bed6e04be8e6b9133d8b16d5a42d0e0ce674fa9a Mon Sep 17 00:00:00 2001
+From: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
+Date: Mon, 11 May 2026 10:43:14 -0400
+Subject: netfilter: conntrack: tcp: do not force CLOSE on invalid-seq RST without direction check
+
+From: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
+
+commit bed6e04be8e6b9133d8b16d5a42d0e0ce674fa9a upstream.
+
+An unintended behavior in the TCP conntrack state machine allows a
+connection to be forced into the CLOSE state using an RST packet with an
+invalid sequence number.
+
+Specifically, after a SYN packet is observed, an RST with an invalid SEQ
+can transition the conntrack entry to TCP_CONNTRACK_CLOSE, regardless of
+whether the RST corresponds to the expected reply direction. The relevant
+code path assumes the RST is a response to an outgoing SYN, but does not
+validate packet direction or ensure that a matching SYN was actually sent
+in the opposite direction.
+
+As a result, a crafted packet sequence consisting of a SYN followed by an
+invalid-sequence RST can prematurely terminate an active NAT entry. This
+makes connection teardown easier than intended.
+
+So, tighten the state transition logic to ensure that RST-triggered
+CLOSE transitions only occur when the RST is a valid response to a
+previously observed SYN in the correct direction.
+
+Cc: stable@vger.kernel.org
+Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.")
+Signed-off-by: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nf_conntrack_proto_tcp.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/netfilter/nf_conntrack_proto_tcp.c
++++ b/net/netfilter/nf_conntrack_proto_tcp.c
+@@ -1221,7 +1221,8 @@ int nf_conntrack_tcp_packet(struct nf_co
+                       new_state = old_state;
+               }
+               if (((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
+-                       && ct->proto.tcp.last_index == TCP_SYN_SET)
++                       && ct->proto.tcp.last_index == TCP_SYN_SET
++                       && ct->proto.tcp.last_dir != dir)
+                       || (!test_bit(IPS_ASSURED_BIT, &ct->status)
+                           && ct->proto.tcp.last_index == TCP_ACK_SET))
+                   && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
diff --git a/queue-6.18/nfc-hci-fix-out-of-bounds-read-in-hcp-header-parsing.patch b/queue-6.18/nfc-hci-fix-out-of-bounds-read-in-hcp-header-parsing.patch
new file mode 100644 (file)
index 0000000..1f81e0e
--- /dev/null
@@ -0,0 +1,89 @@
+From f040e590c035bfd9553fe79ee9585caf1b14d67b Mon Sep 17 00:00:00 2001
+From: Ashutosh Desai <ashutoshdesai993@gmail.com>
+Date: Tue, 5 May 2026 17:07:12 +0000
+Subject: nfc: hci: fix out-of-bounds read in HCP header parsing
+
+From: Ashutosh Desai <ashutoshdesai993@gmail.com>
+
+commit f040e590c035bfd9553fe79ee9585caf1b14d67b upstream.
+
+Both nfc_hci_recv_from_llc() and nci_hci_data_received_cb() read
+packet->header from skb->data at function entry without first checking
+that the buffer holds at least one byte. A malicious NFC peer can send
+a 0-byte HCP frame that passes through the SHDLC layer and reaches
+these functions, causing an out-of-bounds heap read of packet->header.
+The same 0-byte frame, if queued as a non-final fragment, also causes
+the reassembly loop to underflow msg_len to UINT_MAX, triggering
+skb_over_panic() when the reassembled skb is written.
+
+Fix this by adding a pskb_may_pull() check at the entry of each
+function before packet->header is first accessed. The existing
+pskb_may_pull() checks before the reassembled hcp_skb is cast to
+struct hcp_packet remain in place to guard the 2-byte HCP message
+header.
+
+Fixes: 8b8d2e08bf0d ("NFC: HCI support")
+Fixes: 11f54f228643 ("NFC: nci: Add HCI over NCI protocol support")
+Cc: stable@vger.kernel.org
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Ashutosh Desai <ashutoshdesai993@gmail.com>
+Link: https://patch.msgid.link/20260505170712.96560-1-ashutoshdesai993@gmail.com
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/nfc/hci/core.c |   10 ++++++++++
+ net/nfc/nci/hci.c  |   10 ++++++++++
+ 2 files changed, 20 insertions(+)
+
+--- a/net/nfc/hci/core.c
++++ b/net/nfc/hci/core.c
+@@ -861,6 +861,11 @@ static void nfc_hci_recv_from_llc(struct
+       struct sk_buff *frag_skb;
+       int msg_len;
++      if (!pskb_may_pull(skb, NFC_HCI_HCP_PACKET_HEADER_LEN)) {
++              kfree_skb(skb);
++              return;
++      }
++
+       packet = (struct hcp_packet *)skb->data;
+       if ((packet->header & ~NFC_HCI_FRAGMENT) == 0) {
+               skb_queue_tail(&hdev->rx_hcp_frags, skb);
+@@ -904,6 +909,11 @@ static void nfc_hci_recv_from_llc(struct
+        * unblock waiting cmd context. Otherwise, enqueue to dispatch
+        * in separate context where handler can also execute command.
+        */
++      if (!pskb_may_pull(hcp_skb, NFC_HCI_HCP_HEADER_LEN)) {
++              kfree_skb(hcp_skb);
++              return;
++      }
++
+       packet = (struct hcp_packet *)hcp_skb->data;
+       type = HCP_MSG_GET_TYPE(packet->message.header);
+       if (type == NFC_HCI_HCP_RESPONSE) {
+--- a/net/nfc/nci/hci.c
++++ b/net/nfc/nci/hci.c
+@@ -439,6 +439,11 @@ void nci_hci_data_received_cb(void *cont
+               return;
+       }
++      if (!pskb_may_pull(skb, NCI_HCI_HCP_PACKET_HEADER_LEN)) {
++              kfree_skb(skb);
++              return;
++      }
++
+       packet = (struct nci_hcp_packet *)skb->data;
+       if ((packet->header & ~NCI_HCI_FRAGMENT) == 0) {
+               skb_queue_tail(&ndev->hci_dev->rx_hcp_frags, skb);
+@@ -482,6 +487,11 @@ void nci_hci_data_received_cb(void *cont
+        * unblock waiting cmd context. Otherwise, enqueue to dispatch
+        * in separate context where handler can also execute command.
+        */
++      if (!pskb_may_pull(hcp_skb, NCI_HCI_HCP_HEADER_LEN)) {
++              kfree_skb(hcp_skb);
++              return;
++      }
++
+       packet = (struct nci_hcp_packet *)hcp_skb->data;
+       type = NCI_HCP_MSG_GET_TYPE(packet->message.header);
+       if (type == NCI_HCI_HCP_RESPONSE) {
index 31f118755cbf0b43a71b33fc00eac8bb0045aabe..110c3f9225ae5092eadadf75e5b55494fdf38eea 100644 (file)
@@ -181,3 +181,29 @@ usb-dwc2-fix-use-after-free-in-debug-code.patch
 input-elan_i2c-validate-firmware-size-before-use.patch
 i2c-davinci-fix-division-by-zero-on-missing-clock-frequency.patch
 x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch
+wireguard-send-append-trailer-after-expanding-head.patch
+bpf-sockmap-fix-tail-fragment-offset-in-bpf_msg_push_data.patch
+macsec-fix-replay-protection-at-xpn-lower-pn-wrap.patch
+ipv6-exthdrs-refresh-nh-pointer-after-ipv6_hop_jumbo.patch
+asoc-qcom-q6asm-dai-fix-error-handling-in-prepare-and-set_params.patch
+ipv6-exthdrs-refresh-nh-after-handling-hao-option.patch
+ip6-vti-use-ip6_tnl.net-in-vti6_siocdevprivate.patch
+ipv6-validate-extension-header-length-before-copying-to-cmsg.patch
+xfrm-input-hold-netns-during-deferred-transport-reinjection.patch
+l2tp-use-refcount_inc_not_zero-in-l2tp_session_get_by_ifname.patch
+ip6-vti-use-ip6_tnl.net-in-vti6_changelink.patch
+net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch
+spi-spi-mem-avoid-mutating-op-template-in-spi_mem_supports_op.patch
+hid-wacom-fix-oob-write-in-wacom_hid_set_device_mode.patch
+iommu-debugobjects-avoid-gcc-16.1-section-mismatch-warnings.patch
+nfc-hci-fix-out-of-bounds-read-in-hcp-header-parsing.patch
+xfrm-route-migrate-notifications-to-caller-s-netns.patch
+xfrm-ipcomp-free-destination-pages-on-acomp-errors.patch
+xfrm-ah-use-skb_to_full_sk-in-async-output-callbacks.patch
+alsa-scarlett2-fix-2i2-gen-4-direct-monitor-gain-on-firmware-2417.patch
+alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
+netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-check.patch
+asoc-qcom-q6asm-dai-close-stream-only-when-running.patch
+asoc-qcom-q6asm-dai-do-not-set-stream-state-in-event-and-trigger-callbacks.patch
+xfrm-esp-restore-combined-single-frag-length-gate.patch
+alsa-hda-realtek-fix-speaker-output-on-asus-rog-strix-g615lp.patch
diff --git a/queue-6.18/spi-spi-mem-avoid-mutating-op-template-in-spi_mem_supports_op.patch b/queue-6.18/spi-spi-mem-avoid-mutating-op-template-in-spi_mem_supports_op.patch
new file mode 100644 (file)
index 0000000..743a87f
--- /dev/null
@@ -0,0 +1,57 @@
+From 79378db6a86c7014cce40b65252e6c18f5b8bcc2 Mon Sep 17 00:00:00 2001
+From: Santhosh Kumar K <s-k6@ti.com>
+Date: Wed, 27 May 2026 23:07:36 +0530
+Subject: spi: spi-mem: avoid mutating op template in spi_mem_supports_op()
+
+From: Santhosh Kumar K <s-k6@ti.com>
+
+commit 79378db6a86c7014cce40b65252e6c18f5b8bcc2 upstream.
+
+spi_mem_supports_op() accepts a const struct spi_mem_op pointer but
+casts away const internally to call spi_mem_adjust_op_freq(). This
+mutates the caller's op template, which causes stale max_freq values
+when callers reuse persistent templates - subsequent calls won't
+re-apply the device frequency cap since spi_mem_adjust_op_freq()
+skips non-zero values.
+
+Fix by operating on a stack-local copy instead.
+
+Fixes: a4f8e70d75dd ("spi: spi-mem: add spi_mem_adjust_op_freq() in spi_mem_supports_op()")
+Cc: Tianyu Xu <xtydtc@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Santhosh Kumar K <s-k6@ti.com>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://patch.msgid.link/20260527173736.2243004-1-s-k6@ti.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-mem.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -276,13 +276,20 @@ static bool spi_mem_internal_supports_op
+  */
+ bool spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op)
+ {
+-      /* Make sure the operation frequency is correct before going futher */
+-      spi_mem_adjust_op_freq(mem, (struct spi_mem_op *)op);
++      struct spi_mem_op eval_op = *op;
+-      if (spi_mem_check_op(op))
++      /*
++       * Work on a local copy; this is a pure capability check and must
++       * not modify the caller's op. Stored templates with max_freq == 0
++       * must remain unset so their frequency is always re-capped to the
++       * current device maximum at execution time.
++       */
++      spi_mem_adjust_op_freq(mem, &eval_op);
++
++      if (spi_mem_check_op(&eval_op))
+               return false;
+-      return spi_mem_internal_supports_op(mem, op);
++      return spi_mem_internal_supports_op(mem, &eval_op);
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_supports_op);
diff --git a/queue-6.18/wireguard-send-append-trailer-after-expanding-head.patch b/queue-6.18/wireguard-send-append-trailer-after-expanding-head.patch
new file mode 100644 (file)
index 0000000..703c1fb
--- /dev/null
@@ -0,0 +1,61 @@
+From f75e3eb08fe31d30a9af6ed80cdd22e6772837e2 Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Fri, 29 May 2026 19:31:34 +0200
+Subject: wireguard: send: append trailer after expanding head
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+commit f75e3eb08fe31d30a9af6ed80cdd22e6772837e2 upstream.
+
+With how this is currently written, we add the trailer, zero it out, and
+then add the header space on. If that header space requires a
+reallocation + copy, the zeros in the trailer aren't copied, because the
+skb len hasn't actually been yet expanded to cover that. Instead add the
+padding at the end of the process rather than at the beginning.
+
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Link: https://patch.msgid.link/20260529173134.3080773-2-Jason@zx2c4.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireguard/send.c |   20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/wireguard/send.c
++++ b/drivers/net/wireguard/send.c
+@@ -177,16 +177,6 @@ static bool encrypt_packet(struct sk_buf
+       trailer_len = padding_len + noise_encrypted_len(0);
+       plaintext_len = skb->len + padding_len;
+-      /* Expand data section to have room for padding and auth tag. */
+-      num_frags = skb_cow_data(skb, trailer_len, &trailer);
+-      if (unlikely(num_frags < 0 || num_frags > ARRAY_SIZE(sg)))
+-              return false;
+-
+-      /* Set the padding to zeros, and make sure it and the auth tag are part
+-       * of the skb.
+-       */
+-      memset(skb_tail_pointer(trailer), 0, padding_len);
+-
+       /* Expand head section to have room for our header and the network
+        * stack's headers.
+        */
+@@ -198,6 +188,16 @@ static bool encrypt_packet(struct sk_buf
+                    skb_checksum_help(skb)))
+               return false;
++      /* Expand data section to have room for padding and auth tag. */
++      num_frags = skb_cow_data(skb, trailer_len, &trailer);
++      if (unlikely(num_frags < 0 || num_frags > ARRAY_SIZE(sg)))
++              return false;
++
++      /* Set the padding to zeros, and make sure it and the auth tag are part
++       * of the skb.
++       */
++      memset(skb_tail_pointer(trailer), 0, padding_len);
++
+       /* Only after checksumming can we safely add on the padding at the end
+        * and the header.
+        */
diff --git a/queue-6.18/xfrm-ah-use-skb_to_full_sk-in-async-output-callbacks.patch b/queue-6.18/xfrm-ah-use-skb_to_full_sk-in-async-output-callbacks.patch
new file mode 100644 (file)
index 0000000..a15cfb1
--- /dev/null
@@ -0,0 +1,86 @@
+From 79d8be262377f7112cfa3088dfc4142d5a2533f3 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Fri, 15 May 2026 11:45:31 -0400
+Subject: xfrm: ah: use skb_to_full_sk in async output callbacks
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 79d8be262377f7112cfa3088dfc4142d5a2533f3 upstream.
+
+When AH output is offloaded to an asynchronous crypto provider
+(hardware accelerators such as AMD CCP, or a forced-async software
+shim used for testing), the digest completion fires
+ah_output_done() / ah6_output_done() on a workqueue.  The egress
+skb at that point may have been originated by a TCP listener
+sending a SYN-ACK, which sets skb->sk to a request_sock via
+skb_set_owner_edemux(); it may also have been originated by an
+inet_timewait_sock retransmit.  Neither is a full struct sock, and
+passing the raw skb->sk to xfrm_output_resume() then forwards a
+non-full socket through the rest of the xfrm output chain.
+
+xfrm_output_resume() and its downstream consumers expect a full
+sk where they dereference at all.  The natural egress path
+through ah_output_done() does not crash today because the
+consumers that read past sock_common are either gated by
+sk_fullsock() or short-circuit on flags that are clear on a fresh
+request_sock; an exhaustive walk of the 50 most plausible
+consumers under sch_fq, dev_queue_xmit, netfilter, tc-egress and
+cgroup-egress BPF found no current unguarded deref.  The bug is
+still a real type confusion that future consumer changes could
+turn into a memory-corruption primitive.
+
+This is the same bug class fixed for ESP in commit 1620c88887b1
+("xfrm: Fix the usage of skb->sk").  Apply the analogous fix to
+AH: convert skb->sk to a full socket pointer (or NULL) via
+skb_to_full_sk() before handing it to xfrm_output_resume().
+
+The same async AH callbacks were touched recently for an
+independent ESN-related ICV layout bug in commit ec54093e6a8f
+("xfrm: ah: account for ESN high bits in async callbacks"); the
+sk type-confusion addressed here is orthogonal.  This patch is
+part of an ongoing audit of the AH callback paths; an ah_output
+ihl-validation hardening series is also currently under review on
+netdev.
+
+Reproduced under UML + KASAN + lockdep with a forced-async
+hmac(sha1) shim that registers at priority 9999 and wraps the
+sync in-tree hmac-sha1-lib.  With the shim loaded, ah_output_done
+runs on every SYN-ACK egress through a transport-mode AH SA and
+skb->sk arrives as a request_sock (TCP_NEW_SYN_RECV); after this
+patch, xfrm_output_resume() receives the listener (the result of
+sk_to_full_sk()) and consumer derefs land on full-sock fields as
+intended.
+
+Fixes: 9ab1265d5231 ("xfrm: Use actual socket sk instead of skb socket for xfrm_output_resume")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ah4.c |    2 +-
+ net/ipv6/ah6.c |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/ah4.c
++++ b/net/ipv4/ah4.c
+@@ -143,7 +143,7 @@ static void ah_output_done(void *data, i
+       }
+       kfree(AH_SKB_CB(skb)->tmp);
+-      xfrm_output_resume(skb->sk, skb, err);
++      xfrm_output_resume(skb_to_full_sk(skb), skb, err);
+ }
+ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
+--- a/net/ipv6/ah6.c
++++ b/net/ipv6/ah6.c
+@@ -337,7 +337,7 @@ static void ah6_output_done(void *data,
+       ah6_restore_hdrs(top_iph, iph_ext, extlen);
+       kfree(AH_SKB_CB(skb)->tmp);
+-      xfrm_output_resume(skb->sk, skb, err);
++      xfrm_output_resume(skb_to_full_sk(skb), skb, err);
+ }
+ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
diff --git a/queue-6.18/xfrm-esp-restore-combined-single-frag-length-gate.patch b/queue-6.18/xfrm-esp-restore-combined-single-frag-length-gate.patch
new file mode 100644 (file)
index 0000000..13af029
--- /dev/null
@@ -0,0 +1,60 @@
+From dfa0d7b0ff1eb6b2c416b8fdb9b4f2cefba57a40 Mon Sep 17 00:00:00 2001
+From: Jingguo Tan <tanjingguo@huawei.com>
+Date: Mon, 18 May 2026 17:06:48 +0800
+Subject: xfrm: esp: restore combined single-frag length gate
+
+From: Jingguo Tan <tanjingguo@huawei.com>
+
+commit dfa0d7b0ff1eb6b2c416b8fdb9b4f2cefba57a40 upstream.
+
+The ESP out-of-place fast path appends the trailer in esp_output_head()
+before esp_output_tail() allocates the destination page frag. The
+head-side gate currently checks skb->data_len and tailen separately, but
+the tail code allocates a single destination frag from the combined
+post-trailer skb->data_len.
+
+Reject the page-frag fast path when the combined aligned length exceeds a
+page. Otherwise skb_page_frag_refill() may fall back to a single page while
+the destination sg still spans the combined skb->data_len.
+
+Restore this combined-length page gate for both IPv4 and IPv6.
+
+Fixes: 5bd8baab087d ("esp: limit skb_page_frag_refill use to a single page")
+Cc: stable@vger.kernel.org
+Signed-off-by: Lin Ma <malin89@huawei.com>
+Signed-off-by: Chenyuan Mi <michenyuan@huawei.com>
+Signed-off-by: Jingguo Tan <tanjingguo@huawei.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/esp4.c |    4 ++--
+ net/ipv6/esp6.c |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -419,8 +419,8 @@ int esp_output_head(struct xfrm_state *x
+                       return err;
+       }
+-      if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE ||
+-          ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE)
++      if (ALIGN(skb->data_len + tailen, L1_CACHE_BYTES) >
++          PAGE_SIZE)
+               goto cow;
+       if (!skb_cloned(skb)) {
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -448,8 +448,8 @@ int esp6_output_head(struct xfrm_state *
+                       return err;
+       }
+-      if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE ||
+-          ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE)
++      if (ALIGN(skb->data_len + tailen, L1_CACHE_BYTES) >
++          PAGE_SIZE)
+               goto cow;
+       if (!skb_cloned(skb)) {
diff --git a/queue-6.18/xfrm-input-hold-netns-during-deferred-transport-reinjection.patch b/queue-6.18/xfrm-input-hold-netns-during-deferred-transport-reinjection.patch
new file mode 100644 (file)
index 0000000..0675b79
--- /dev/null
@@ -0,0 +1,75 @@
+From c16f74dc1d75d0e2e7670076d5375deda110ebeb Mon Sep 17 00:00:00 2001
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+Date: Fri, 22 May 2026 17:31:55 +0800
+Subject: xfrm: input: hold netns during deferred transport reinjection
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+commit c16f74dc1d75d0e2e7670076d5375deda110ebeb upstream.
+
+Transport-mode reinjection stores a struct net pointer in skb->cb and
+uses it later from xfrm_trans_reinject(). That pointer must stay valid
+until the deferred callback runs.
+
+Take a netns reference when queueing deferred reinjection work and drop
+it after the callback completes. Use maybe_get_net() so the queueing
+path does not revive a namespace that is already being torn down.
+
+This keeps the existing workqueue design and fixes the netns lifetime
+handling in one place for all users of xfrm_trans_queue_net().
+
+Fixes: 7b3801927e52 ("xfrm: introduce xfrm_trans_queue_net")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Co-developed-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Assisted-by: Codex:gpt-5.4
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_input.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -794,9 +794,12 @@ static void xfrm_trans_reinject(struct w
+       spin_unlock_bh(&trans->queue_lock);
+       local_bh_disable();
+-      while ((skb = __skb_dequeue(&queue)))
+-              XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
+-                                             NULL, skb);
++      while ((skb = __skb_dequeue(&queue))) {
++              struct net *net = XFRM_TRANS_SKB_CB(skb)->net;
++
++              XFRM_TRANS_SKB_CB(skb)->finish(net, NULL, skb);
++              put_net(net);
++      }
+       local_bh_enable();
+ }
+@@ -805,6 +808,7 @@ int xfrm_trans_queue_net(struct net *net
+                                      struct sk_buff *))
+ {
+       struct xfrm_trans_tasklet *trans;
++      struct net *hold_net;
+       trans = this_cpu_ptr(&xfrm_trans_tasklet);
+@@ -813,8 +817,12 @@ int xfrm_trans_queue_net(struct net *net
+       BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb));
++      hold_net = maybe_get_net(net);
++      if (!hold_net)
++              return -ENODEV;
++
+       XFRM_TRANS_SKB_CB(skb)->finish = finish;
+-      XFRM_TRANS_SKB_CB(skb)->net = net;
++      XFRM_TRANS_SKB_CB(skb)->net = hold_net;
+       spin_lock_bh(&trans->queue_lock);
+       __skb_queue_tail(&trans->queue, skb);
+       spin_unlock_bh(&trans->queue_lock);
diff --git a/queue-6.18/xfrm-ipcomp-free-destination-pages-on-acomp-errors.patch b/queue-6.18/xfrm-ipcomp-free-destination-pages-on-acomp-errors.patch
new file mode 100644 (file)
index 0000000..022f07e
--- /dev/null
@@ -0,0 +1,59 @@
+From 7dbac7680eb629b3b4dc7e98c34f943b8814c0c8 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Wed, 6 May 2026 21:23:28 +0800
+Subject: xfrm: ipcomp: Free destination pages on acomp errors
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit 7dbac7680eb629b3b4dc7e98c34f943b8814c0c8 upstream.
+
+Move the out_free_req label up by a couple of lines so that the
+allocated dst SG list gets freed on error as well as success.
+
+Fixes: eb2953d26971 ("xfrm: ipcomp: Use crypto_acomp interface")
+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>
+Reported-by: Yilin Zhu <zylzyl2333@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_ipcomp.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/net/xfrm/xfrm_ipcomp.c
++++ b/net/xfrm/xfrm_ipcomp.c
+@@ -51,11 +51,15 @@ static int ipcomp_post_acomp(struct sk_b
+       struct scatterlist *dsg;
+       int len, dlen;
+-      if (unlikely(err))
+-              goto out_free_req;
++      if (unlikely(!req))
++              return err;
+       extra = acomp_request_extra(req);
+       dsg = extra->sg;
++
++      if (unlikely(err))
++              goto out_free_req;
++
+       dlen = req->dlen;
+       pskb_trim_unique(skb, 0);
+@@ -84,10 +88,10 @@ static int ipcomp_post_acomp(struct sk_b
+               skb_shinfo(skb)->nr_frags++;
+       } while ((dlen -= len));
+-      for (; dsg; dsg = sg_next(dsg))
++out_free_req:
++      for (; dsg && sg_page(dsg); dsg = sg_next(dsg))
+               __free_page(sg_page(dsg));
+-out_free_req:
+       acomp_request_free(req);
+       return err;
+ }
diff --git a/queue-6.18/xfrm-route-migrate-notifications-to-caller-s-netns.patch b/queue-6.18/xfrm-route-migrate-notifications-to-caller-s-netns.patch
new file mode 100644 (file)
index 0000000..25b0b07
--- /dev/null
@@ -0,0 +1,161 @@
+From 7e2a4f7ca0952820731ef7bdadfc9a9e9d3571b4 Mon Sep 17 00:00:00 2001
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+Date: Mon, 4 May 2026 22:27:36 +0800
+Subject: xfrm: route MIGRATE notifications to caller's netns
+
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+
+commit 7e2a4f7ca0952820731ef7bdadfc9a9e9d3571b4 upstream.
+
+xfrm_send_migrate() in net/xfrm/xfrm_user.c and pfkey_send_migrate()
+in net/key/af_key.c both hardcode &init_net for the multicast that
+announces a successful XFRM_MSG_MIGRATE / SADB_X_MIGRATE.
+
+XFRM_MSG_MIGRATE arrives on a per-netns NETLINK_XFRM socket, and the
+rest of the xfrm/af_key netlink path was made netns-aware in 2008.
+The other 14 multicast paths in xfrm_user.c route their event using
+xs_net(x), xp_net(xp) or sock_net(skb->sk); only the migrate path
+was missed.
+
+Two consequences of the init_net hardcoding:
+
+  1. The notification (selector, old/new endpoint addresses, and the
+     km_address) is delivered to listeners on init_net's
+     XFRMNLGRP_MIGRATE / pfkey BROADCAST_ALL groups rather than on
+     the issuing netns. An IKE daemon running in init_net therefore
+     receives migration notifications originating from any other
+     netns on the host.
+
+  2. An IKE daemon running inside a non-init netns and subscribed
+     to its own XFRMNLGRP_MIGRATE / pfkey groups never receives the
+     notification of its own migration. IKEv2 MOBIKE / address-update
+     handling inside a netns is silently broken.
+
+Thread struct net through km_migrate() and the xfrm_mgr.migrate
+function pointer, drop the &init_net override in xfrm_send_migrate()
+and pfkey_send_migrate(), and pass the caller's net (already in
+scope in xfrm_migrate() via sock_net(skb->sk)) all the way down.
+struct xfrm_mgr is in-tree only and not exported as a stable API,
+so the function-pointer signature change is internal.
+
+pfkey_broadcast() is already netns-aware via net_generic(net,
+pfkey_net_id) since the pernet conversion. The five other
+pfkey_broadcast() callers in af_key.c already pass xs_net(x),
+sock_net(sk) or a per-netns net, so this only removes the
+&init_net outlier.
+
+Fixes: 5c79de6e79cd ("[XFRM]: User interface for handling XFRM_MSG_MIGRATE")
+Cc: stable@vger.kernel.org # v5.15+
+Signed-off-by: Maoyi Xie <maoyi.xie@ntu.edu.sg>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/xfrm.h     |    3 ++-
+ net/key/af_key.c       |    6 +++---
+ net/xfrm/xfrm_policy.c |    2 +-
+ net/xfrm/xfrm_state.c  |    4 ++--
+ net/xfrm/xfrm_user.c   |    5 ++---
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -715,6 +715,7 @@ struct xfrm_mgr {
+                                          const struct xfrm_migrate *m,
+                                          int num_bundles,
+                                          const struct xfrm_kmaddress *k,
++                                         struct net *net,
+                                          const struct xfrm_encap_tmpl *encap);
+       bool                    (*is_alive)(const struct km_event *c);
+ };
+@@ -1891,7 +1892,7 @@ int xfrm_sk_policy_insert(struct sock *s
+ #ifdef CONFIG_XFRM_MIGRATE
+ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
+              const struct xfrm_migrate *m, int num_bundles,
+-             const struct xfrm_kmaddress *k,
++             const struct xfrm_kmaddress *k, struct net *net,
+              const struct xfrm_encap_tmpl *encap);
+ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+                                               u32 if_id);
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -3564,7 +3564,7 @@ static int set_ipsecrequest(struct sk_bu
+ #ifdef CONFIG_NET_KEY_MIGRATE
+ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
+                             const struct xfrm_migrate *m, int num_bundles,
+-                            const struct xfrm_kmaddress *k,
++                            const struct xfrm_kmaddress *k, struct net *net,
+                             const struct xfrm_encap_tmpl *encap)
+ {
+       int i;
+@@ -3669,7 +3669,7 @@ static int pfkey_send_migrate(const stru
+       }
+       /* broadcast migrate message to sockets */
+-      pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net);
++      pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, net);
+       return 0;
+@@ -3680,7 +3680,7 @@ err:
+ #else
+ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
+                             const struct xfrm_migrate *m, int num_bundles,
+-                            const struct xfrm_kmaddress *k,
++                            const struct xfrm_kmaddress *k, struct net *net,
+                             const struct xfrm_encap_tmpl *encap)
+ {
+       return -ENOPROTOOPT;
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -4704,7 +4704,7 @@ int xfrm_migrate(const struct xfrm_selec
+       }
+       /* Stage 5 - announce */
+-      km_migrate(sel, dir, type, m, num_migrate, k, encap);
++      km_migrate(sel, dir, type, m, num_migrate, k, net, encap);
+       xfrm_pol_put(pol);
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2836,7 +2836,7 @@ EXPORT_SYMBOL(km_policy_expired);
+ #ifdef CONFIG_XFRM_MIGRATE
+ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
+              const struct xfrm_migrate *m, int num_migrate,
+-             const struct xfrm_kmaddress *k,
++             const struct xfrm_kmaddress *k, struct net *net,
+              const struct xfrm_encap_tmpl *encap)
+ {
+       int err = -EINVAL;
+@@ -2847,7 +2847,7 @@ int km_migrate(const struct xfrm_selecto
+       list_for_each_entry_rcu(km, &xfrm_km_list, list) {
+               if (km->migrate) {
+                       ret = km->migrate(sel, dir, type, m, num_migrate, k,
+-                                        encap);
++                                        net, encap);
+                       if (!ret)
+                               err = ret;
+               }
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -3262,10 +3262,9 @@ out_cancel:
+ static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
+                            const struct xfrm_migrate *m, int num_migrate,
+-                           const struct xfrm_kmaddress *k,
++                           const struct xfrm_kmaddress *k, struct net *net,
+                            const struct xfrm_encap_tmpl *encap)
+ {
+-      struct net *net = &init_net;
+       struct sk_buff *skb;
+       int err;
+@@ -3283,7 +3282,7 @@ static int xfrm_send_migrate(const struc
+ #else
+ static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
+                            const struct xfrm_migrate *m, int num_migrate,
+-                           const struct xfrm_kmaddress *k,
++                           const struct xfrm_kmaddress *k, struct net *net,
+                            const struct xfrm_encap_tmpl *encap)
+ {
+       return -ENOPROTOOPT;