]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees
authorSasha Levin <sashal@kernel.org>
Sat, 1 Aug 2026 01:39:44 +0000 (21:39 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 1 Aug 2026 01:39:44 +0000 (21:39 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
26 files changed:
staging-5.10/media-uvcvideo-fix-sequence-number-when-no-eof.patch [new file with mode: 0644]
staging-5.10/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch [new file with mode: 0644]
staging-5.10/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch [new file with mode: 0644]
staging-5.10/series [new file with mode: 0644]
staging-5.15/media-uvcvideo-fix-sequence-number-when-no-eof.patch [new file with mode: 0644]
staging-5.15/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch [new file with mode: 0644]
staging-5.15/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch [new file with mode: 0644]
staging-5.15/series [new file with mode: 0644]
staging-6.1/media-uvcvideo-fix-sequence-number-when-no-eof.patch [new file with mode: 0644]
staging-6.1/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch [new file with mode: 0644]
staging-6.1/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch [new file with mode: 0644]
staging-6.1/netfilter-br_netfilter-reallocate-headroom-if-necess.patch [new file with mode: 0644]
staging-6.1/series
staging-6.12/net-airoha-fix-register-index-for-tx-fwd-counter-con.patch [new file with mode: 0644]
staging-6.12/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch [new file with mode: 0644]
staging-6.12/netfilter-br_netfilter-reallocate-headroom-if-necess.patch [new file with mode: 0644]
staging-6.12/series
staging-6.18/drm-gpusvm-publish-dpagemap-early-to-avoid-device-ma.patch [new file with mode: 0644]
staging-6.18/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch [new file with mode: 0644]
staging-6.18/netfilter-br_netfilter-reallocate-headroom-if-necess.patch [new file with mode: 0644]
staging-6.18/series
staging-6.6/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch [new file with mode: 0644]
staging-6.6/netfilter-br_netfilter-reallocate-headroom-if-necess.patch [new file with mode: 0644]
staging-6.6/series
staging-7.1/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch [new file with mode: 0644]
staging-7.1/series [new file with mode: 0644]

diff --git a/staging-5.10/media-uvcvideo-fix-sequence-number-when-no-eof.patch b/staging-5.10/media-uvcvideo-fix-sequence-number-when-no-eof.patch
new file mode 100644 (file)
index 0000000..92f09dd
--- /dev/null
@@ -0,0 +1,157 @@
+From dea91bcd3205ee67f1b69217c6a8ea4c0c7f68a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 10:43:20 +0000
+Subject: media: uvcvideo: Fix sequence number when no EOF
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+commit f078966ca1fb1b3865d8e6bbe2705cfd277fc637 upstream.
+
+If the driver could not detect the EOF, the sequence number is increased
+twice:
+ 1) When we enter uvc_video_decode_start() with the old buffer and FID has
+   flipped => We return -EAGAIN and last_fid is not flipped
+ 2) When we enter uvc_video_decode_start() with the new buffer.
+
+Fix this issue by moving the new frame detection logic earlier in
+uvc_video_decode_start().
+
+This also has some nice side affects:
+
+- The error status from the new packet will no longer get propagated
+  to the previous frame-buffer.
+- uvc_video_clock_decode() will no longer update the previous frame
+  buf->stf with info from the new packet.
+- uvc_video_clock_decode() and uvc_video_stats_decode() will no longer
+  get called twice for the same packet.
+
+Cc: stable@kernel.org
+Fixes: 650b95feee35 ("[media] uvcvideo: Generate discontinuous sequence numbers when frames are lost")
+Reported-by: Hans de Goede <hansg@kernel.org>
+Closes: https://lore.kernel.org/linux-media/CANiDSCuj4cPuB5_v2xyvAagA5FjoN8V5scXiFFOeD3aKDMqkCg@mail.gmail.com/T/#me39fb134e8c2c085567a31548c3403eb639625e4
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_video.c | 94 ++++++++++++++++---------------
+ 1 file changed, 49 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index 7d462e346abd..909e158a017a 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -1093,7 +1093,55 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+       header_len = data[0];
+       fid = data[1] & UVC_STREAM_FID;
+-      /* Increase the sequence number regardless of any buffer states, so
++      /*
++       * Mark the buffer as done if we're at the beginning of a new frame.
++       * End of frame detection is better implemented by checking the EOF
++       * bit (FID bit toggling is delayed by one frame compared to the EOF
++       * bit), but some devices don't set the bit at end of frame (and the
++       * last payload can be lost anyway). We thus must check if the FID has
++       * been toggled.
++       *
++       * stream->last_fid is initialized to -1, and buf->bytesused to 0,
++       * so the first isochronous frame will never trigger an end of frame
++       * detection.
++       *
++       * Empty buffers (bytesused == 0) don't trigger end of frame detection
++       * as it doesn't make sense to return an empty buffer. This also
++       * avoids detecting end of frame conditions at FID toggling if the
++       * previous payload had the EOF bit set.
++       */
++      if (fid != stream->last_fid && buf && buf->bytesused != 0) {
++              uvc_trace(UVC_TRACE_FRAME,
++                        "Frame complete (FID bit toggled)\n");
++              buf->state = UVC_BUF_STATE_READY;
++
++              return -EAGAIN;
++      }
++
++      /*
++       * Some cameras, when running two parallel streams (one MJPEG alongside
++       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
++       * We can detect the end of a frame by checking for a new SOI marker, as
++       * the SOI always lies on the packet boundary between two frames for
++       * these devices.
++       */
++      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
++          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
++           stream->cur_format->fcc == V4L2_PIX_FMT_JPEG) &&
++          buf && buf->bytesused != 0) {
++              const u8 *packet = data + header_len;
++
++              if (len >= header_len + 2 &&
++                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI) {
++                      buf->state = UVC_BUF_STATE_READY;
++                      buf->error = 1;
++                      stream->last_fid ^= UVC_STREAM_FID;
++                      return -EAGAIN;
++              }
++      }
++
++      /*
++       * Increase the sequence number regardless of any buffer states, so
+        * that discontinuous sequence numbers always indicate lost frames.
+        */
+       if (stream->last_fid != fid) {
+@@ -1157,50 +1205,6 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+                       meta_buf->state = UVC_BUF_STATE_ACTIVE;
+       }
+-      /* Mark the buffer as done if we're at the beginning of a new frame.
+-       * End of frame detection is better implemented by checking the EOF
+-       * bit (FID bit toggling is delayed by one frame compared to the EOF
+-       * bit), but some devices don't set the bit at end of frame (and the
+-       * last payload can be lost anyway). We thus must check if the FID has
+-       * been toggled.
+-       *
+-       * stream->last_fid is initialized to -1, so the first isochronous
+-       * frame will never trigger an end of frame detection.
+-       *
+-       * Empty buffers (bytesused == 0) don't trigger end of frame detection
+-       * as it doesn't make sense to return an empty buffer. This also
+-       * avoids detecting end of frame conditions at FID toggling if the
+-       * previous payload had the EOF bit set.
+-       */
+-      if (fid != stream->last_fid && buf->bytesused != 0) {
+-              uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
+-                              "toggled).\n");
+-              buf->state = UVC_BUF_STATE_READY;
+-              return -EAGAIN;
+-      }
+-
+-      /*
+-       * Some cameras, when running two parallel streams (one MJPEG alongside
+-       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
+-       * We can detect the end of a frame by checking for a new SOI marker, as
+-       * the SOI always lies on the packet boundary between two frames for
+-       * these devices.
+-       */
+-      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
+-          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
+-          stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) {
+-              const u8 *packet = data + header_len;
+-
+-              if (len >= header_len + 2 &&
+-                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI &&
+-                  buf->bytesused != 0) {
+-                      buf->state = UVC_BUF_STATE_READY;
+-                      buf->error = 1;
+-                      stream->last_fid ^= UVC_STREAM_FID;
+-                      return -EAGAIN;
+-              }
+-      }
+-
+       stream->last_fid = fid;
+       return header_len;
+-- 
+2.53.0
+
diff --git a/staging-5.10/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch b/staging-5.10/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
new file mode 100644 (file)
index 0000000..d13ee63
--- /dev/null
@@ -0,0 +1,112 @@
+From 4d8e565ccc3264f67b21b575764713cd4d330391 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 10:43:19 +0000
+Subject: media: uvcvideo: Implement dual stream quirk to fix loss of usb
+ packets
+
+From: Isaac Scott <isaac.scott@ideasonboard.com>
+
+commit c2eda35e675b6ea4a0a21a4b1167b121571a9036 upstream.
+
+Some cameras, such as the Sonix Technology Co. 292A, exhibit issues when
+running two parallel streams, causing USB packets to be dropped when an
+H.264 stream posts a keyframe while an MJPEG stream is running
+simultaneously. This occasionally causes the driver to erroneously
+output two consecutive JPEG images as a single frame.
+
+To fix this, we inspect the buffer, and trigger a new frame when we
+find an SOI.
+
+Signed-off-by: Isaac Scott <isaac.scott@ideasonboard.com>
+Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
+Link: https://lore.kernel.org/r/20241128145144.61475-2-isaac.scott@ideasonboard.com
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+[Added JPEG_MARKER_SOI definition, jpeg header does not exist yet]
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_video.c | 28 +++++++++++++++++++++++++++-
+ drivers/media/usb/uvc/uvcvideo.h  |  4 ++++
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index 1a8a89aa0c5c..7d462e346abd 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -21,6 +21,8 @@
+ #include "uvcvideo.h"
++#define JPEG_MARKER_SOI                0xd8
++
+ /* ------------------------------------------------------------------------
+  * UVC Controls
+  */
+@@ -1075,6 +1077,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+                                 struct uvc_buffer *meta_buf,
+                                 const u8 *data, int len)
+ {
++      u8 header_len;
+       u8 fid;
+       /* Sanity checks:
+@@ -1087,6 +1090,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+               return -EINVAL;
+       }
++      header_len = data[0];
+       fid = data[1] & UVC_STREAM_FID;
+       /* Increase the sequence number regardless of any buffer states, so
+@@ -1175,9 +1179,31 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+               return -EAGAIN;
+       }
++      /*
++       * Some cameras, when running two parallel streams (one MJPEG alongside
++       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
++       * We can detect the end of a frame by checking for a new SOI marker, as
++       * the SOI always lies on the packet boundary between two frames for
++       * these devices.
++       */
++      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
++          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
++          stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) {
++              const u8 *packet = data + header_len;
++
++              if (len >= header_len + 2 &&
++                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI &&
++                  buf->bytesused != 0) {
++                      buf->state = UVC_BUF_STATE_READY;
++                      buf->error = 1;
++                      stream->last_fid ^= UVC_STREAM_FID;
++                      return -EAGAIN;
++              }
++      }
++
+       stream->last_fid = fid;
+-      return data[0];
++      return header_len;
+ }
+ /*
+diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
+index a83995276170..4a1ff08453d7 100644
+--- a/drivers/media/usb/uvc/uvcvideo.h
++++ b/drivers/media/usb/uvc/uvcvideo.h
+@@ -204,6 +204,10 @@
+ #define UVC_QUIRK_FORCE_Y8            0x00000800
+ #define UVC_QUIRK_FORCE_BPP           0x00001000
+ #define UVC_QUIRK_WAKE_AUTOSUSPEND    0x00002000
++#define UVC_QUIRK_NO_RESET_RESUME     0x00004000
++#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000
++#define UVC_QUIRK_INVALID_DEVICE_SOF  0x00010000
++#define UVC_QUIRK_MJPEG_NO_EOF                0x00020000
+ /* Format flags */
+ #define UVC_FMT_FLAG_COMPRESSED               0x00000001
+-- 
+2.53.0
+
diff --git a/staging-5.10/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch b/staging-5.10/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
new file mode 100644 (file)
index 0000000..5afca81
--- /dev/null
@@ -0,0 +1,74 @@
+From 006dbf7b421df18e7ca652dc22b48de48c0a5dee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2026 10:08:29 +0900
+Subject: net: mpls: initialize rtm_tos in mpls_getroute()
+
+From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+
+[ Upstream commit 295dd295e2137e10e9a5b1891d97e0f08de76f03 ]
+
+mpls_getroute() builds the RTM_NEWROUTE reply to an RTM_GETROUTE
+request by filling a struct rtmsg allocated from an skb whose data
+area is not zeroed (alloc_skb(NLMSG_GOODSIZE, ...)). It sets every
+field of the header except rtm_tos:
+
+       r = nlmsg_data(nlh);
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+       r->rtm_protocol = rt->rt_protocol;
+       r->rtm_flags    = 0;
+
+struct rtmsg has no padding, so the one uninitialised byte rtm_tos
+(offset 3) is copied straight to user space on recvmsg(), leaking a
+byte of uninitialised heap memory. This is in contrast to
+mpls_dump_route(), which fills the very same header and does set
+rtm_tos = 0.
+
+Initialize rtm_tos to 0, matching mpls_dump_route().
+
+Reproduced with KMSAN by adding an MPLS route and issuing a
+non-RTM_F_FIB_MATCH RTM_GETROUTE for its label:
+
+  BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x36c/0x33f0
+   _copy_to_iter+0x36c/0x33f0
+   __skb_datagram_iter+0x196/0x12c0
+   skb_copy_datagram_iter+0x5b/0x210
+   netlink_recvmsg+0x37b/0xef0
+   ...
+  Uninit was created at:
+   __alloc_skb+0x8ca/0x10e0
+   mpls_getroute+0x1280/0x3a40
+   rtnetlink_rcv_msg+0x1138/0x15a0
+   ...
+  Byte 19 of 64 is uninitialized
+
+(byte 19 = nlmsghdr(16) + rtmsg offset 3 = rtm_tos)
+
+Fixes: 397fc9e5cefe ("mpls: route get support")
+Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+Link: https://patch.msgid.link/20260723010830.289917-1-yhlee@isslab.korea.ac.kr
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 66f498667ed8..5c80fb93bb7a 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2492,6 +2492,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
++      r->rtm_tos      = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+-- 
+2.53.0
+
diff --git a/staging-5.10/series b/staging-5.10/series
new file mode 100644 (file)
index 0000000..a83ad16
--- /dev/null
@@ -0,0 +1,3 @@
+net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
+media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
+media-uvcvideo-fix-sequence-number-when-no-eof.patch
diff --git a/staging-5.15/media-uvcvideo-fix-sequence-number-when-no-eof.patch b/staging-5.15/media-uvcvideo-fix-sequence-number-when-no-eof.patch
new file mode 100644 (file)
index 0000000..5201c59
--- /dev/null
@@ -0,0 +1,157 @@
+From b60af3c20395afe4a364be38a954cb89a625a2e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 10:48:33 +0000
+Subject: media: uvcvideo: Fix sequence number when no EOF
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+commit f078966ca1fb1b3865d8e6bbe2705cfd277fc637 upstream.
+
+If the driver could not detect the EOF, the sequence number is increased
+twice:
+ 1) When we enter uvc_video_decode_start() with the old buffer and FID has
+   flipped => We return -EAGAIN and last_fid is not flipped
+ 2) When we enter uvc_video_decode_start() with the new buffer.
+
+Fix this issue by moving the new frame detection logic earlier in
+uvc_video_decode_start().
+
+This also has some nice side affects:
+
+- The error status from the new packet will no longer get propagated
+  to the previous frame-buffer.
+- uvc_video_clock_decode() will no longer update the previous frame
+  buf->stf with info from the new packet.
+- uvc_video_clock_decode() and uvc_video_stats_decode() will no longer
+  get called twice for the same packet.
+
+Cc: stable@kernel.org
+Fixes: 650b95feee35 ("[media] uvcvideo: Generate discontinuous sequence numbers when frames are lost")
+Reported-by: Hans de Goede <hansg@kernel.org>
+Closes: https://lore.kernel.org/linux-media/CANiDSCuj4cPuB5_v2xyvAagA5FjoN8V5scXiFFOeD3aKDMqkCg@mail.gmail.com/T/#me39fb134e8c2c085567a31548c3403eb639625e4
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_video.c | 94 ++++++++++++++++---------------
+ 1 file changed, 49 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index 2a2c10daa07a..d0415ebe54d0 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -1095,7 +1095,55 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+       header_len = data[0];
+       fid = data[1] & UVC_STREAM_FID;
+-      /* Increase the sequence number regardless of any buffer states, so
++      /*
++       * Mark the buffer as done if we're at the beginning of a new frame.
++       * End of frame detection is better implemented by checking the EOF
++       * bit (FID bit toggling is delayed by one frame compared to the EOF
++       * bit), but some devices don't set the bit at end of frame (and the
++       * last payload can be lost anyway). We thus must check if the FID has
++       * been toggled.
++       *
++       * stream->last_fid is initialized to -1, and buf->bytesused to 0,
++       * so the first isochronous frame will never trigger an end of frame
++       * detection.
++       *
++       * Empty buffers (bytesused == 0) don't trigger end of frame detection
++       * as it doesn't make sense to return an empty buffer. This also
++       * avoids detecting end of frame conditions at FID toggling if the
++       * previous payload had the EOF bit set.
++       */
++      if (fid != stream->last_fid && buf && buf->bytesused != 0) {
++              uvc_dbg(stream->dev, FRAME,
++                      "Frame complete (FID bit toggled)\n");
++              buf->state = UVC_BUF_STATE_READY;
++
++              return -EAGAIN;
++      }
++
++      /*
++       * Some cameras, when running two parallel streams (one MJPEG alongside
++       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
++       * We can detect the end of a frame by checking for a new SOI marker, as
++       * the SOI always lies on the packet boundary between two frames for
++       * these devices.
++       */
++      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
++          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
++           stream->cur_format->fcc == V4L2_PIX_FMT_JPEG) &&
++          buf && buf->bytesused != 0) {
++              const u8 *packet = data + header_len;
++
++              if (len >= header_len + 2 &&
++                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI) {
++                      buf->state = UVC_BUF_STATE_READY;
++                      buf->error = 1;
++                      stream->last_fid ^= UVC_STREAM_FID;
++                      return -EAGAIN;
++              }
++      }
++
++      /*
++       * Increase the sequence number regardless of any buffer states, so
+        * that discontinuous sequence numbers always indicate lost frames.
+        */
+       if (stream->last_fid != fid) {
+@@ -1159,50 +1207,6 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+                       meta_buf->state = UVC_BUF_STATE_ACTIVE;
+       }
+-      /* Mark the buffer as done if we're at the beginning of a new frame.
+-       * End of frame detection is better implemented by checking the EOF
+-       * bit (FID bit toggling is delayed by one frame compared to the EOF
+-       * bit), but some devices don't set the bit at end of frame (and the
+-       * last payload can be lost anyway). We thus must check if the FID has
+-       * been toggled.
+-       *
+-       * stream->last_fid is initialized to -1, so the first isochronous
+-       * frame will never trigger an end of frame detection.
+-       *
+-       * Empty buffers (bytesused == 0) don't trigger end of frame detection
+-       * as it doesn't make sense to return an empty buffer. This also
+-       * avoids detecting end of frame conditions at FID toggling if the
+-       * previous payload had the EOF bit set.
+-       */
+-      if (fid != stream->last_fid && buf->bytesused != 0) {
+-              uvc_dbg(stream->dev, FRAME,
+-                      "Frame complete (FID bit toggled)\n");
+-              buf->state = UVC_BUF_STATE_READY;
+-              return -EAGAIN;
+-      }
+-
+-      /*
+-       * Some cameras, when running two parallel streams (one MJPEG alongside
+-       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
+-       * We can detect the end of a frame by checking for a new SOI marker, as
+-       * the SOI always lies on the packet boundary between two frames for
+-       * these devices.
+-       */
+-      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
+-          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
+-          stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) {
+-              const u8 *packet = data + header_len;
+-
+-              if (len >= header_len + 2 &&
+-                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI &&
+-                  buf->bytesused != 0) {
+-                      buf->state = UVC_BUF_STATE_READY;
+-                      buf->error = 1;
+-                      stream->last_fid ^= UVC_STREAM_FID;
+-                      return -EAGAIN;
+-              }
+-      }
+-
+       stream->last_fid = fid;
+       return header_len;
+-- 
+2.53.0
+
diff --git a/staging-5.15/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch b/staging-5.15/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
new file mode 100644 (file)
index 0000000..30b8fc1
--- /dev/null
@@ -0,0 +1,112 @@
+From 0c5a192d9c2389203f6f1e951c11829d9c2129f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 10:48:32 +0000
+Subject: media: uvcvideo: Implement dual stream quirk to fix loss of usb
+ packets
+
+From: Isaac Scott <isaac.scott@ideasonboard.com>
+
+commit c2eda35e675b6ea4a0a21a4b1167b121571a9036 upstream.
+
+Some cameras, such as the Sonix Technology Co. 292A, exhibit issues when
+running two parallel streams, causing USB packets to be dropped when an
+H.264 stream posts a keyframe while an MJPEG stream is running
+simultaneously. This occasionally causes the driver to erroneously
+output two consecutive JPEG images as a single frame.
+
+To fix this, we inspect the buffer, and trigger a new frame when we
+find an SOI.
+
+Signed-off-by: Isaac Scott <isaac.scott@ideasonboard.com>
+Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
+Link: https://lore.kernel.org/r/20241128145144.61475-2-isaac.scott@ideasonboard.com
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+[Added JPEG_MARKER_SOI definition, jpeg header does not exist yet]
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_video.c | 28 +++++++++++++++++++++++++++-
+ drivers/media/usb/uvc/uvcvideo.h  |  4 ++++
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index 3184308e6896..2a2c10daa07a 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -24,6 +24,8 @@
+ #include "uvcvideo.h"
++#define JPEG_MARKER_SOI                0xd8
++
+ /* ------------------------------------------------------------------------
+  * UVC Controls
+  */
+@@ -1077,6 +1079,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+                                 struct uvc_buffer *meta_buf,
+                                 const u8 *data, int len)
+ {
++      u8 header_len;
+       u8 fid;
+       /* Sanity checks:
+@@ -1089,6 +1092,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+               return -EINVAL;
+       }
++      header_len = data[0];
+       fid = data[1] & UVC_STREAM_FID;
+       /* Increase the sequence number regardless of any buffer states, so
+@@ -1177,9 +1181,31 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+               return -EAGAIN;
+       }
++      /*
++       * Some cameras, when running two parallel streams (one MJPEG alongside
++       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
++       * We can detect the end of a frame by checking for a new SOI marker, as
++       * the SOI always lies on the packet boundary between two frames for
++       * these devices.
++       */
++      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
++          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
++          stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) {
++              const u8 *packet = data + header_len;
++
++              if (len >= header_len + 2 &&
++                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI &&
++                  buf->bytesused != 0) {
++                      buf->state = UVC_BUF_STATE_READY;
++                      buf->error = 1;
++                      stream->last_fid ^= UVC_STREAM_FID;
++                      return -EAGAIN;
++              }
++      }
++
+       stream->last_fid = fid;
+-      return data[0];
++      return header_len;
+ }
+ static inline enum dma_data_direction uvc_stream_dir(
+diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
+index be4b746d902c..2dd8d04589ab 100644
+--- a/drivers/media/usb/uvc/uvcvideo.h
++++ b/drivers/media/usb/uvc/uvcvideo.h
+@@ -212,6 +212,10 @@
+ #define UVC_QUIRK_FORCE_Y8            0x00000800
+ #define UVC_QUIRK_FORCE_BPP           0x00001000
+ #define UVC_QUIRK_WAKE_AUTOSUSPEND    0x00002000
++#define UVC_QUIRK_NO_RESET_RESUME     0x00004000
++#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000
++#define UVC_QUIRK_INVALID_DEVICE_SOF  0x00010000
++#define UVC_QUIRK_MJPEG_NO_EOF                0x00020000
+ /* Format flags */
+ #define UVC_FMT_FLAG_COMPRESSED               0x00000001
+-- 
+2.53.0
+
diff --git a/staging-5.15/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch b/staging-5.15/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
new file mode 100644 (file)
index 0000000..67e5369
--- /dev/null
@@ -0,0 +1,74 @@
+From 4044c7986bb3746f4f1b05bbda25088e0fdb8343 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2026 10:08:29 +0900
+Subject: net: mpls: initialize rtm_tos in mpls_getroute()
+
+From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+
+[ Upstream commit 295dd295e2137e10e9a5b1891d97e0f08de76f03 ]
+
+mpls_getroute() builds the RTM_NEWROUTE reply to an RTM_GETROUTE
+request by filling a struct rtmsg allocated from an skb whose data
+area is not zeroed (alloc_skb(NLMSG_GOODSIZE, ...)). It sets every
+field of the header except rtm_tos:
+
+       r = nlmsg_data(nlh);
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+       r->rtm_protocol = rt->rt_protocol;
+       r->rtm_flags    = 0;
+
+struct rtmsg has no padding, so the one uninitialised byte rtm_tos
+(offset 3) is copied straight to user space on recvmsg(), leaking a
+byte of uninitialised heap memory. This is in contrast to
+mpls_dump_route(), which fills the very same header and does set
+rtm_tos = 0.
+
+Initialize rtm_tos to 0, matching mpls_dump_route().
+
+Reproduced with KMSAN by adding an MPLS route and issuing a
+non-RTM_F_FIB_MATCH RTM_GETROUTE for its label:
+
+  BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x36c/0x33f0
+   _copy_to_iter+0x36c/0x33f0
+   __skb_datagram_iter+0x196/0x12c0
+   skb_copy_datagram_iter+0x5b/0x210
+   netlink_recvmsg+0x37b/0xef0
+   ...
+  Uninit was created at:
+   __alloc_skb+0x8ca/0x10e0
+   mpls_getroute+0x1280/0x3a40
+   rtnetlink_rcv_msg+0x1138/0x15a0
+   ...
+  Byte 19 of 64 is uninitialized
+
+(byte 19 = nlmsghdr(16) + rtmsg offset 3 = rtm_tos)
+
+Fixes: 397fc9e5cefe ("mpls: route get support")
+Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+Link: https://patch.msgid.link/20260723010830.289917-1-yhlee@isslab.korea.ac.kr
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index bd84c9ddb006..d77e028aed23 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2495,6 +2495,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
++      r->rtm_tos      = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+-- 
+2.53.0
+
diff --git a/staging-5.15/series b/staging-5.15/series
new file mode 100644 (file)
index 0000000..a83ad16
--- /dev/null
@@ -0,0 +1,3 @@
+net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
+media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
+media-uvcvideo-fix-sequence-number-when-no-eof.patch
diff --git a/staging-6.1/media-uvcvideo-fix-sequence-number-when-no-eof.patch b/staging-6.1/media-uvcvideo-fix-sequence-number-when-no-eof.patch
new file mode 100644 (file)
index 0000000..4bb52ee
--- /dev/null
@@ -0,0 +1,155 @@
+From 60635162af7211f55bcd12ded6e65ee47692448a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 10:52:23 +0000
+Subject: media: uvcvideo: Fix sequence number when no EOF
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+commit f078966ca1fb1b3865d8e6bbe2705cfd277fc637 upstream.
+
+If the driver could not detect the EOF, the sequence number is increased
+twice:
+ 1) When we enter uvc_video_decode_start() with the old buffer and FID has
+   flipped => We return -EAGAIN and last_fid is not flipped
+ 2) When we enter uvc_video_decode_start() with the new buffer.
+
+Fix this issue by moving the new frame detection logic earlier in
+uvc_video_decode_start().
+
+This also has some nice side affects:
+
+- The error status from the new packet will no longer get propagated
+  to the previous frame-buffer.
+- uvc_video_clock_decode() will no longer update the previous frame
+  buf->stf with info from the new packet.
+- uvc_video_clock_decode() and uvc_video_stats_decode() will no longer
+  get called twice for the same packet.
+
+Cc: stable@kernel.org
+Fixes: 650b95feee35 ("[media] uvcvideo: Generate discontinuous sequence numbers when frames are lost")
+Reported-by: Hans de Goede <hansg@kernel.org>
+Closes: https://lore.kernel.org/linux-media/CANiDSCuj4cPuB5_v2xyvAagA5FjoN8V5scXiFFOeD3aKDMqkCg@mail.gmail.com/T/#me39fb134e8c2c085567a31548c3403eb639625e4
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_video.c | 92 ++++++++++++++++---------------
+ 1 file changed, 47 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index 408be24fceea..2cc00f4be793 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -1108,6 +1108,53 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+       header_len = data[0];
+       fid = data[1] & UVC_STREAM_FID;
++      /*
++       * Mark the buffer as done if we're at the beginning of a new frame.
++       * End of frame detection is better implemented by checking the EOF
++       * bit (FID bit toggling is delayed by one frame compared to the EOF
++       * bit), but some devices don't set the bit at end of frame (and the
++       * last payload can be lost anyway). We thus must check if the FID has
++       * been toggled.
++       *
++       * stream->last_fid is initialized to -1, and buf->bytesused to 0,
++       * so the first isochronous frame will never trigger an end of frame
++       * detection.
++       *
++       * Empty buffers (bytesused == 0) don't trigger end of frame detection
++       * as it doesn't make sense to return an empty buffer. This also
++       * avoids detecting end of frame conditions at FID toggling if the
++       * previous payload had the EOF bit set.
++       */
++      if (fid != stream->last_fid && buf && buf->bytesused != 0) {
++              uvc_dbg(stream->dev, FRAME,
++                      "Frame complete (FID bit toggled)\n");
++              buf->state = UVC_BUF_STATE_READY;
++
++              return -EAGAIN;
++      }
++
++      /*
++       * Some cameras, when running two parallel streams (one MJPEG alongside
++       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
++       * We can detect the end of a frame by checking for a new SOI marker, as
++       * the SOI always lies on the packet boundary between two frames for
++       * these devices.
++       */
++      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
++          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
++           stream->cur_format->fcc == V4L2_PIX_FMT_JPEG) &&
++          buf && buf->bytesused != 0) {
++              const u8 *packet = data + header_len;
++
++              if (len >= header_len + 2 &&
++                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI) {
++                      buf->state = UVC_BUF_STATE_READY;
++                      buf->error = 1;
++                      stream->last_fid ^= UVC_STREAM_FID;
++                      return -EAGAIN;
++              }
++      }
++
+       /*
+        * Increase the sequence number regardless of any buffer states, so
+        * that discontinuous sequence numbers always indicate lost frames.
+@@ -1175,51 +1222,6 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+                       meta_buf->state = UVC_BUF_STATE_ACTIVE;
+       }
+-      /*
+-       * Mark the buffer as done if we're at the beginning of a new frame.
+-       * End of frame detection is better implemented by checking the EOF
+-       * bit (FID bit toggling is delayed by one frame compared to the EOF
+-       * bit), but some devices don't set the bit at end of frame (and the
+-       * last payload can be lost anyway). We thus must check if the FID has
+-       * been toggled.
+-       *
+-       * stream->last_fid is initialized to -1, so the first isochronous
+-       * frame will never trigger an end of frame detection.
+-       *
+-       * Empty buffers (bytesused == 0) don't trigger end of frame detection
+-       * as it doesn't make sense to return an empty buffer. This also
+-       * avoids detecting end of frame conditions at FID toggling if the
+-       * previous payload had the EOF bit set.
+-       */
+-      if (fid != stream->last_fid && buf->bytesused != 0) {
+-              uvc_dbg(stream->dev, FRAME,
+-                      "Frame complete (FID bit toggled)\n");
+-              buf->state = UVC_BUF_STATE_READY;
+-              return -EAGAIN;
+-      }
+-
+-      /*
+-       * Some cameras, when running two parallel streams (one MJPEG alongside
+-       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
+-       * We can detect the end of a frame by checking for a new SOI marker, as
+-       * the SOI always lies on the packet boundary between two frames for
+-       * these devices.
+-       */
+-      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
+-          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
+-          stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) {
+-              const u8 *packet = data + header_len;
+-
+-              if (len >= header_len + 2 &&
+-                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI &&
+-                  buf->bytesused != 0) {
+-                      buf->state = UVC_BUF_STATE_READY;
+-                      buf->error = 1;
+-                      stream->last_fid ^= UVC_STREAM_FID;
+-                      return -EAGAIN;
+-              }
+-      }
+-
+       stream->last_fid = fid;
+       return header_len;
+-- 
+2.53.0
+
diff --git a/staging-6.1/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch b/staging-6.1/media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
new file mode 100644 (file)
index 0000000..19cdb81
--- /dev/null
@@ -0,0 +1,112 @@
+From fad444426a785df6855987c7fbbc0a893ad1bdd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 10:52:22 +0000
+Subject: media: uvcvideo: Implement dual stream quirk to fix loss of usb
+ packets
+
+From: Isaac Scott <isaac.scott@ideasonboard.com>
+
+commit c2eda35e675b6ea4a0a21a4b1167b121571a9036 upstream.
+
+Some cameras, such as the Sonix Technology Co. 292A, exhibit issues when
+running two parallel streams, causing USB packets to be dropped when an
+H.264 stream posts a keyframe while an MJPEG stream is running
+simultaneously. This occasionally causes the driver to erroneously
+output two consecutive JPEG images as a single frame.
+
+To fix this, we inspect the buffer, and trigger a new frame when we
+find an SOI.
+
+Signed-off-by: Isaac Scott <isaac.scott@ideasonboard.com>
+Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
+Link: https://lore.kernel.org/r/20241128145144.61475-2-isaac.scott@ideasonboard.com
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+[Added JPEG_MARKER_SOI definition, jpeg header does not exist yet]
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_video.c | 28 +++++++++++++++++++++++++++-
+ drivers/media/usb/uvc/uvcvideo.h  |  4 ++++
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index e33b9bedddda..408be24fceea 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -24,6 +24,8 @@
+ #include "uvcvideo.h"
++#define JPEG_MARKER_SOI                0xd8
++
+ /* ------------------------------------------------------------------------
+  * UVC Controls
+  */
+@@ -1089,6 +1091,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+                                 struct uvc_buffer *meta_buf,
+                                 const u8 *data, int len)
+ {
++      u8 header_len;
+       u8 fid;
+       /*
+@@ -1102,6 +1105,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+               return -EINVAL;
+       }
++      header_len = data[0];
+       fid = data[1] & UVC_STREAM_FID;
+       /*
+@@ -1194,9 +1198,31 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
+               return -EAGAIN;
+       }
++      /*
++       * Some cameras, when running two parallel streams (one MJPEG alongside
++       * another non-MJPEG stream), are known to lose the EOF packet for a frame.
++       * We can detect the end of a frame by checking for a new SOI marker, as
++       * the SOI always lies on the packet boundary between two frames for
++       * these devices.
++       */
++      if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
++          (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
++          stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) {
++              const u8 *packet = data + header_len;
++
++              if (len >= header_len + 2 &&
++                  packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI &&
++                  buf->bytesused != 0) {
++                      buf->state = UVC_BUF_STATE_READY;
++                      buf->error = 1;
++                      stream->last_fid ^= UVC_STREAM_FID;
++                      return -EAGAIN;
++              }
++      }
++
+       stream->last_fid = fid;
+-      return data[0];
++      return header_len;
+ }
+ static inline enum dma_data_direction uvc_stream_dir(
+diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
+index a7182305390b..8404814fa899 100644
+--- a/drivers/media/usb/uvc/uvcvideo.h
++++ b/drivers/media/usb/uvc/uvcvideo.h
+@@ -77,6 +77,10 @@
+ #define UVC_QUIRK_FORCE_Y8            0x00000800
+ #define UVC_QUIRK_FORCE_BPP           0x00001000
+ #define UVC_QUIRK_WAKE_AUTOSUSPEND    0x00002000
++#define UVC_QUIRK_NO_RESET_RESUME     0x00004000
++#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000
++#define UVC_QUIRK_INVALID_DEVICE_SOF  0x00010000
++#define UVC_QUIRK_MJPEG_NO_EOF                0x00020000
+ /* Format flags */
+ #define UVC_FMT_FLAG_COMPRESSED               0x00000001
+-- 
+2.53.0
+
diff --git a/staging-6.1/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch b/staging-6.1/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
new file mode 100644 (file)
index 0000000..15ab868
--- /dev/null
@@ -0,0 +1,74 @@
+From e2784b54299ddcbc5b097aa122700eee428dfe1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2026 10:08:29 +0900
+Subject: net: mpls: initialize rtm_tos in mpls_getroute()
+
+From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+
+[ Upstream commit 295dd295e2137e10e9a5b1891d97e0f08de76f03 ]
+
+mpls_getroute() builds the RTM_NEWROUTE reply to an RTM_GETROUTE
+request by filling a struct rtmsg allocated from an skb whose data
+area is not zeroed (alloc_skb(NLMSG_GOODSIZE, ...)). It sets every
+field of the header except rtm_tos:
+
+       r = nlmsg_data(nlh);
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+       r->rtm_protocol = rt->rt_protocol;
+       r->rtm_flags    = 0;
+
+struct rtmsg has no padding, so the one uninitialised byte rtm_tos
+(offset 3) is copied straight to user space on recvmsg(), leaking a
+byte of uninitialised heap memory. This is in contrast to
+mpls_dump_route(), which fills the very same header and does set
+rtm_tos = 0.
+
+Initialize rtm_tos to 0, matching mpls_dump_route().
+
+Reproduced with KMSAN by adding an MPLS route and issuing a
+non-RTM_F_FIB_MATCH RTM_GETROUTE for its label:
+
+  BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x36c/0x33f0
+   _copy_to_iter+0x36c/0x33f0
+   __skb_datagram_iter+0x196/0x12c0
+   skb_copy_datagram_iter+0x5b/0x210
+   netlink_recvmsg+0x37b/0xef0
+   ...
+  Uninit was created at:
+   __alloc_skb+0x8ca/0x10e0
+   mpls_getroute+0x1280/0x3a40
+   rtnetlink_rcv_msg+0x1138/0x15a0
+   ...
+  Byte 19 of 64 is uninitialized
+
+(byte 19 = nlmsghdr(16) + rtmsg offset 3 = rtm_tos)
+
+Fixes: 397fc9e5cefe ("mpls: route get support")
+Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+Link: https://patch.msgid.link/20260723010830.289917-1-yhlee@isslab.korea.ac.kr
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 6369ff87f4b9..11131f6a5a94 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2483,6 +2483,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
++      r->rtm_tos      = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+-- 
+2.53.0
+
diff --git a/staging-6.1/netfilter-br_netfilter-reallocate-headroom-if-necess.patch b/staging-6.1/netfilter-br_netfilter-reallocate-headroom-if-necess.patch
new file mode 100644 (file)
index 0000000..2bcb6f6
--- /dev/null
@@ -0,0 +1,142 @@
+From 212df0069a67885c08e01baedcf628a63ec24830 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 16:46:38 +0200
+Subject: netfilter: br_netfilter: Reallocate headroom if necessary in
+ neigh_hh_bridge()
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit b2870fc21601db9133bc70c48c603b487614fa3b ]
+
+neigh_hh_bridge() assumes the skb always has sufficient headroom to copy
+the aligned  L2 header. This assumption can trigger the crash reported
+below using the following netfilter setup:
+
+$modprobe br_netfilter
+$sysctl -w net.bridge.bridge-nf-call-iptables=1
+
+$root@OpenWrt:~# nft list ruleset
+table ip nat {
+        chain prerouting {
+                type nat hook prerouting priority dstnat; policy accept;
+                ip daddr 192.168.83.123 dnat to 192.168.83.120
+        }
+}
+
+- iperf3 client (192.168.83.119) --> bridge (192.168.83.118) --> iperf3 server (192.168.83.120)
+
+the iperf3 client is sending packet for 192.168.83.123 to the bridge device.
+
+[ 1579.036575] Unable to handle kernel write to read-only memory at virtual address ffffff8004d76ffe
+[ 1579.045482] Mem abort info:
+[ 1579.048273]   ESR = 0x000000009600004f
+[ 1579.052024]   EC = 0x25: DABT (current EL), IL = 32 bits
+[ 1579.057363]   SET = 0, FnV = 0
+[ 1579.060417]   EA = 0, S1PTW = 0
+[ 1579.063550]   FSC = 0x0f: level 3 permission fault
+[ 1579.068345] Data abort info:
+[ 1579.071224]   ISV = 0, ISS = 0x0000004f, ISS2 = 0x00000000
+[ 1579.076720]   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
+[ 1579.081770]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 1579.087092] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000080dc4000
+[ 1579.093794] [ffffff8004d76ffe] pgd=180000009ffff003, p4d=180000009ffff003, pud=180000009ffff003, pmd=180000009ffe3003, pte=0060000084d76787
+[ 1579.106343] Internal error: Oops: 000000009600004f [#1] SMP
+[ 1579.193824] CPU: 0 UID: 0 PID: 235 Comm: napi/qdma_eth-3 Tainted: G           O       6.12.57 #0
+[ 1579.202614] Tainted: [O]=OOT_MODULE
+[ 1579.206102] Hardware name: Airoha AN7581 Evaluation Board (DT)
+[ 1579.211929] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 1579.218889] pc : br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter]
+[ 1579.225859] lr : br_nf_pre_routing_finish_bridge+0x18c/0xcc8 [br_netfilter]
+[ 1579.232822] sp : ffffffc0817cba20
+[ 1579.236128] x29: ffffffc0817cba20 x28: 0000000000000000 x27: ffffff8002b89000
+[ 1579.243273] x26: ffffff8004d7700e x25: 0000000000000008 x24: 0000000000000000
+[ 1579.250416] x23: ffffffc08179d4c0 x22: 0000000000000000 x21: ffffffc08179d4c0
+[ 1579.257561] x20: ffffff8004d9b800 x19: ffffff8015010000 x18: 0000000000000014
+[ 1579.264704] x17: ffffffbf9e930000 x16: ffffffc0817c8000 x15: 0000000000000070
+[ 1579.271848] x14: 0000000000000080 x13: 0000000000000001 x12: 0000000000000000
+[ 1579.278993] x11: ffffffc0798caae0 x10: ffffff8014db6fd8 x9 : 0000000000000000
+[ 1579.286136] x8 : 0000000000000003 x7 : ffffffc08171f628 x6 : 000000001a3b83d3
+[ 1579.293281] x5 : 0000000000000000 x4 : 1beb76f22fee0000 x3 : ffffff8004d7700e
+[ 1579.300425] x2 : 0000000000000000 x1 : ffffff8004d9b8bc x0 : ffffff80026ed000
+[ 1579.307570] Call trace:
+[ 1579.310018]  br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter]
+[ 1579.316632]  br_nf_hook_thresh+0xd4/0x14bc [br_netfilter]
+[ 1579.322032]  br_nf_hook_thresh+0x250/0x14bc [br_netfilter]
+[ 1579.327517]  br_nf_hook_thresh+0x76c/0x14bc [br_netfilter]
+[ 1579.333003]  br_handle_frame+0x180/0x480
+[ 1579.336935]  __netif_receive_skb_core.constprop.0+0x540/0xf40
+[ 1579.342682]  __netif_receive_skb_one_core+0x28/0x50
+[ 1579.347561]  process_backlog+0x98/0x1e0
+[ 1579.351398]  __napi_poll+0x34/0x1c4
+[ 1579.354887]  net_rx_action+0x178/0x330
+[ 1579.358638]  handle_softirqs+0x108/0x2d4
+[ 1579.362560]  __do_softirq+0x10/0x18
+[ 1579.366051]  ____do_softirq+0xc/0x20
+[ 1579.369627]  call_on_irq_stack+0x30/0x4c
+[ 1579.373550]  do_softirq_own_stack+0x18/0x20
+[ 1579.377734]  do_softirq+0x4c/0x60
+[ 1579.381050]  __local_bh_enable_ip+0x88/0x98
+[ 1579.385234]  napi_threaded_poll_loop+0x188/0x21c
+[ 1579.389853]  napi_threaded_poll+0x70/0x80
+[ 1579.393863]  kthread+0xd8/0xdc
+[ 1579.396918]  ret_from_fork+0x10/0x20
+[ 1579.400499] Code: 88dffc22 3707ffc2 f9406663 f9406684 (f81f0064)
+[ 1579.406589] ---[ end trace 0000000000000000 ]---
+[ 1579.411209] Kernel panic - not syncing: Oops: Fatal exception in interrupt
+[ 1579.418083] SMP: stopping secondary CPUs
+[ 1579.422012] Kernel Offset: disabled
+
+Fix the issue reallocating the skb headroom if necessary in neigh_hh_bridge routine.
+
+Fixes: e179e6322ac33 ("netfilter: bridge-netfilter: Fix MAC header handling with IP DNAT")
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/neighbour.h         | 8 ++++++--
+ net/bridge/br_netfilter_hooks.c | 6 +++++-
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index 93aecfaa7628..b8b385a2a31c 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -478,11 +478,15 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
+ {
+-      unsigned int seq, hh_alen;
++      unsigned int seq, hh_alen = HH_DATA_ALIGN(ETH_HLEN);
++      int err;
++
++      err = skb_cow_head(skb, hh_alen);
++      if (err)
++              return err;
+       do {
+               seq = read_seqbegin(&hh->hh_lock);
+-              hh_alen = HH_DATA_ALIGN(ETH_HLEN);
+               memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
+       } while (read_seqretry(&hh->hh_lock, seq));
+       return 0;
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
+index c4765691e781..ffd100a242a0 100644
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -292,7 +292,11 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
+                               goto free_skb;
+                       }
+-                      neigh_hh_bridge(&neigh->hh, skb);
++                      if (neigh_hh_bridge(&neigh->hh, skb)) {
++                              neigh_release(neigh);
++                              goto free_skb;
++                      }
++
+                       skb->dev = br_indev;
+                       ret = br_handle_frame_finish(net, sk, skb);
+-- 
+2.53.0
+
index 5d3a24c72c73a6cff4c615d459d3d351bb9d19cd..ca65a4d42ca8eaa0d04e63a076556496a7234919 100644 (file)
@@ -2,3 +2,7 @@ io_uring-rw-fix-missing-erestartsys-conversion-in-re.patch
 mm-damon-core-validate-ranges-in-damon_set_regions.patch
 mm-damon-core-disallow-overlapping-input-ranges-for-.patch
 netfilter-nf_conntrack_expect-restore-helper-propaga.patch
