From 157a2dda085aba1eb7f757884dc6befce12b98f4 Mon Sep 17 00:00:00 2001 From: RHEL Packaging Agent Date: Sat, 22 Aug 2026 13:07:25 +0000 Subject: [PATCH] Fix CVE-2026-18296: heap buffer overflow in qtmoovrecover Backport upstream commit 93fa4cd30ba43b38b02a9de76a7a80dc198c87a0 (qtmoovrecover: Validate box sizes) to fix CVE-2026-18295 and CVE-2026-18296. The patch adds box size validation and box version checks to gst/isomp4/atomsrecovery.c. The upstream patch was adapted from the GStreamer monorepo layout to match the standalone gst-plugins-good-1.16.1 source tree. CVE: CVE-2026-18295 CVE-2026-18296 Upstream patches: - https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/93fa4cd30ba43b38b02a9de76a7a80dc198c87a0.patch Resolves: RHEL-246382 This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent. Assisted-by: Ymir --- ...mer1-plugins-good-1.16.1-RHEL-246382.patch | 259 ++++++++++++++++++ gstreamer1-plugins-good.spec | 8 +- 2 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 gstreamer1-plugins-good-1.16.1-RHEL-246382.patch diff --git a/gstreamer1-plugins-good-1.16.1-RHEL-246382.patch b/gstreamer1-plugins-good-1.16.1-RHEL-246382.patch new file mode 100644 index 0000000..c7b75cd --- /dev/null +++ b/gstreamer1-plugins-good-1.16.1-RHEL-246382.patch @@ -0,0 +1,259 @@ +From ea37cc1d2be268244adfb01ead08eaf024430456 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= +Date: Wed, 17 Jun 2026 16:18:50 +0300 +Subject: [PATCH] qtmoovrecover: Validate box sizes + +Also validate box versions where it matters. + +Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5118 +Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5120 + +Part-of: +--- + gst/isomp4/atomsrecovery.c | 88 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 84 insertions(+), 4 deletions(-) + +diff --git a/gst/isomp4/atomsrecovery.c b/gst/isomp4/atomsrecovery.c +index edc4434..1761854 100644 +--- a/gst/isomp4/atomsrecovery.c ++++ b/gst/isomp4/atomsrecovery.c +@@ -283,6 +283,8 @@ moov_recov_file_parse_prefix (MoovRecovFile * moovrf) + if (!read_atom_header (moovrf->file, &fourcc, &size)) { + return FALSE; + } ++ if (size < 8) ++ return FALSE; + + if (fourcc != FOURCC_ftyp) { + /* we might have a prefix here */ +@@ -294,6 +296,8 @@ moov_recov_file_parse_prefix (MoovRecovFile * moovrf) + /* now read the ftyp */ + if (!read_atom_header (moovrf->file, &fourcc, &size)) + return FALSE; ++ if (size < 8) ++ return FALSE; + } + + /* this has to be the ftyp */ +@@ -315,12 +319,25 @@ moov_recov_file_parse_mvhd (MoovRecovFile * moovrf) + /* check for sanity */ + if (fourcc != FOURCC_mvhd) + return FALSE; ++ if (size < 8) ++ return FALSE; + + moovrf->mvhd_size = size; + moovrf->mvhd_pos = ftell (moovrf->file) - 8; + ++ guint8 version; ++ if (fread (&version, 1, 1, moovrf->file) != 1) ++ return FALSE; ++ if (version != 0) { ++ GST_WARNING ("Version %d mvhd not supported", version); ++ return FALSE; ++ } ++ ++ if (size != 108) ++ return FALSE; ++ + /* skip the remaining of the mvhd in the file */ +- return fseek (moovrf->file, size - 8, SEEK_CUR) == 0; ++ return fseek (moovrf->file, size - 8 - 1, SEEK_CUR) == 0; + } + + static gboolean +@@ -357,6 +374,8 @@ mdat_recov_file_find_mdat (FILE * file, GError ** err) + case FOURCC_ftyp: + case FOURCC_free: + case FOURCC_udta: ++ if (size < 8) ++ return FALSE; + if (fseek (file, size - 8, SEEK_CUR) != 0) { + goto file_seek_error; + } +@@ -486,6 +505,8 @@ skip_atom (MoovRecovFile * moovrf, guint32 expected_fourcc) + return FALSE; + if (fourcc != expected_fourcc) + return FALSE; ++ if (size < 8) ++ return FALSE; + + return (fseek (moovrf->file, size - 8, SEEK_CUR) == 0); + } +@@ -502,11 +523,24 @@ moov_recov_parse_tkhd (MoovRecovFile * moovrf, TrakRecovData * trakrd) + return FALSE; + if (fourcc != FOURCC_tkhd) + return FALSE; ++ if (size < 8) ++ return FALSE; + + trakrd->tkhd_file_offset = ftell (moovrf->file) - 8; + +- /* move 8 bytes forward to the trak_id pos */ +- if (fseek (moovrf->file, 12, SEEK_CUR) != 0) ++ guint8 version; ++ if (fread (&version, 1, 1, moovrf->file) != 1) ++ return FALSE; ++ if (version != 0) { ++ GST_WARNING ("Version %d tkhd not supported", version); ++ return FALSE; ++ } ++ ++ if (size != 92) ++ return FALSE; ++ ++ /* move 12-1 bytes forward to the trak_id pos */ ++ if (fseek (moovrf->file, 12 - 1, SEEK_CUR) != 0) + return FALSE; + if (fread (data, 1, 4, moovrf->file) != 4) + return FALSE; +@@ -530,6 +564,8 @@ moov_recov_parse_stbl (MoovRecovFile * moovrf, TrakRecovData * trakrd) + return FALSE; + if (fourcc != FOURCC_stbl) + return FALSE; ++ if (size < 8) ++ return FALSE; + + trakrd->stbl_file_offset = ftell (moovrf->file) - 8; + trakrd->stbl_size = size; +@@ -539,12 +575,17 @@ moov_recov_parse_stbl (MoovRecovFile * moovrf, TrakRecovData * trakrd) + return FALSE; + if (fourcc != FOURCC_stsd) + return FALSE; ++ if (auxsize < 8) ++ return FALSE; + if (fseek (moovrf->file, auxsize - 8, SEEK_CUR) != 0) + return FALSE; + + trakrd->stsd_size = auxsize; + trakrd->post_stsd_offset = ftell (moovrf->file); + ++ if (trakrd->stbl_size < trakrd->post_stsd_offset - trakrd->stbl_file_offset) ++ return FALSE; ++ + /* as this is the last atom we parse, we don't skip forward */ + + return TRUE; +@@ -556,11 +597,14 @@ moov_recov_parse_minf (MoovRecovFile * moovrf, TrakRecovData * trakrd) + guint32 size; + guint32 fourcc; + guint32 auxsize; ++ guint64 offset; + + if (!read_atom_header (moovrf->file, &fourcc, &size)) + return FALSE; + if (fourcc != FOURCC_minf) + return FALSE; ++ if (size < 8) ++ return FALSE; + + trakrd->minf_file_offset = ftell (moovrf->file) - 8; + trakrd->minf_size = size; +@@ -571,17 +615,23 @@ moov_recov_parse_minf (MoovRecovFile * moovrf, TrakRecovData * trakrd) + if (fourcc != FOURCC_vmhd && fourcc != FOURCC_smhd && fourcc != FOURCC_hmhd && + fourcc != FOURCC_gmhd) + return FALSE; ++ if (auxsize < 8) ++ return FALSE; + if (fseek (moovrf->file, auxsize - 8, SEEK_CUR)) + return FALSE; + + /* skip a possible hdlr and the following dinf */ + if (!read_atom_header (moovrf->file, &fourcc, &auxsize)) + return FALSE; ++ if (auxsize < 8) ++ return FALSE; + if (fourcc == FOURCC_hdlr) { + if (fseek (moovrf->file, auxsize - 8, SEEK_CUR)) + return FALSE; + if (!read_atom_header (moovrf->file, &fourcc, &auxsize)) + return FALSE; ++ if (auxsize < 8) ++ return FALSE; + } + if (fourcc != FOURCC_dinf) + return FALSE; +@@ -592,6 +642,10 @@ moov_recov_parse_minf (MoovRecovFile * moovrf, TrakRecovData * trakrd) + if (!moov_recov_parse_stbl (moovrf, trakrd)) + return FALSE; + ++ offset = ftell (moovrf->file); ++ if (trakrd->minf_size < offset - trakrd->minf_file_offset) ++ return FALSE; ++ + return TRUE; + } + +@@ -607,11 +661,24 @@ moov_recov_parse_mdhd (MoovRecovFile * moovrf, TrakRecovData * trakrd) + return FALSE; + if (fourcc != FOURCC_mdhd) + return FALSE; ++ if (size < 8) ++ return FALSE; + + trakrd->mdhd_file_offset = ftell (moovrf->file) - 8; + ++ guint8 version; ++ if (fread (&version, 1, 1, moovrf->file) != 1) ++ return FALSE; ++ if (version != 0) { ++ GST_WARNING ("Version %d mdhd not supported", version); ++ return FALSE; ++ } ++ ++ if (size != 32) ++ return FALSE; ++ + /* get the timescale */ +- if (fseek (moovrf->file, 12, SEEK_CUR) != 0) ++ if (fseek (moovrf->file, 12 - 1, SEEK_CUR) != 0) + return FALSE; + if (fread (data, 1, 4, moovrf->file) != 4) + return FALSE; +@@ -626,12 +693,15 @@ moov_recov_parse_mdia (MoovRecovFile * moovrf, TrakRecovData * trakrd) + { + guint32 size; + guint32 fourcc; ++ guint64 offset; + + /* make sure we are on a tkhd atom */ + if (!read_atom_header (moovrf->file, &fourcc, &size)) + return FALSE; + if (fourcc != FOURCC_mdia) + return FALSE; ++ if (size < 8) ++ return FALSE; + + trakrd->mdia_file_offset = ftell (moovrf->file) - 8; + trakrd->mdia_size = size; +@@ -643,6 +713,11 @@ moov_recov_parse_mdia (MoovRecovFile * moovrf, TrakRecovData * trakrd) + return FALSE; + if (!moov_recov_parse_minf (moovrf, trakrd)) + return FALSE; ++ ++ offset = ftell (moovrf->file); ++ if (trakrd->mdia_size < offset - trakrd->mdia_file_offset) ++ return FALSE; ++ + return TRUE; + } + +@@ -665,6 +740,8 @@ moov_recov_parse_trak (MoovRecovFile * moovrf, TrakRecovData * trakrd) + if (fourcc != FOURCC_trak) { + return FALSE; + } ++ if (size < 8) ++ return FALSE; + trakrd->trak_size = size; + + /* now we should have a trak header 'tkhd' */ +@@ -683,6 +760,9 @@ moov_recov_parse_trak (MoovRecovFile * moovrf, TrakRecovData * trakrd) + return FALSE; + + trakrd->extra_atoms_offset = ftell (moovrf->file); ++ if (trakrd->trak_size < trakrd->extra_atoms_offset - offset) ++ return FALSE; ++ + trakrd->extra_atoms_size = size - (trakrd->extra_atoms_offset - offset); + + trakrd->file_offset = offset; diff --git a/gstreamer1-plugins-good.spec b/gstreamer1-plugins-good.spec index 6a320f9..b6e3fa0 100644 --- a/gstreamer1-plugins-good.spec +++ b/gstreamer1-plugins-good.spec @@ -15,7 +15,7 @@ Name: gstreamer1-plugins-good Version: 1.16.1 -Release: 7%{?gitcommit:.git%{shortcommit}}%{?dist}.6 +Release: 7%{?gitcommit:.git%{shortcommit}}%{?dist}.7 Summary: GStreamer plugins with good code and licensing License: LGPLv2+ @@ -52,7 +52,9 @@ Patch12: gstreamer1-plugins-good-1.16.1-CVE-2026-18649.patch # https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/0bcc6564c7deedc7d6d7373a2ab6479c9bf3889f Patch13: gstreamer1-plugins-good-1.16.1-CVE-2026-73434.patch # https://issues.redhat.com/browse/RHEL-246549 +# https://issues.redhat.com/browse/RHEL-246382 # https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/93fa4cd30ba43b38b02a9de76a7a80dc198c87a0 +# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12041 Patch14: gstreamer1-plugins-good-1.16.1-CVE-2026-18296.patch # https://issues.redhat.com/browse/RHEL-246618 # https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12042 @@ -394,6 +396,10 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' %changelog +* Sat Aug 22 2026 RHEL Packaging Agent - 1.16.1-7.7 +- Fix CVE-2026-18296: heap buffer overflow in qtmoovrecover + Resolves: RHEL-246382 + * Sat Aug 22 2026 RHEL Packaging Agent - 1.16.1-7.6 - Fix CVE-2026-18298: heap buffer overflow in GdkPixbuf image decoder Resolves: RHEL-246561