From 340af9ec5155153b5d7d09528392e0d6e1d2db8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= <tim@centricular.com>
Date: Thu, 24 Sep 2026 11:59:50 +0100
Subject: [PATCH] rtpL8depay, rtpL16depay, rtpL24depay: fix out of bounds write
 for high channel count

The positions array is only 64 entries large, but if a high channel count
is signalled in the SDP we might try to initialise more entries than are
available and write beyond the end of the array.

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5271

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5306

Fixes ZDI-CAN-31143

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12642>

Upstream-Status: Backport [80c184b4c5ee8ba28b2540ba58f40b8d44b61622]
CVE: CVE-2026-111183
---
 gst/rtp/gstrtpL16depay.c | 3 ++-
 gst/rtp/gstrtpL24depay.c | 3 ++-
 gst/rtp/gstrtpL8depay.c  | 3 ++-
 gst/rtp/gstrtpchannels.c | 5 ++++-
 gst/rtp/gstrtpchannels.h | 4 +++-
 5 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/gst/rtp/gstrtpL16depay.c b/gst/rtp/gstrtpL16depay.c
index aa7e5d03da..e86dd7c476 100644
--- a/gst/rtp/gstrtpL16depay.c
+++ b/gst/rtp/gstrtpL16depay.c
@@ -211,7 +211,8 @@ gst_rtp_L16_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
         (NULL), ("Unknown channel order '%s' for %d channels",
             GST_STR_NULL (channel_order), channels));
     /* create default NONE layout */
-    gst_rtp_channels_create_default (channels, info->position);
+    gst_rtp_channels_create_default (channels, info->position,
+        G_N_ELEMENTS (info->position));
     info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
   }
 
diff --git a/gst/rtp/gstrtpL24depay.c b/gst/rtp/gstrtpL24depay.c
index e39fe7c2f4..9bcd981cc1 100644
--- a/gst/rtp/gstrtpL24depay.c
+++ b/gst/rtp/gstrtpL24depay.c
@@ -189,7 +189,8 @@ gst_rtp_L24_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
         (NULL), ("Unknown channel order '%s' for %d channels",
             GST_STR_NULL (channel_order), channels));
     /* create default NONE layout */
-    gst_rtp_channels_create_default (channels, info->position);
+    gst_rtp_channels_create_default (channels, info->position,
+        G_N_ELEMENTS (info->position));
     info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
   }
 
diff --git a/gst/rtp/gstrtpL8depay.c b/gst/rtp/gstrtpL8depay.c
index f1c0fe3024..ff28909a79 100644
--- a/gst/rtp/gstrtpL8depay.c
+++ b/gst/rtp/gstrtpL8depay.c
@@ -190,7 +190,8 @@ gst_rtp_L8_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
         (NULL), ("Unknown channel order '%s' for %d channels",
             GST_STR_NULL (channel_order), channels));
     /* create default NONE layout */
-    gst_rtp_channels_create_default (channels, info->position);
+    gst_rtp_channels_create_default (channels, info->position,
+        G_N_ELEMENTS (info->position));
     info->flags |= GST_AUDIO_FLAG_UNPOSITIONED;
   }
 
diff --git a/gst/rtp/gstrtpchannels.c b/gst/rtp/gstrtpchannels.c
index d0694cb821..9fbf288f84 100644
--- a/gst/rtp/gstrtpchannels.c
+++ b/gst/rtp/gstrtpchannels.c
@@ -299,12 +299,15 @@ gst_rtp_channels_get_by_index (gint channels, guint idx)
  * #GST_AUDIO_CHANNEL_POSITION_NONE.
  */
 void
-gst_rtp_channels_create_default (gint channels, GstAudioChannelPosition * posn)
+gst_rtp_channels_create_default (gint channels,
+    GstAudioChannelPosition * posn, gsize n_posn)
 {
   gint i;
 
   g_return_if_fail (channels > 0);
 
+  channels = MIN (channels, n_posn);
+
   for (i = 0; i < channels; i++)
     posn[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
 }
diff --git a/gst/rtp/gstrtpchannels.h b/gst/rtp/gstrtpchannels.h
index 6d3f530902..42c39a4021 100644
--- a/gst/rtp/gstrtpchannels.h
+++ b/gst/rtp/gstrtpchannels.h
@@ -41,6 +41,8 @@ const GstRTPChannelOrder *   gst_rtp_channels_get_by_order   (gint channels,
                                                               const gchar *order);
 const GstRTPChannelOrder *   gst_rtp_channels_get_by_index   (gint channels, guint idx);
 
-void                         gst_rtp_channels_create_default (gint channels, GstAudioChannelPosition *pos);
+void                         gst_rtp_channels_create_default (gint channels,
+                                                              GstAudioChannelPosition *pos,
+                                                              gsize n_posn);
 
 #endif /* __GST_RTP_CHANNELS_H__ */