+netfilter-br_netfilter-reallocate-headroom-if-necess.patch
+net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
+media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
+media-uvcvideo-fix-sequence-number-when-no-eof.patch
diff --git a/staging-6.12/net-airoha-fix-register-index-for-tx-fwd-counter-con.patch b/staging-6.12/net-airoha-fix-register-index-for-tx-fwd-counter-con.patch
new file mode 100644 (file)
index 0000000..0b3477e
--- /dev/null
@@ -0,0 +1,45 @@
+From e1cc41fc264d103a19bfebc3fc7133019a7b49c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 07:09:13 +0800
+Subject: net: airoha: Fix register index for Tx-fwd counter configuration
+
+From: Wayen.Yan <win847@gmail.com>
+
+[ Upstream commit 1402ecccf5630a0b7fa4749d7d2e72abc3f3d73d ]
+
+In airoha_qdma_init_qos_stats(), the Tx-fwd counter configuration
+register uses the same index (i << 1) as the Tx-cpu counter, which
+overwrites the Tx-cpu configuration. The Tx-fwd counter value register
+correctly uses (i << 1) + 1, so the configuration register should use
+the same index.
+
+Fix the REG_CNTR_CFG index from (i << 1) to ((i << 1) + 1) so that
+the Tx-fwd counter is properly configured instead of clobbering the
+Tx-cpu counter config.
+
+Fixes: 20bf7d07c956 ("net: airoha: Add sched ETS offload support")
+Signed-off-by: Wayen.Yan <win847@gmail.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/6a2b40e7.4dd82583.3a5c46.e566@mx.google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
+index 58e5791e9cd4..9ebc9788ded7 100644
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2022,7 +2022,7 @@ static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma)
+                              FIELD_PREP(CNTR_CHAN_MASK, i));
+               /* Tx-fwd transferred count */
+               airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0);
+-              airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1),
++              airoha_qdma_wr(qdma, REG_CNTR_CFG((i << 1) + 1),
+                              CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK |
+                              CNTR_ALL_DSCP_RING_EN_MASK |
+                              FIELD_PREP(CNTR_SRC_MASK, 1) |
+-- 
+2.53.0
+
diff --git a/staging-6.12/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch b/staging-6.12/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
new file mode 100644 (file)
index 0000000..6e82228
--- /dev/null
@@ -0,0 +1,74 @@
+From 936a49ce377e5e93e23df1ba275802a43312ae10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2026 10:08:29 +0900
+Subject: net: mpls: initialize rtm_tos in mpls_getroute()
+
+From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+
+[ Upstream commit 295dd295e2137e10e9a5b1891d97e0f08de76f03 ]
+
+mpls_getroute() builds the RTM_NEWROUTE reply to an RTM_GETROUTE
+request by filling a struct rtmsg allocated from an skb whose data
+area is not zeroed (alloc_skb(NLMSG_GOODSIZE, ...)). It sets every
+field of the header except rtm_tos:
+
+       r = nlmsg_data(nlh);
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+       r->rtm_protocol = rt->rt_protocol;
+       r->rtm_flags    = 0;
+
+struct rtmsg has no padding, so the one uninitialised byte rtm_tos
+(offset 3) is copied straight to user space on recvmsg(), leaking a
+byte of uninitialised heap memory. This is in contrast to
+mpls_dump_route(), which fills the very same header and does set
+rtm_tos = 0.
+
+Initialize rtm_tos to 0, matching mpls_dump_route().
+
+Reproduced with KMSAN by adding an MPLS route and issuing a
+non-RTM_F_FIB_MATCH RTM_GETROUTE for its label:
+
+  BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x36c/0x33f0
+   _copy_to_iter+0x36c/0x33f0
+   __skb_datagram_iter+0x196/0x12c0
+   skb_copy_datagram_iter+0x5b/0x210
+   netlink_recvmsg+0x37b/0xef0
+   ...
+  Uninit was created at:
+   __alloc_skb+0x8ca/0x10e0
+   mpls_getroute+0x1280/0x3a40
+   rtnetlink_rcv_msg+0x1138/0x15a0
+   ...
+  Byte 19 of 64 is uninitialized
+
+(byte 19 = nlmsghdr(16) + rtmsg offset 3 = rtm_tos)
+
+Fixes: 397fc9e5cefe ("mpls: route get support")
+Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+Link: https://patch.msgid.link/20260723010830.289917-1-yhlee@isslab.korea.ac.kr
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 98816e51e01a..0379540d601a 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2468,6 +2468,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
++      r->rtm_tos      = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+-- 
+2.53.0
+
diff --git a/staging-6.12/netfilter-br_netfilter-reallocate-headroom-if-necess.patch b/staging-6.12/netfilter-br_netfilter-reallocate-headroom-if-necess.patch
new file mode 100644 (file)
index 0000000..e213cba
--- /dev/null
@@ -0,0 +1,142 @@
+From 803fa2f613703f2af77704991ad23ea7ae7f1c26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 16:46:38 +0200
+Subject: netfilter: br_netfilter: Reallocate headroom if necessary in
+ neigh_hh_bridge()
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit b2870fc21601db9133bc70c48c603b487614fa3b ]
+
+neigh_hh_bridge() assumes the skb always has sufficient headroom to copy
+the aligned  L2 header. This assumption can trigger the crash reported
+below using the following netfilter setup:
+
+$modprobe br_netfilter
+$sysctl -w net.bridge.bridge-nf-call-iptables=1
+
+$root@OpenWrt:~# nft list ruleset
+table ip nat {
+        chain prerouting {
+                type nat hook prerouting priority dstnat; policy accept;
+                ip daddr 192.168.83.123 dnat to 192.168.83.120
+        }
+}
+
+- iperf3 client (192.168.83.119) --> bridge (192.168.83.118) --> iperf3 server (192.168.83.120)
+
+the iperf3 client is sending packet for 192.168.83.123 to the bridge device.
+
+[ 1579.036575] Unable to handle kernel write to read-only memory at virtual address ffffff8004d76ffe
+[ 1579.045482] Mem abort info:
+[ 1579.048273]   ESR = 0x000000009600004f
+[ 1579.052024]   EC = 0x25: DABT (current EL), IL = 32 bits
+[ 1579.057363]   SET = 0, FnV = 0
+[ 1579.060417]   EA = 0, S1PTW = 0
+[ 1579.063550]   FSC = 0x0f: level 3 permission fault
+[ 1579.068345] Data abort info:
+[ 1579.071224]   ISV = 0, ISS = 0x0000004f, ISS2 = 0x00000000
+[ 1579.076720]   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
+[ 1579.081770]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 1579.087092] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000080dc4000
+[ 1579.093794] [ffffff8004d76ffe] pgd=180000009ffff003, p4d=180000009ffff003, pud=180000009ffff003, pmd=180000009ffe3003, pte=0060000084d76787
+[ 1579.106343] Internal error: Oops: 000000009600004f [#1] SMP
+[ 1579.193824] CPU: 0 UID: 0 PID: 235 Comm: napi/qdma_eth-3 Tainted: G           O       6.12.57 #0
+[ 1579.202614] Tainted: [O]=OOT_MODULE
+[ 1579.206102] Hardware name: Airoha AN7581 Evaluation Board (DT)
+[ 1579.211929] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 1579.218889] pc : br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter]
+[ 1579.225859] lr : br_nf_pre_routing_finish_bridge+0x18c/0xcc8 [br_netfilter]
+[ 1579.232822] sp : ffffffc0817cba20
+[ 1579.236128] x29: ffffffc0817cba20 x28: 0000000000000000 x27: ffffff8002b89000
+[ 1579.243273] x26: ffffff8004d7700e x25: 0000000000000008 x24: 0000000000000000
+[ 1579.250416] x23: ffffffc08179d4c0 x22: 0000000000000000 x21: ffffffc08179d4c0
+[ 1579.257561] x20: ffffff8004d9b800 x19: ffffff8015010000 x18: 0000000000000014
+[ 1579.264704] x17: ffffffbf9e930000 x16: ffffffc0817c8000 x15: 0000000000000070
+[ 1579.271848] x14: 0000000000000080 x13: 0000000000000001 x12: 0000000000000000
+[ 1579.278993] x11: ffffffc0798caae0 x10: ffffff8014db6fd8 x9 : 0000000000000000
+[ 1579.286136] x8 : 0000000000000003 x7 : ffffffc08171f628 x6 : 000000001a3b83d3
+[ 1579.293281] x5 : 0000000000000000 x4 : 1beb76f22fee0000 x3 : ffffff8004d7700e
+[ 1579.300425] x2 : 0000000000000000 x1 : ffffff8004d9b8bc x0 : ffffff80026ed000
+[ 1579.307570] Call trace:
+[ 1579.310018]  br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter]
+[ 1579.316632]  br_nf_hook_thresh+0xd4/0x14bc [br_netfilter]
+[ 1579.322032]  br_nf_hook_thresh+0x250/0x14bc [br_netfilter]
+[ 1579.327517]  br_nf_hook_thresh+0x76c/0x14bc [br_netfilter]
+[ 1579.333003]  br_handle_frame+0x180/0x480
+[ 1579.336935]  __netif_receive_skb_core.constprop.0+0x540/0xf40
+[ 1579.342682]  __netif_receive_skb_one_core+0x28/0x50
+[ 1579.347561]  process_backlog+0x98/0x1e0
+[ 1579.351398]  __napi_poll+0x34/0x1c4
+[ 1579.354887]  net_rx_action+0x178/0x330
+[ 1579.358638]  handle_softirqs+0x108/0x2d4
+[ 1579.362560]  __do_softirq+0x10/0x18
+[ 1579.366051]  ____do_softirq+0xc/0x20
+[ 1579.369627]  call_on_irq_stack+0x30/0x4c
+[ 1579.373550]  do_softirq_own_stack+0x18/0x20
+[ 1579.377734]  do_softirq+0x4c/0x60
+[ 1579.381050]  __local_bh_enable_ip+0x88/0x98
+[ 1579.385234]  napi_threaded_poll_loop+0x188/0x21c
+[ 1579.389853]  napi_threaded_poll+0x70/0x80
+[ 1579.393863]  kthread+0xd8/0xdc
+[ 1579.396918]  ret_from_fork+0x10/0x20
+[ 1579.400499] Code: 88dffc22 3707ffc2 f9406663 f9406684 (f81f0064)
+[ 1579.406589] ---[ end trace 0000000000000000 ]---
+[ 1579.411209] Kernel panic - not syncing: Oops: Fatal exception in interrupt
+[ 1579.418083] SMP: stopping secondary CPUs
+[ 1579.422012] Kernel Offset: disabled
+
+Fix the issue reallocating the skb headroom if necessary in neigh_hh_bridge routine.
+
+Fixes: e179e6322ac33 ("netfilter: bridge-netfilter: Fix MAC header handling with IP DNAT")
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/neighbour.h         | 8 ++++++--
+ net/bridge/br_netfilter_hooks.c | 6 +++++-
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index cb5f835a5d61..0272d0f0e89d 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -476,11 +476,15 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
+ {
+-      unsigned int seq, hh_alen;
++      unsigned int seq, hh_alen = HH_DATA_ALIGN(ETH_HLEN);
++      int err;
++
++      err = skb_cow_head(skb, hh_alen);
++      if (err)
++              return err;
+       do {
+               seq = read_seqbegin(&hh->hh_lock);
+-              hh_alen = HH_DATA_ALIGN(ETH_HLEN);
+               memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
+       } while (read_seqretry(&hh->hh_lock, seq));
+       return 0;
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
+index 5ad3f3ef4ca7..c550907b92dd 100644
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -296,7 +296,11 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
+                               goto free_skb;
+                       }
+-                      neigh_hh_bridge(&neigh->hh, skb);
++                      if (neigh_hh_bridge(&neigh->hh, skb)) {
++                              neigh_release(neigh);
++                              goto free_skb;
++                      }
++
+                       skb->dev = br_indev;
+                       ret = br_handle_frame_finish(net, sk, skb);
+-- 
+2.53.0
+
index 8b36f5acf42d1eeaf2a89263eb5117b94aa59b70..ab6e78e7a294b54587d2385c76f9c8bd39f5270d 100644 (file)
@@ -8,3 +8,6 @@ um-set-parent-death-signal-for-userspace-process.patch
 kunit-tool-terminate-kernel-under-test-on-sigint.patch
 kunit-tool-skip-stty-when-stdin-is-not-a-tty.patch
 um-preserve-errno-within-signal-handler.patch
