Fix CVE-2026-18296: heap buffer overflow in qtmoovrecover
Backport upstream commit 93fa4cd3 to fix CVE-2026-18296 in
gstreamer1-plugins-good. The patch adds box size and version
validation to atomsrecovery.c (qtmoovrecover), preventing
potential issues with malformed input files.
CVE: CVE-2026-18296
Upstream patches:
- 93fa4cd30b.patch
Resolves: RHEL-246547
This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent.
Assisted-by: Ymir
This commit is contained in:
parent
f747e74241
commit
3da6b27d8f
259
gstreamer1-plugins-good-1.26.7-CVE-2026-18296.patch
Normal file
259
gstreamer1-plugins-good-1.26.7-CVE-2026-18296.patch
Normal file
@ -0,0 +1,259 @@
|
||||
From 8fbd9d76f6f7f134087deae1aa348ecfcac759a7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
|
||||
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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12041>
|
||||
---
|
||||
.../gst/isomp4/atomsrecovery.c | 88 ++++++++++++++++++-
|
||||
1 file changed, 84 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/subprojects/gst-plugins-good/gst/isomp4/atomsrecovery.c b/subprojects/gst-plugins-good/gst/isomp4/atomsrecovery.c
|
||||
index edc443487b..176185476f 100644
|
||||
--- a/subprojects/gst-plugins-good/gst/isomp4/atomsrecovery.c
|
||||
+++ b/subprojects/gst-plugins-good/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;
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
Name: gstreamer1-plugins-good
|
||||
Version: 1.26.7
|
||||
Release: 7%{?dist}
|
||||
Release: 8%{?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
|
||||
@ -66,6 +66,8 @@ Patch: gstreamer1-plugins-good-1.26.7-CVE-2026-5056.patch
|
||||
Patch: gstreamer1-plugins-good-1.26.7-CVE-2026-73434.patch
|
||||
# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12231
|
||||
Patch: gstreamer1-plugins-good-1.26.7-CVE-2026-73433.patch
|
||||
# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12041
|
||||
Patch: gstreamer1-plugins-good-1.26.7-CVE-2026-18296.patch
|
||||
|
||||
BuildRequires: meson >= 0.48.0
|
||||
BuildRequires: gcc
|
||||
@ -386,6 +388,10 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -fv {} ';'
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Aug 24 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 1.26.7-8
|
||||
- Fix CVE-2026-18296: validate box sizes in qtmoovrecover
|
||||
Resolves: RHEL-246547
|
||||
|
||||
* Mon Aug 17 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 1.26.7-7
|
||||
- Fix CVE-2026-73433: out-of-bounds reads in AVI FUJIFILM strd parsing
|
||||
Resolves: RHEL-239061
|
||||
|
||||
Loading…
Reference in New Issue
Block a user