From 67028be52bfefd14d767aa0489b689bbb02625e3 Mon Sep 17 00:00:00 2001 From: RHEL Packaging Agent Date: Tue, 11 Aug 2026 14:49:39 +0000 Subject: [PATCH] Fix CVE-2026-18649: limit RTP H.264/H.265 fragmentation unit size Backport upstream MR 12234 to fix CVE-2026-18649 in gstreamer1-plugins-good-1.22.12. Adds a max-fragmentation-unit-size property (default 32MB) to both the H264 and H265 RTP depayloaders, dropping fragmentation units that exceed this limit to prevent excessive memory usage. Also properly resets internal state fields when discarding data during fragmentation unit handling. CVE: CVE-2026-18649 Upstream patches: - https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12234.patch Resolves: RHEL-224165 This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent. Assisted-by: Ymir --- ...-plugins-good-1.22.12-CVE-2026-18649.patch | 310 ++++++++++++++++++ gstreamer1-plugins-good.spec | 11 +- 2 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 gstreamer1-plugins-good-1.22.12-CVE-2026-18649.patch diff --git a/gstreamer1-plugins-good-1.22.12-CVE-2026-18649.patch b/gstreamer1-plugins-good-1.22.12-CVE-2026-18649.patch new file mode 100644 index 0000000..0f851a6 --- /dev/null +++ b/gstreamer1-plugins-good-1.22.12-CVE-2026-18649.patch @@ -0,0 +1,310 @@ +From f92e4319eed01faea1a93360cd29008e211973cc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= +Date: Wed, 29 Jul 2026 17:39:56 +0300 +Subject: [PATCH 1/2] rtph264depay: rtph265depay: Limit the maximum + fragmentation unit size + +Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5224 + +Part-of: +--- + .../gst/rtp/gstrtph264depay.c | 43 ++++++++++- + .../gst/rtp/gstrtph264depay.h | 1 + + .../gst/rtp/gstrtph265depay.c | 71 +++++++++++++++++++ + .../gst/rtp/gstrtph265depay.h | 2 + + 4 files changed, 116 insertions(+), 1 deletion(-) + +diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c +index 9cef347c21..9ccd8ab24e 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c +@@ -41,12 +41,14 @@ GST_DEBUG_CATEGORY_STATIC (rtph264depay_debug); + #define DEFAULT_ACCESS_UNIT FALSE + #define DEFAULT_WAIT_FOR_KEYFRAME FALSE + #define DEFAULT_REQUEST_KEYFRAME FALSE ++#define DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE (32 * 1024 * 1024) + + enum + { + PROP_0, + PROP_WAIT_FOR_KEYFRAME, + PROP_REQUEST_KEYFRAME, ++ PROP_MAX_FRAGMENTATION_UNIT_SIZE, + }; + + +@@ -126,6 +128,9 @@ gst_rtp_h264_depay_set_property (GObject * object, guint prop_id, + case PROP_REQUEST_KEYFRAME: + self->request_keyframe = g_value_get_boolean (value); + break; ++ 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; +@@ -145,6 +150,9 @@ gst_rtp_h264_depay_get_property (GObject * object, guint prop_id, + case PROP_REQUEST_KEYFRAME: + g_value_set_boolean (value, self->request_keyframe); + break; ++ 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; +@@ -194,6 +202,24 @@ gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass) + DEFAULT_REQUEST_KEYFRAME, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + ++ /** ++ * 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. ++ * ++ * Since: 1.28.6 ++ */ ++ 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); + gst_element_class_add_static_pad_template (gstelement_class, +@@ -223,6 +249,8 @@ gst_rtp_h264_depay_init (GstRtpH264Depay * rtph264depay) + (GDestroyNotify) gst_buffer_unref); + rtph264depay->wait_for_keyframe = DEFAULT_WAIT_FOR_KEYFRAME; + rtph264depay->request_keyframe = DEFAULT_REQUEST_KEYFRAME; ++ rtph264depay->max_fragmentation_unit_size = ++ DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE; + } + + static void +@@ -1396,8 +1424,21 @@ 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); ++ gst_rtp_base_depayload_flush (depayload, FALSE); ++ gst_adapter_clear (rtph264depay->adapter); ++ return NULL; ++ } ++ } + break; + } + default: +diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.h b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.h +index 8ca7381beb..ae3ee4a6e2 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.h ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.h +@@ -75,6 +75,7 @@ struct _GstRtpH264Depay + gboolean wait_for_keyframe; + gboolean request_keyframe; + gboolean waiting_for_keyframe; ++ guint max_fragmentation_unit_size; + }; + + struct _GstRtpH264DepayClass +diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c +index 41d2762ffe..b8d2943228 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c +@@ -39,6 +39,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 }; +@@ -119,6 +126,37 @@ static void gst_rtp_h265_depay_push (GstRtpH265Depay * rtph265depay, + GstBuffer * outbuf, gboolean keyframe, GstClockTime timestamp, + gboolean marker); + ++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_class_init (GstRtpH265DepayClass * klass) +@@ -132,6 +170,26 @@ 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. ++ * ++ * Since: 1.28.6 ++ */ ++ 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); +@@ -165,6 +223,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 +@@ -1516,6 +1576,17 @@ 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); ++ gst_rtp_base_depayload_flush (depayload, FALSE); ++ gst_adapter_clear (rtph265depay->adapter); ++ return NULL; ++ } + } + break; + } +diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.h b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.h +index 505bdb5cd1..6e525cc086 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.h ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.h +@@ -86,6 +86,8 @@ struct _GstRtpH265Depay + /* downstream allocator */ + GstAllocator *allocator; + GstAllocationParams params; ++ ++ guint max_fragmentation_unit_size; + }; + + struct _GstRtpH265DepayClass + +From 8c6d8dceb16dbde77e451d5b122b864b8420aa75 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= +Date: Tue, 4 Aug 2026 20:05:57 +0300 +Subject: [PATCH 2/2] rtph264depay: rtph265depay: Reset missing fields when + resetting during fragmentation unit handling + +Part-of: +--- + subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c | 7 ++++++- + subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c | 7 ++++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c +index 9ccd8ab24e..5467a51848 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c +@@ -1399,6 +1399,9 @@ gst_rtp_h264_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp) + "%u to %u within Fragmentation Unit. Data was lost, dropping " + "stored.", rtph264depay->last_fu_seqnum, + gst_rtp_buffer_get_seq (rtp)); ++ rtph264depay->wait_start = TRUE; ++ rtph264depay->current_fu_type = 0; ++ rtph264depay->last_fu_seqnum = 0; + gst_adapter_clear (rtph264depay->adapter); + return NULL; + } +@@ -1434,7 +1437,9 @@ gst_rtp_h264_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp) + if (gst_adapter_available (rtph264depay->adapter) > limit) { + GST_WARNING_OBJECT (rtph264depay, + "Too big (> %u bytes) fragmentation unit, dropping.", limit); +- gst_rtp_base_depayload_flush (depayload, FALSE); ++ rtph264depay->wait_start = TRUE; ++ rtph264depay->current_fu_type = 0; ++ rtph264depay->last_fu_seqnum = 0; + gst_adapter_clear (rtph264depay->adapter); + return NULL; + } +diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c +index b8d2943228..c555835436 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c +@@ -1545,6 +1545,9 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp) + "%u to %u within Fragmentation Unit. Data was lost, dropping " + "stored.", rtph265depay->last_fu_seqnum, + gst_rtp_buffer_get_seq (rtp)); ++ rtph265depay->wait_start = TRUE; ++ rtph265depay->current_fu_type = 0; ++ rtph265depay->last_fu_seqnum = 0; + gst_adapter_clear (rtph265depay->adapter); + return NULL; + } +@@ -1583,7 +1586,9 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp) + if (gst_adapter_available (rtph265depay->adapter) > limit) { + GST_WARNING_OBJECT (rtph265depay, + "Too big (> %u bytes) fragmentation unit, dropping.", limit); +- gst_rtp_base_depayload_flush (depayload, FALSE); ++ rtph265depay->wait_start = TRUE; ++ rtph265depay->current_fu_type = 0; ++ rtph265depay->last_fu_seqnum = 0; + gst_adapter_clear (rtph265depay->adapter); + return NULL; + } diff --git a/gstreamer1-plugins-good.spec b/gstreamer1-plugins-good.spec index e763ed1..b08e2fc 100644 --- a/gstreamer1-plugins-good.spec +++ b/gstreamer1-plugins-good.spec @@ -28,7 +28,7 @@ Name: gstreamer1-plugins-good Version: 1.22.12 -Release: 8%{?dist} +Release: 9%{?dist} Summary: GStreamer plugins with good code and licensing License: CC0-1.0 AND GPL-2.0-only AND LGPL-2.0-only AND LGPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND xlock AND MIT AND BSD-3-Clause AND CC-BY-3.0 @@ -80,6 +80,9 @@ Patch0029: 0001-rtpqdm2depay-error-out-if-anyone-tries-to-use-this-e.patch # https://issues.redhat.com/browse/RHEL-184478 # https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11797 Patch0030: gstreamer1-plugins-good-1.22.12-CVE-2026-53705.patch +# https://issues.redhat.com/browse/RHEL-224165 +# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12234 +Patch0031: gstreamer1-plugins-good-1.22.12-CVE-2026-18649.patch BuildRequires: meson >= 0.48.0 BuildRequires: gcc @@ -269,6 +272,7 @@ to be installed. %patch -P 0028 -p3 %patch -P 0029 -p3 %patch -P 0030 -p3 +%patch -P 0031 -p3 %build %meson \ @@ -419,6 +423,11 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -fv {} ';' %changelog +* Tue Aug 11 2026 RHEL Packaging Agent - 1.22.12-9 +- Limit maximum fragmentation unit size in RTP H264/H265 + depayloaders to prevent excessive memory usage + (CVE-2026-18649) + * Wed Jul 29 2026 RHEL Packaging Agent - 1.22.12-8 - Fix integer overflows in wavpackdec (CVE-2026-53705)