+netfilter-br_netfilter-reallocate-headroom-if-necess.patch
+net-airoha-fix-register-index-for-tx-fwd-counter-con.patch
+net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
diff --git a/staging-6.18/drm-gpusvm-publish-dpagemap-early-to-avoid-device-ma.patch b/staging-6.18/drm-gpusvm-publish-dpagemap-early-to-avoid-device-ma.patch
new file mode 100644 (file)
index 0000000..fee34d5
--- /dev/null
@@ -0,0 +1,70 @@
+From 081cb57de50473cb058ae07230a580f7d9bbb7ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 19:17:28 +0800
+Subject: drm/gpusvm: publish dpagemap early to avoid device mapping leak on
+ error
+
+From: Honglei Huang <honghuan@amd.com>
+
+commit 7f708f51e3955bda0d77a0b67ab9bea6c97fea99 upstream.
+
+drm_gpusvm_get_pages() only stored the local dpagemap into
+svm_pages->dpagemap on the success path. If a later page failed (e.g.
+-EOPNOTSUPP when ctx->allow_mixed is false) and jumped to err_unmap,
+svm_pages->dpagemap was still NULL, so __drm_gpusvm_unmap_pages() skipped
+device_unmap() and leaked the device mappings already created.
+
+Assign svm_pages->dpagemap when the first device page is mapped so the
+err_unmap path can device_unmap() those mappings.
+
+This issue was found by Sashiko AI review.
+
+Fixes: f70da6f99d4f ("drm/gpusvm: pull out drm_gpusvm_pages substructure")
+Cc: stable@vger.kernel.org
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Honglei Huang <honghuan@amd.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patch.msgid.link/20260701062800.409248-4-honghuan@amd.com
+[ Adjusted for 6.18.y: drop drm_pagemap_get()/drm_pagemap_put() around the
+  svm_pages->dpagemap assignment; that reference counting is not present in
+  6.18 where the field is not refcounted (unmap path only clears it). ]
+Signed-off-by: Honglei Huang <honghuan@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_gpusvm.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c
+index 781cd4e5b704..e5c7befe3108 100644
+--- a/drivers/gpu/drm/drm_gpusvm.c
++++ b/drivers/gpu/drm/drm_gpusvm.c
+@@ -1390,6 +1390,14 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
+                                       err = -EAGAIN;
+                                       goto err_unmap;
+                               }
++
++                              /*
++                               * Set the dpagemap as soon as the first
++                               * device page is mapped so the err_unmap path
++                               * can device_unmap() the device mappings that
++                               * have already been created.
++                               */
++                              svm_pages->dpagemap = dpagemap;
+                       }
+                       svm_pages->dma_addr[j] =
+                               dpagemap->ops->device_map(dpagemap,
+@@ -1432,10 +1440,8 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
+               flags.has_dma_mapping = true;
+       }
+-      if (pagemap) {
++      if (pagemap)
+               flags.has_devmem_pages = true;
+-              svm_pages->dpagemap = dpagemap;
+-      }
+       /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */
+       WRITE_ONCE(svm_pages->flags.__flags, flags.__flags);
+-- 
+2.53.0
+
diff --git a/staging-6.18/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch b/staging-6.18/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
new file mode 100644 (file)
index 0000000..1436087
--- /dev/null
@@ -0,0 +1,74 @@
+From 725d4c733423508d3690cb930ee44c9d168caa7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2026 10:08:29 +0900
+Subject: net: mpls: initialize rtm_tos in mpls_getroute()
+
+From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+
+[ Upstream commit 295dd295e2137e10e9a5b1891d97e0f08de76f03 ]
+
+mpls_getroute() builds the RTM_NEWROUTE reply to an RTM_GETROUTE
+request by filling a struct rtmsg allocated from an skb whose data
+area is not zeroed (alloc_skb(NLMSG_GOODSIZE, ...)). It sets every
+field of the header except rtm_tos:
+
+       r = nlmsg_data(nlh);
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+       r->rtm_protocol = rt->rt_protocol;
+       r->rtm_flags    = 0;
+
+struct rtmsg has no padding, so the one uninitialised byte rtm_tos
+(offset 3) is copied straight to user space on recvmsg(), leaking a
+byte of uninitialised heap memory. This is in contrast to
+mpls_dump_route(), which fills the very same header and does set
+rtm_tos = 0.
+
+Initialize rtm_tos to 0, matching mpls_dump_route().
+
+Reproduced with KMSAN by adding an MPLS route and issuing a
+non-RTM_F_FIB_MATCH RTM_GETROUTE for its label:
+
+  BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x36c/0x33f0
+   _copy_to_iter+0x36c/0x33f0
+   __skb_datagram_iter+0x196/0x12c0
+   skb_copy_datagram_iter+0x5b/0x210
+   netlink_recvmsg+0x37b/0xef0
+   ...
+  Uninit was created at:
+   __alloc_skb+0x8ca/0x10e0
+   mpls_getroute+0x1280/0x3a40
+   rtnetlink_rcv_msg+0x1138/0x15a0
+   ...
+  Byte 19 of 64 is uninitialized
+
+(byte 19 = nlmsghdr(16) + rtmsg offset 3 = rtm_tos)
+
+Fixes: 397fc9e5cefe ("mpls: route get support")
+Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+Link: https://patch.msgid.link/20260723010830.289917-1-yhlee@isslab.korea.ac.kr
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index f7f60025d042..f9b8c4d0f049 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2468,6 +2468,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
++      r->rtm_tos      = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+-- 
+2.53.0
+
diff --git a/staging-6.18/netfilter-br_netfilter-reallocate-headroom-if-necess.patch b/staging-6.18/netfilter-br_netfilter-reallocate-headroom-if-necess.patch
new file mode 100644 (file)
index 0000000..3f36b32
--- /dev/null
@@ -0,0 +1,142 @@
+From 55d3dc69df3c4c77d98127c4891fe31a2eb9d115 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 16:46:38 +0200
+Subject: netfilter: br_netfilter: Reallocate headroom if necessary in
+ neigh_hh_bridge()
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit b2870fc21601db9133bc70c48c603b487614fa3b ]
+
+neigh_hh_bridge() assumes the skb always has sufficient headroom to copy
+the aligned  L2 header. This assumption can trigger the crash reported
+below using the following netfilter setup:
+
+$modprobe br_netfilter
+$sysctl -w net.bridge.bridge-nf-call-iptables=1
+
+$root@OpenWrt:~# nft list ruleset
+table ip nat {
+        chain prerouting {
+                type nat hook prerouting priority dstnat; policy accept;
+                ip daddr 192.168.83.123 dnat to 192.168.83.120
+        }
+}
+
+- iperf3 client (192.168.83.119) --> bridge (192.168.83.118) --> iperf3 server (192.168.83.120)
+
+the iperf3 client is sending packet for 192.168.83.123 to the bridge device.
+
+[ 1579.036575] Unable to handle kernel write to read-only memory at virtual address ffffff8004d76ffe
+[ 1579.045482] Mem abort info:
+[ 1579.048273]   ESR = 0x000000009600004f
+[ 1579.052024]   EC = 0x25: DABT (current EL), IL = 32 bits
+[ 1579.057363]   SET = 0, FnV = 0
+[ 1579.060417]   EA = 0, S1PTW = 0
+[ 1579.063550]   FSC = 0x0f: level 3 permission fault
+[ 1579.068345] Data abort info:
+[ 1579.071224]   ISV = 0, ISS = 0x0000004f, ISS2 = 0x00000000
+[ 1579.076720]   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
+[ 1579.081770]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 1579.087092] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000080dc4000
+[ 1579.093794] [ffffff8004d76ffe] pgd=180000009ffff003, p4d=180000009ffff003, pud=180000009ffff003, pmd=180000009ffe3003, pte=0060000084d76787
+[ 1579.106343] Internal error: Oops: 000000009600004f [#1] SMP
+[ 1579.193824] CPU: 0 UID: 0 PID: 235 Comm: napi/qdma_eth-3 Tainted: G           O       6.12.57 #0
+[ 1579.202614] Tainted: [O]=OOT_MODULE
+[ 1579.206102] Hardware name: Airoha AN7581 Evaluation Board (DT)
+[ 1579.211929] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 1579.218889] pc : br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter]
+[ 1579.225859] lr : br_nf_pre_routing_finish_bridge+0x18c/0xcc8 [br_netfilter]
+[ 1579.232822] sp : ffffffc0817cba20
+[ 1579.236128] x29: ffffffc0817cba20 x28: 0000000000000000 x27: ffffff8002b89000
+[ 1579.243273] x26: ffffff8004d7700e x25: 0000000000000008 x24: 0000000000000000
+[ 1579.250416] x23: ffffffc08179d4c0 x22: 0000000000000000 x21: ffffffc08179d4c0
+[ 1579.257561] x20: ffffff8004d9b800 x19: ffffff8015010000 x18: 0000000000000014
+[ 1579.264704] x17: ffffffbf9e930000 x16: ffffffc0817c8000 x15: 0000000000000070
+[ 1579.271848] x14: 0000000000000080 x13: 0000000000000001 x12: 0000000000000000
+[ 1579.278993] x11: ffffffc0798caae0 x10: ffffff8014db6fd8 x9 : 0000000000000000
+[ 1579.286136] x8 : 0000000000000003 x7 : ffffffc08171f628 x6 : 000000001a3b83d3
+[ 1579.293281] x5 : 0000000000000000 x4 : 1beb76f22fee0000 x3 : ffffff8004d7700e
+[ 1579.300425] x2 : 0000000000000000 x1 : ffffff8004d9b8bc x0 : ffffff80026ed000
+[ 1579.307570] Call trace:
+[ 1579.310018]  br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter]
+[ 1579.316632]  br_nf_hook_thresh+0xd4/0x14bc [br_netfilter]
+[ 1579.322032]  br_nf_hook_thresh+0x250/0x14bc [br_netfilter]
+[ 1579.327517]  br_nf_hook_thresh+0x76c/0x14bc [br_netfilter]
+[ 1579.333003]  br_handle_frame+0x180/0x480
+[ 1579.336935]  __netif_receive_skb_core.constprop.0+0x540/0xf40
+[ 1579.342682]  __netif_receive_skb_one_core+0x28/0x50
+[ 1579.347561]  process_backlog+0x98/0x1e0
+[ 1579.351398]  __napi_poll+0x34/0x1c4
+[ 1579.354887]  net_rx_action+0x178/0x330
+[ 1579.358638]  handle_softirqs+0x108/0x2d4
+[ 1579.362560]  __do_softirq+0x10/0x18
+[ 1579.366051]  ____do_softirq+0xc/0x20
+[ 1579.369627]  call_on_irq_stack+0x30/0x4c
+[ 1579.373550]  do_softirq_own_stack+0x18/0x20
+[ 1579.377734]  do_softirq+0x4c/0x60
+[ 1579.381050]  __local_bh_enable_ip+0x88/0x98
+[ 1579.385234]  napi_threaded_poll_loop+0x188/0x21c
+[ 1579.389853]  napi_threaded_poll+0x70/0x80
+[ 1579.393863]  kthread+0xd8/0xdc
+[ 1579.396918]  ret_from_fork+0x10/0x20
+[ 1579.400499] Code: 88dffc22 3707ffc2 f9406663 f9406684 (f81f0064)
+[ 1579.406589] ---[ end trace 0000000000000000 ]---
+[ 1579.411209] Kernel panic - not syncing: Oops: Fatal exception in interrupt
+[ 1579.418083] SMP: stopping secondary CPUs
+[ 1579.422012] Kernel Offset: disabled
+
+Fix the issue reallocating the skb headroom if necessary in neigh_hh_bridge routine.
+
+Fixes: e179e6322ac33 ("netfilter: bridge-netfilter: Fix MAC header handling with IP DNAT")
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/neighbour.h         | 8 ++++++--
+ net/bridge/br_netfilter_hooks.c | 6 +++++-
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index 4a30bd458c5a..c13c758aca7e 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -480,11 +480,15 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
+ {
+-      unsigned int seq, hh_alen;
++      unsigned int seq, hh_alen = HH_DATA_ALIGN(ETH_HLEN);
++      int err;
++
++      err = skb_cow_head(skb, hh_alen);
++      if (err)
++              return err;
+       do {
+               seq = read_seqbegin(&hh->hh_lock);
+-              hh_alen = HH_DATA_ALIGN(ETH_HLEN);
+               memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
+       } while (read_seqretry(&hh->hh_lock, seq));
+       return 0;
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
+index 083e2fe96441..6544c18febef 100644
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -296,7 +296,11 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
+                               goto free_skb;
+                       }
+-                      neigh_hh_bridge(&neigh->hh, skb);
++                      if (neigh_hh_bridge(&neigh->hh, skb)) {
++                              neigh_release(neigh);
++                              goto free_skb;
++                      }
++
+                       skb->dev = br_indev;
+                       ret = br_handle_frame_finish(net, sk, skb);
+-- 
+2.53.0
+
index e31db453cce48f9ac849437ad6a63ce4183dc52c..cc1362d923dcf4a4065f231c4cd4acd8e6a7441c 100644 (file)
@@ -1,3 +1,6 @@
 netfilter-nf_conntrack_expect-restore-helper-propaga.patch
 kunit-tool-skip-stty-when-stdin-is-not-a-tty.patch
 kunit-tool-terminate-kernel-under-test-on-sigint.patch
