From bf45d4c4191f03b3bf113e121701c74e129807d7 Mon Sep 17 00:00:00 2001 From: RHEL Packaging Agent Date: Tue, 11 Aug 2026 14:40:54 +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 rtph264depay and rtph265depay elements. The patch limits the maximum fragmentation unit size (defaulting to 32MB) to prevent excessive memory usage, and properly resets internal state fields when errors occur during fragmentation unit handling. CVE: CVE-2026-18649 Upstream patches: - https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12234.patch Resolves: RHEL-224159 This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent. Assisted-by: Ymir --- ...1-plugins-good-1.26.7-CVE-2026-18649.patch | 288 ++++++++++++++++++ gstreamer1-plugins-good.spec | 8 +- 2 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 gstreamer1-plugins-good-1.26.7-CVE-2026-18649.patch diff --git a/gstreamer1-plugins-good-1.26.7-CVE-2026-18649.patch b/gstreamer1-plugins-good-1.26.7-CVE-2026-18649.patch new file mode 100644 index 0000000..c3dc064 --- /dev/null +++ b/gstreamer1-plugins-good-1.26.7-CVE-2026-18649.patch @@ -0,0 +1,288 @@ +From 434aec750431e62eac02ee762e79299b3958f97f 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 | 39 +++++++++++++++++ + .../gst/rtp/gstrtph265depay.h | 1 + + 4 files changed, 83 insertions(+), 1 deletion(-) + +diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c +index bf9b1050f9..55b8b02b4c 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; +@@ -195,6 +203,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, +@@ -227,6 +253,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 +@@ -1465,8 +1493,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 ac1f0106f4..27486bf441 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.h ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.h +@@ -76,6 +76,7 @@ struct _GstRtpH264Depay + gboolean request_keyframe; + gboolean waiting_for_keyframe; + gboolean requesting_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 177a1103e8..50e24a32e7 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c +@@ -41,12 +41,14 @@ GST_DEBUG_CATEGORY_STATIC (rtph265depay_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, + }; + + +@@ -142,6 +144,9 @@ gst_rtp_h265_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; +@@ -161,6 +166,9 @@ gst_rtp_h265_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; +@@ -212,6 +220,24 @@ gst_rtp_h265_depay_class_init (GstRtpH265DepayClass * klass) + DEFAULT_REQUEST_KEYFRAME, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + ++ /** ++ * 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); + gst_element_class_add_static_pad_template (gstelement_class, +@@ -249,6 +275,8 @@ gst_rtp_h265_depay_init (GstRtpH265Depay * rtph265depay) + (GDestroyNotify) gst_buffer_unref); + rtph265depay->wait_for_keyframe = DEFAULT_WAIT_FOR_KEYFRAME; + rtph265depay->request_keyframe = DEFAULT_REQUEST_KEYFRAME; ++ rtph265depay->max_fragmentation_unit_size = ++ DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE; + } + + static void +@@ -1703,6 +1731,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 fc6248e85c..45d9466f7a 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.h ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.h +@@ -91,6 +91,7 @@ struct _GstRtpH265Depay + gboolean request_keyframe; + gboolean waiting_for_keyframe; + gboolean requesting_keyframe; ++ guint max_fragmentation_unit_size; + }; + + struct _GstRtpH265DepayClass + +From ab66eaae2f4ef0a4e017f980fa62d2c2f01f46a9 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 | 6 ++++++ + subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c | 6 ++++++ + 2 files changed, 12 insertions(+) + +diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c +index 55b8b02b4c..44ddc5b0fa 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph264depay.c +@@ -1467,6 +1467,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_rtp_base_depayload_flush (depayload, FALSE); + gst_adapter_clear (rtph264depay->adapter); + return NULL; +@@ -1503,6 +1506,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); ++ rtph264depay->wait_start = TRUE; ++ rtph264depay->current_fu_type = 0; ++ rtph264depay->last_fu_seqnum = 0; + gst_rtp_base_depayload_flush (depayload, FALSE); + 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 50e24a32e7..5748f51f69 100644 +--- a/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c ++++ b/subprojects/gst-plugins-good/gst/rtp/gstrtph265depay.c +@@ -1699,6 +1699,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_rtp_base_depayload_flush (depayload, FALSE); + gst_adapter_clear (rtph265depay->adapter); + return NULL; +@@ -1738,6 +1741,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); ++ rtph265depay->wait_start = TRUE; ++ rtph265depay->current_fu_type = 0; ++ rtph265depay->last_fu_seqnum = 0; + gst_rtp_base_depayload_flush (depayload, FALSE); + gst_adapter_clear (rtph265depay->adapter); + return NULL; diff --git a/gstreamer1-plugins-good.spec b/gstreamer1-plugins-good.spec index 24e17d9..8d43aaa 100644 --- a/gstreamer1-plugins-good.spec +++ b/gstreamer1-plugins-good.spec @@ -35,7 +35,7 @@ Name: gstreamer1-plugins-good Version: 1.26.7 -Release: 3%{?dist} +Release: 4%{?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 @@ -58,6 +58,8 @@ Source1: gstreamer-good.appdata.xml Patch: 0001-rtpqdm2depay-error-out-if-anyone-tries-to-use-this-e.patch # https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/11797 Patch: gstreamer1-plugins-good-1.26.7-CVE-2026-53705.patch +# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12234 +Patch: gstreamer1-plugins-good-1.26.7-CVE-2026-18649.patch BuildRequires: meson >= 0.48.0 BuildRequires: gcc @@ -378,6 +380,10 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -fv {} ';' %changelog +* Tue Aug 11 2026 RHEL Packaging Agent - 1.26.7-4 +- Fix RTP H264/H265 depayloader fragmentation unit handling (CVE-2026-18649) + Resolves: RHEL-224159 + * Wed Jul 29 2026 RHEL Packaging Agent - 1.26.7-3 - Fix integer overflow in wavpack decoder (CVE-2026-53705) Resolves: RHEL-184481