From d76cae74dad89994bfcdad83da6ef1ad69074332 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Tue, 29 Apr 2025 09:43:58 +0300
Subject: [PATCH] qtdemux: Use byte reader to parse mvhd box

This avoids OOB reads.

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4394
Fixes CVE-2025-47183

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9133>

CVE: CVE-2025-47183
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/d76cae74dad89994bfcdad83da6ef1ad69074332]
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
 gst/isomp4/qtdemux.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index e708ef4..0d29869 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -14228,7 +14228,7 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
   GNode *pssh;
   guint64 creation_time;
   GstDateTime *datetime = NULL;
-  gint version;
+  guint8 version;
   GstByteReader mvhd_reader;
   guint32 matrix[9];
 
@@ -14242,19 +14242,35 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
     return qtdemux_parse_redirects (qtdemux);
   }
 
-  version = QT_UINT8 ((guint8 *) mvhd->data + 8);
+  if (!gst_byte_reader_get_uint8 (&mvhd_reader, &version))
+    return FALSE;
+  /* flags */
+  if (!gst_byte_reader_skip (&mvhd_reader, 3))
+    return FALSE;
   if (version == 1) {
-    creation_time = QT_UINT64 ((guint8 *) mvhd->data + 12);
-    qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 28);
-    qtdemux->duration = QT_UINT64 ((guint8 *) mvhd->data + 32);
-    if (!gst_byte_reader_skip (&mvhd_reader, 4 + 8 + 8 + 4 + 8))
+    if (!gst_byte_reader_get_uint64_be (&mvhd_reader, &creation_time))
+      return FALSE;
+    /* modification time */
+    if (!gst_byte_reader_skip (&mvhd_reader, 8))
+      return FALSE;
+    if (!gst_byte_reader_get_uint32_be (&mvhd_reader, &qtdemux->timescale))
+      return FALSE;
+    if (!gst_byte_reader_get_uint64_be (&mvhd_reader, &qtdemux->duration))
       return FALSE;
   } else if (version == 0) {
-    creation_time = QT_UINT32 ((guint8 *) mvhd->data + 12);
-    qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 20);
-    qtdemux->duration = QT_UINT32 ((guint8 *) mvhd->data + 24);
-    if (!gst_byte_reader_skip (&mvhd_reader, 4 + 4 + 4 + 4 + 4))
+    guint32 tmp;
+
+    if (!gst_byte_reader_get_uint32_be (&mvhd_reader, &tmp))
+      return FALSE;
+    creation_time = tmp;
+    /* modification time */
+    if (!gst_byte_reader_skip (&mvhd_reader, 4))
+      return FALSE;
+    if (!gst_byte_reader_get_uint32_be (&mvhd_reader, &qtdemux->timescale))
+      return FALSE;
+    if (!gst_byte_reader_get_uint32_be (&mvhd_reader, &tmp))
       return FALSE;
+    qtdemux->duration = tmp;
   } else {
     GST_WARNING_OBJECT (qtdemux, "Unhandled mvhd version %d", version);
     return FALSE;
-- 
2.50.1