+netfilter-br_netfilter-reallocate-headroom-if-necess.patch
+net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
+drm-gpusvm-publish-dpagemap-early-to-avoid-device-ma.patch
diff --git a/staging-6.6/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch b/staging-6.6/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
new file mode 100644 (file)
index 0000000..87273df
--- /dev/null
@@ -0,0 +1,74 @@
+From af674c2145b8eec73f250be1433796e3af33aba1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2026 10:08:29 +0900
+Subject: net: mpls: initialize rtm_tos in mpls_getroute()
+
+From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+
+[ Upstream commit 295dd295e2137e10e9a5b1891d97e0f08de76f03 ]
+
+mpls_getroute() builds the RTM_NEWROUTE reply to an RTM_GETROUTE
+request by filling a struct rtmsg allocated from an skb whose data
+area is not zeroed (alloc_skb(NLMSG_GOODSIZE, ...)). It sets every
+field of the header except rtm_tos:
+
+       r = nlmsg_data(nlh);
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+       r->rtm_protocol = rt->rt_protocol;
+       r->rtm_flags    = 0;
+
+struct rtmsg has no padding, so the one uninitialised byte rtm_tos
+(offset 3) is copied straight to user space on recvmsg(), leaking a
+byte of uninitialised heap memory. This is in contrast to
+mpls_dump_route(), which fills the very same header and does set
+rtm_tos = 0.
+
+Initialize rtm_tos to 0, matching mpls_dump_route().
+
+Reproduced with KMSAN by adding an MPLS route and issuing a
+non-RTM_F_FIB_MATCH RTM_GETROUTE for its label:
+
+  BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x36c/0x33f0
+   _copy_to_iter+0x36c/0x33f0
+   __skb_datagram_iter+0x196/0x12c0
+   skb_copy_datagram_iter+0x5b/0x210
+   netlink_recvmsg+0x37b/0xef0
+   ...
+  Uninit was created at:
+   __alloc_skb+0x8ca/0x10e0
+   mpls_getroute+0x1280/0x3a40
+   rtnetlink_rcv_msg+0x1138/0x15a0
+   ...
+  Byte 19 of 64 is uninitialized
+
+(byte 19 = nlmsghdr(16) + rtmsg offset 3 = rtm_tos)
+
+Fixes: 397fc9e5cefe ("mpls: route get support")
+Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+Link: https://patch.msgid.link/20260723010830.289917-1-yhlee@isslab.korea.ac.kr
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 2099ce095edc..cf5ae62ba898 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2469,6 +2469,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
++      r->rtm_tos      = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+-- 
+2.53.0
+
diff --git a/staging-6.6/netfilter-br_netfilter-reallocate-headroom-if-necess.patch b/staging-6.6/netfilter-br_netfilter-reallocate-headroom-if-necess.patch
new file mode 100644 (file)
index 0000000..e6dc84f
--- /dev/null
@@ -0,0 +1,142 @@
+From 92da9a2759d37369e137570b018903ac0cccf9d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 16:46:38 +0200
+Subject: netfilter: br_netfilter: Reallocate headroom if necessary in
+ neigh_hh_bridge()
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit b2870fc21601db9133bc70c48c603b487614fa3b ]
+
+neigh_hh_bridge() assumes the skb always has sufficient headroom to copy
+the aligned  L2 header. This assumption can trigger the crash reported
+below using the following netfilter setup:
+
+$modprobe br_netfilter
+$sysctl -w net.bridge.bridge-nf-call-iptables=1
+
+$root@OpenWrt:~# nft list ruleset
+table ip nat {
+        chain prerouting {
+                type nat hook prerouting priority dstnat; policy accept;
+                ip daddr 192.168.83.123 dnat to 192.168.83.120
+        }
+}
+
+- iperf3 client (192.168.83.119) --> bridge (192.168.83.118) --> iperf3 server (192.168.83.120)
+
+the iperf3 client is sending packet for 192.168.83.123 to the bridge device.
+
+[ 1579.036575] Unable to handle kernel write to read-only memory at virtual address ffffff8004d76ffe
+[ 1579.045482] Mem abort info:
+[ 1579.048273]   ESR = 0x000000009600004f
+[ 1579.052024]   EC = 0x25: DABT (current EL), IL = 32 bits
+[ 1579.057363]   SET = 0, FnV = 0
+[ 1579.060417]   EA = 0, S1PTW = 0
+[ 1579.063550]   FSC = 0x0f: level 3 permission fault
+[ 1579.068345] Data abort info:
+[ 1579.071224]   ISV = 0, ISS = 0x0000004f, ISS2 = 0x00000000
+[ 1579.076720]   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
+[ 1579.081770]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 1579.087092] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000080dc4000
+[ 1579.093794] [ffffff8004d76ffe] pgd=180000009ffff003, p4d=180000009ffff003, pud=180000009ffff003, pmd=180000009ffe3003, pte=0060000084d76787
+[ 1579.106343] Internal error: Oops: 000000009600004f [#1] SMP
+[ 1579.193824] CPU: 0 UID: 0 PID: 235 Comm: napi/qdma_eth-3 Tainted: G           O       6.12.57 #0
+[ 1579.202614] Tainted: [O]=OOT_MODULE
+[ 1579.206102] Hardware name: Airoha AN7581 Evaluation Board (DT)
+[ 1579.211929] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 1579.218889] pc : br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter]
+[ 1579.225859] lr : br_nf_pre_routing_finish_bridge+0x18c/0xcc8 [br_netfilter]
+[ 1579.232822] sp : ffffffc0817cba20
+[ 1579.236128] x29: ffffffc0817cba20 x28: 0000000000000000 x27: ffffff8002b89000
+[ 1579.243273] x26: ffffff8004d7700e x25: 0000000000000008 x24: 0000000000000000
+[ 1579.250416] x23: ffffffc08179d4c0 x22: 0000000000000000 x21: ffffffc08179d4c0
+[ 1579.257561] x20: ffffff8004d9b800 x19: ffffff8015010000 x18: 0000000000000014
+[ 1579.264704] x17: ffffffbf9e930000 x16: ffffffc0817c8000 x15: 0000000000000070
+[ 1579.271848] x14: 0000000000000080 x13: 0000000000000001 x12: 0000000000000000
+[ 1579.278993] x11: ffffffc0798caae0 x10: ffffff8014db6fd8 x9 : 0000000000000000
+[ 1579.286136] x8 : 0000000000000003 x7 : ffffffc08171f628 x6 : 000000001a3b83d3
+[ 1579.293281] x5 : 0000000000000000 x4 : 1beb76f22fee0000 x3 : ffffff8004d7700e
+[ 1579.300425] x2 : 0000000000000000 x1 : ffffff8004d9b8bc x0 : ffffff80026ed000
+[ 1579.307570] Call trace:
+[ 1579.310018]  br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter]
+[ 1579.316632]  br_nf_hook_thresh+0xd4/0x14bc [br_netfilter]
+[ 1579.322032]  br_nf_hook_thresh+0x250/0x14bc [br_netfilter]
+[ 1579.327517]  br_nf_hook_thresh+0x76c/0x14bc [br_netfilter]
+[ 1579.333003]  br_handle_frame+0x180/0x480
+[ 1579.336935]  __netif_receive_skb_core.constprop.0+0x540/0xf40
+[ 1579.342682]  __netif_receive_skb_one_core+0x28/0x50
+[ 1579.347561]  process_backlog+0x98/0x1e0
+[ 1579.351398]  __napi_poll+0x34/0x1c4
+[ 1579.354887]  net_rx_action+0x178/0x330
+[ 1579.358638]  handle_softirqs+0x108/0x2d4
+[ 1579.362560]  __do_softirq+0x10/0x18
+[ 1579.366051]  ____do_softirq+0xc/0x20
+[ 1579.369627]  call_on_irq_stack+0x30/0x4c
+[ 1579.373550]  do_softirq_own_stack+0x18/0x20
+[ 1579.377734]  do_softirq+0x4c/0x60
+[ 1579.381050]  __local_bh_enable_ip+0x88/0x98
+[ 1579.385234]  napi_threaded_poll_loop+0x188/0x21c
+[ 1579.389853]  napi_threaded_poll+0x70/0x80
+[ 1579.393863]  kthread+0xd8/0xdc
+[ 1579.396918]  ret_from_fork+0x10/0x20
+[ 1579.400499] Code: 88dffc22 3707ffc2 f9406663 f9406684 (f81f0064)
+[ 1579.406589] ---[ end trace 0000000000000000 ]---
+[ 1579.411209] Kernel panic - not syncing: Oops: Fatal exception in interrupt
+[ 1579.418083] SMP: stopping secondary CPUs
+[ 1579.422012] Kernel Offset: disabled
+
+Fix the issue reallocating the skb headroom if necessary in neigh_hh_bridge routine.
+
+Fixes: e179e6322ac33 ("netfilter: bridge-netfilter: Fix MAC header handling with IP DNAT")
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/neighbour.h         | 8 ++++++--
+ net/bridge/br_netfilter_hooks.c | 6 +++++-
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index d775906a65c7..9ada7451fd2a 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -476,11 +476,15 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
+ {
+-      unsigned int seq, hh_alen;
++      unsigned int seq, hh_alen = HH_DATA_ALIGN(ETH_HLEN);
++      int err;
++
++      err = skb_cow_head(skb, hh_alen);
++      if (err)
++              return err;
+       do {
+               seq = read_seqbegin(&hh->hh_lock);
+-              hh_alen = HH_DATA_ALIGN(ETH_HLEN);
+               memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
+       } while (read_seqretry(&hh->hh_lock, seq));
+       return 0;
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
+index e6962d693359..3fbcf1b7e93d 100644
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -292,7 +292,11 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
+                               goto free_skb;
+                       }
+-                      neigh_hh_bridge(&neigh->hh, skb);
++                      if (neigh_hh_bridge(&neigh->hh, skb)) {
++                              neigh_release(neigh);
++                              goto free_skb;
++                      }
++
+                       skb->dev = br_indev;
+                       ret = br_handle_frame_finish(net, sk, skb);
+-- 
+2.53.0
+
index 9de0fac5781177053aabe562f1137b8b341836ae..7464fefac51086a1926ff4233facb563f3e1629c 100644 (file)
@@ -1 +1,3 @@
 netfilter-nf_conntrack_expect-restore-helper-propaga.patch
