Fix CVE-2026-18649 in H.264/H.265 RTP depayloaders
Backport CVE-2026-18649 fix from upstream GStreamer MR 12244 to gstreamer1-plugins-good 1.16.1. The patch adds a max-fragmentation-unit-size property (default 32 MB) to both H.264 and H.265 RTP depayloaders. If a fragmentation unit exceeds this limit while being assembled, it is dropped and the depayloader state is reset, preventing excessive memory usage from crafted RTP streams. CVE: CVE-2026-18649 Upstream patches: - https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12244.patch Resolves: RHEL-224145 This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent. Assisted-by: Ymir
This commit is contained in:
parent
1a5072bc97
commit
14df9f8d70
296
gstreamer1-plugins-good-1.16.1-CVE-2026-18649.patch
Normal file
296
gstreamer1-plugins-good-1.16.1-CVE-2026-18649.patch
Normal file
@ -0,0 +1,296 @@
|
||||
From 07cbde0479905b968c54f6ca22999aa9b62bd653 Mon Sep 17 00:00:00 2001
|
||||
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
|
||||
Date: Fri, 7 Aug 2026 14:34:04 +0000
|
||||
Subject: [PATCH] rtph264depay: rtph265depay: Limit the maximum fragmentation
|
||||
unit size
|
||||
|
||||
Adds a max-fragmentation-unit-size property (default 32 MB) to both
|
||||
H.264 and H.265 RTP depayloaders. If a fragmentation unit exceeds
|
||||
this limit while being assembled, it is dropped and the depayloader
|
||||
state is reset to prevent excessive memory usage.
|
||||
|
||||
Adapted from upstream commits:
|
||||
- 5cd490c125e04676659593b0f5b19130fc2face7
|
||||
- 820bd15585b13af8be9b0131699655194ae68a5b
|
||||
|
||||
Fixes: CVE-2026-18649
|
||||
---
|
||||
gst/rtp/gstrtph264depay.c | 79 ++++++++++++++++++++++++++++++++++++++-
|
||||
gst/rtp/gstrtph264depay.h | 2 +
|
||||
gst/rtp/gstrtph265depay.c | 75 +++++++++++++++++++++++++++++++++++++
|
||||
gst/rtp/gstrtph265depay.h | 2 +
|
||||
4 files changed, 157 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gst/rtp/gstrtph264depay.c b/gst/rtp/gstrtph264depay.c
|
||||
index 275a9a0..625244f 100644
|
||||
--- a/gst/rtp/gstrtph264depay.c
|
||||
+++ b/gst/rtp/gstrtph264depay.c
|
||||
@@ -38,6 +38,13 @@ GST_DEBUG_CATEGORY_STATIC (rtph264depay_debug);
|
||||
* expressed a restriction or preference via caps */
|
||||
#define DEFAULT_BYTE_STREAM TRUE
|
||||
#define DEFAULT_ACCESS_UNIT FALSE
|
||||
+#define DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE (32 * 1024 * 1024)
|
||||
+
|
||||
+enum
|
||||
+{
|
||||
+ PROP_0,
|
||||
+ PROP_MAX_FRAGMENTATION_UNIT_SIZE,
|
||||
+};
|
||||
|
||||
/* 3 zero bytes syncword */
|
||||
static const guint8 sync_bytes[] = { 0, 0, 0, 1 };
|
||||
@@ -83,6 +90,10 @@ G_DEFINE_TYPE (GstRtpH264Depay, gst_rtp_h264_depay,
|
||||
GST_TYPE_RTP_BASE_DEPAYLOAD);
|
||||
|
||||
static void gst_rtp_h264_depay_finalize (GObject * object);
|
||||
+static void gst_rtp_h264_depay_set_property (GObject * object, guint prop_id,
|
||||
+ const GValue * value, GParamSpec * pspec);
|
||||
+static void gst_rtp_h264_depay_get_property (GObject * object, guint prop_id,
|
||||
+ GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtp_h264_depay_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
@@ -111,6 +122,24 @@ gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass)
|
||||
gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_rtp_h264_depay_finalize;
|
||||
+ gobject_class->set_property = gst_rtp_h264_depay_set_property;
|
||||
+ gobject_class->get_property = gst_rtp_h264_depay_get_property;
|
||||
+
|
||||
+ /**
|
||||
+ * GstRtpH264Depay:max-fragmentation-unit-size:
|
||||
+ *
|
||||
+ * Maximum size in bytes for a fragmentation unit. Larger units
|
||||
+ * will be dropped to prevent excessive memory usage.
|
||||
+ *
|
||||
+ * Use 0 for automatic.
|
||||
+ */
|
||||
+ g_object_class_install_property (gobject_class,
|
||||
+ PROP_MAX_FRAGMENTATION_UNIT_SIZE,
|
||||
+ g_param_spec_uint ("max-fragmentation-unit-size",
|
||||
+ "Max Fragmentation Unit Size",
|
||||
+ "Maximum size in bytes for a fragmentation unit (0 = auto)", 0,
|
||||
+ G_MAXUINT, DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE,
|
||||
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_add_static_pad_template (gstelement_class,
|
||||
&gst_rtp_h264_depay_src_template);
|
||||
@@ -128,6 +157,38 @@ gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass)
|
||||
gstrtpbasedepayload_class->handle_event = gst_rtp_h264_depay_handle_event;
|
||||
}
|
||||
|
||||
+static void
|
||||
+gst_rtp_h264_depay_set_property (GObject * object, guint prop_id,
|
||||
+ const GValue * value, GParamSpec * pspec)
|
||||
+{
|
||||
+ GstRtpH264Depay *self = GST_RTP_H264_DEPAY (object);
|
||||
+
|
||||
+ switch (prop_id) {
|
||||
+ case PROP_MAX_FRAGMENTATION_UNIT_SIZE:
|
||||
+ self->max_fragmentation_unit_size = g_value_get_uint (value);
|
||||
+ break;
|
||||
+ default:
|
||||
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+gst_rtp_h264_depay_get_property (GObject * object, guint prop_id,
|
||||
+ GValue * value, GParamSpec * pspec)
|
||||
+{
|
||||
+ GstRtpH264Depay *self = GST_RTP_H264_DEPAY (object);
|
||||
+
|
||||
+ switch (prop_id) {
|
||||
+ case PROP_MAX_FRAGMENTATION_UNIT_SIZE:
|
||||
+ g_value_set_uint (value, self->max_fragmentation_unit_size);
|
||||
+ break;
|
||||
+ default:
|
||||
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
gst_rtp_h264_depay_init (GstRtpH264Depay * rtph264depay)
|
||||
{
|
||||
@@ -139,6 +200,8 @@ gst_rtp_h264_depay_init (GstRtpH264Depay * rtph264depay)
|
||||
(GDestroyNotify) gst_buffer_unref);
|
||||
rtph264depay->pps = g_ptr_array_new_with_free_func (
|
||||
(GDestroyNotify) gst_buffer_unref);
|
||||
+ rtph264depay->max_fragmentation_unit_size =
|
||||
+ DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1241,8 +1304,22 @@ gst_rtp_h264_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
|
||||
rtph264depay->fu_marker = marker;
|
||||
|
||||
/* if NAL unit ends, flush the adapter */
|
||||
- if (E)
|
||||
+ if (E) {
|
||||
gst_rtp_h264_finish_fragmentation_unit (rtph264depay);
|
||||
+ GST_DEBUG_OBJECT (rtph264depay, "End of Fragmentation Unit");
|
||||
+ } else {
|
||||
+ guint limit = rtph264depay->max_fragmentation_unit_size ?
|
||||
+ rtph264depay->max_fragmentation_unit_size :
|
||||
+ DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE;
|
||||
+ if (gst_adapter_available (rtph264depay->adapter) > limit) {
|
||||
+ GST_WARNING_OBJECT (rtph264depay,
|
||||
+ "Too big (> %u bytes) fragmentation unit, dropping.", limit);
|
||||
+ rtph264depay->wait_start = TRUE;
|
||||
+ rtph264depay->current_fu_type = 0;
|
||||
+ gst_adapter_clear (rtph264depay->adapter);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
default:
|
||||
diff --git a/gst/rtp/gstrtph264depay.h b/gst/rtp/gstrtph264depay.h
|
||||
index ba41312..a02a65d 100644
|
||||
--- a/gst/rtp/gstrtph264depay.h
|
||||
+++ b/gst/rtp/gstrtph264depay.h
|
||||
@@ -62,6 +62,8 @@ struct _GstRtpH264Depay
|
||||
GstClockTime fu_timestamp;
|
||||
gboolean fu_marker;
|
||||
|
||||
+ guint max_fragmentation_unit_size;
|
||||
+
|
||||
/* misc */
|
||||
GPtrArray *sps;
|
||||
GPtrArray *pps;
|
||||
diff --git a/gst/rtp/gstrtph265depay.c b/gst/rtp/gstrtph265depay.c
|
||||
index 551e08a..b046030 100644
|
||||
--- a/gst/rtp/gstrtph265depay.c
|
||||
+++ b/gst/rtp/gstrtph265depay.c
|
||||
@@ -38,6 +38,13 @@ GST_DEBUG_CATEGORY_STATIC (rtph265depay_debug);
|
||||
* expressed a restriction or preference via caps */
|
||||
#define DEFAULT_STREAM_FORMAT GST_H265_STREAM_FORMAT_BYTESTREAM
|
||||
#define DEFAULT_ACCESS_UNIT FALSE
|
||||
+#define DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE (32 * 1024 * 1024)
|
||||
+
|
||||
+enum
|
||||
+{
|
||||
+ PROP_0,
|
||||
+ PROP_MAX_FRAGMENTATION_UNIT_SIZE,
|
||||
+};
|
||||
|
||||
/* 3 zero bytes syncword */
|
||||
static const guint8 sync_bytes[] = { 0, 0, 0, 1 };
|
||||
@@ -99,6 +106,10 @@ G_DEFINE_TYPE (GstRtpH265Depay, gst_rtp_h265_depay,
|
||||
GST_TYPE_RTP_BASE_DEPAYLOAD);
|
||||
|
||||
static void gst_rtp_h265_depay_finalize (GObject * object);
|
||||
+static void gst_rtp_h265_depay_set_property (GObject * object, guint prop_id,
|
||||
+ const GValue * value, GParamSpec * pspec);
|
||||
+static void gst_rtp_h265_depay_get_property (GObject * object, guint prop_id,
|
||||
+ GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtp_h265_depay_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
@@ -128,6 +139,24 @@ gst_rtp_h265_depay_class_init (GstRtpH265DepayClass * klass)
|
||||
gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_rtp_h265_depay_finalize;
|
||||
+ gobject_class->set_property = gst_rtp_h265_depay_set_property;
|
||||
+ gobject_class->get_property = gst_rtp_h265_depay_get_property;
|
||||
+
|
||||
+ /**
|
||||
+ * GstRtpH265Depay:max-fragmentation-unit-size:
|
||||
+ *
|
||||
+ * Maximum size in bytes for a fragmentation unit. Larger units
|
||||
+ * will be dropped to prevent excessive memory usage.
|
||||
+ *
|
||||
+ * Use 0 for automatic.
|
||||
+ */
|
||||
+ g_object_class_install_property (gobject_class,
|
||||
+ PROP_MAX_FRAGMENTATION_UNIT_SIZE,
|
||||
+ g_param_spec_uint ("max-fragmentation-unit-size",
|
||||
+ "Max Fragmentation Unit Size",
|
||||
+ "Maximum size in bytes for a fragmentation unit (0 = auto)", 0,
|
||||
+ G_MAXUINT, DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE,
|
||||
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_add_static_pad_template (gstelement_class,
|
||||
&gst_rtp_h265_depay_src_template);
|
||||
@@ -145,6 +174,38 @@ gst_rtp_h265_depay_class_init (GstRtpH265DepayClass * klass)
|
||||
gstrtpbasedepayload_class->handle_event = gst_rtp_h265_depay_handle_event;
|
||||
}
|
||||
|
||||
+static void
|
||||
+gst_rtp_h265_depay_set_property (GObject * object, guint prop_id,
|
||||
+ const GValue * value, GParamSpec * pspec)
|
||||
+{
|
||||
+ GstRtpH265Depay *self = GST_RTP_H265_DEPAY (object);
|
||||
+
|
||||
+ switch (prop_id) {
|
||||
+ case PROP_MAX_FRAGMENTATION_UNIT_SIZE:
|
||||
+ self->max_fragmentation_unit_size = g_value_get_uint (value);
|
||||
+ break;
|
||||
+ default:
|
||||
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+gst_rtp_h265_depay_get_property (GObject * object, guint prop_id,
|
||||
+ GValue * value, GParamSpec * pspec)
|
||||
+{
|
||||
+ GstRtpH265Depay *self = GST_RTP_H265_DEPAY (object);
|
||||
+
|
||||
+ switch (prop_id) {
|
||||
+ case PROP_MAX_FRAGMENTATION_UNIT_SIZE:
|
||||
+ g_value_set_uint (value, self->max_fragmentation_unit_size);
|
||||
+ break;
|
||||
+ default:
|
||||
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
gst_rtp_h265_depay_init (GstRtpH265Depay * rtph265depay)
|
||||
{
|
||||
@@ -161,6 +222,8 @@ gst_rtp_h265_depay_init (GstRtpH265Depay * rtph265depay)
|
||||
(GDestroyNotify) gst_buffer_unref);
|
||||
rtph265depay->pps = g_ptr_array_new_with_free_func (
|
||||
(GDestroyNotify) gst_buffer_unref);
|
||||
+ rtph265depay->max_fragmentation_unit_size =
|
||||
+ DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1520,6 +1583,18 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
|
||||
if (E) {
|
||||
gst_rtp_h265_finish_fragmentation_unit (rtph265depay);
|
||||
GST_DEBUG_OBJECT (rtph265depay, "End of Fragmentation Unit");
|
||||
+ } else {
|
||||
+ guint limit = rtph265depay->max_fragmentation_unit_size ?
|
||||
+ rtph265depay->max_fragmentation_unit_size :
|
||||
+ DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE;
|
||||
+ if (gst_adapter_available (rtph265depay->adapter) > limit) {
|
||||
+ GST_WARNING_OBJECT (rtph265depay,
|
||||
+ "Too big (> %u bytes) fragmentation unit, dropping.", limit);
|
||||
+ rtph265depay->wait_start = TRUE;
|
||||
+ rtph265depay->current_fu_type = 0;
|
||||
+ gst_adapter_clear (rtph265depay->adapter);
|
||||
+ return NULL;
|
||||
+ }
|
||||
}
|
||||
break;
|
||||
}
|
||||
diff --git a/gst/rtp/gstrtph265depay.h b/gst/rtp/gstrtph265depay.h
|
||||
index cf17694..e851d3b 100644
|
||||
--- a/gst/rtp/gstrtph265depay.h
|
||||
+++ b/gst/rtp/gstrtph265depay.h
|
||||
@@ -76,6 +76,8 @@ struct _GstRtpH265Depay
|
||||
GstClockTime fu_timestamp;
|
||||
gboolean fu_marker;
|
||||
|
||||
+ guint max_fragmentation_unit_size;
|
||||
+
|
||||
/* misc */
|
||||
GPtrArray *vps;
|
||||
GPtrArray *sps;
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
Name: gstreamer1-plugins-good
|
||||
Version: 1.16.1
|
||||
Release: 7%{?gitcommit:.git%{shortcommit}}%{?dist}.1
|
||||
Release: 7%{?gitcommit:.git%{shortcommit}}%{?dist}.2
|
||||
Summary: GStreamer plugins with good code and licensing
|
||||
|
||||
License: LGPLv2+
|
||||
@ -45,6 +45,9 @@ Patch10: gstreamer1-plugins-good-1.16.1-CVE-2026-53705.patch
|
||||
# https://issues.redhat.com/browse/RHEL-239068
|
||||
# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12231
|
||||
Patch11: gstreamer1-plugins-good-1.16.1-CVE-2026-73433.patch
|
||||
# https://issues.redhat.com/browse/RHEL-224145
|
||||
# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12244
|
||||
Patch12: gstreamer1-plugins-good-1.16.1-CVE-2026-18649.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc-c++
|
||||
@ -190,6 +193,7 @@ to be installed.
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
|
||||
%build
|
||||
%configure --disable-silent-rules --disable-fatal-warnings \
|
||||
@ -374,6 +378,10 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Aug 13 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 1.16.1-7.2
|
||||
- Fix CVE-2026-18649 in H.264/H.265 RTP depayloaders
|
||||
Resolves: RHEL-224145
|
||||
|
||||
* Thu Aug 13 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 1.16.1-7.1
|
||||
- Fix multiple security issues in AVI demuxer (CVE-2026-73433)
|
||||
Resolves: RHEL-239068
|
||||
|
||||
Loading…
Reference in New Issue
Block a user