+netfilter-br_netfilter-reallocate-headroom-if-necess.patch
+net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
diff --git a/staging-7.1/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch b/staging-7.1/net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
new file mode 100644 (file)
index 0000000..f3c4f04
--- /dev/null
@@ -0,0 +1,74 @@
+From 7426b5daf78256a507e3d6bc16375a9ad27dc735 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2026 10:08:29 +0900
+Subject: net: mpls: initialize rtm_tos in mpls_getroute()
+
+From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+
+[ Upstream commit 295dd295e2137e10e9a5b1891d97e0f08de76f03 ]
+
+mpls_getroute() builds the RTM_NEWROUTE reply to an RTM_GETROUTE
+request by filling a struct rtmsg allocated from an skb whose data
+area is not zeroed (alloc_skb(NLMSG_GOODSIZE, ...)). It sets every
+field of the header except rtm_tos:
+
+       r = nlmsg_data(nlh);
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+       r->rtm_protocol = rt->rt_protocol;
+       r->rtm_flags    = 0;
+
+struct rtmsg has no padding, so the one uninitialised byte rtm_tos
+(offset 3) is copied straight to user space on recvmsg(), leaking a
+byte of uninitialised heap memory. This is in contrast to
+mpls_dump_route(), which fills the very same header and does set
+rtm_tos = 0.
+
+Initialize rtm_tos to 0, matching mpls_dump_route().
+
+Reproduced with KMSAN by adding an MPLS route and issuing a
+non-RTM_F_FIB_MATCH RTM_GETROUTE for its label:
+
+  BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x36c/0x33f0
+   _copy_to_iter+0x36c/0x33f0
+   __skb_datagram_iter+0x196/0x12c0
+   skb_copy_datagram_iter+0x5b/0x210
+   netlink_recvmsg+0x37b/0xef0
+   ...
+  Uninit was created at:
+   __alloc_skb+0x8ca/0x10e0
+   mpls_getroute+0x1280/0x3a40
+   rtnetlink_rcv_msg+0x1138/0x15a0
+   ...
+  Byte 19 of 64 is uninitialized
+
+(byte 19 = nlmsghdr(16) + rtmsg offset 3 = rtm_tos)
+
+Fixes: 397fc9e5cefe ("mpls: route get support")
+Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
+Link: https://patch.msgid.link/20260723010830.289917-1-yhlee@isslab.korea.ac.kr
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 35069183f59c..1ad5a2d9b6cd 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2541,6 +2541,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
+       r->rtm_family    = AF_MPLS;
+       r->rtm_dst_len  = 20;
+       r->rtm_src_len  = 0;
++      r->rtm_tos      = 0;
+       r->rtm_table    = RT_TABLE_MAIN;
+       r->rtm_type     = RTN_UNICAST;
+       r->rtm_scope    = RT_SCOPE_UNIVERSE;
+-- 
+2.53.0
+
diff --git a/staging-7.1/series b/staging-7.1/series
new file mode 100644 (file)
index 0000000..20e097a
--- /dev/null
@@ -0,0 +1 @@
+net-mpls-initialize-rtm_tos-in-mpls_getroute.patch