From 006047a23a4e4c146e40e5dab765bc6318a94744 Mon Sep 17 00:00:00 2001
From: Mathieu Duponchelle <mathieu@centricular.com>
Date: Wed, 2 Oct 2024 15:16:30 +0200
Subject: [PATCH 1/2] vorbis_parse: check writes to
 GstOggStream.vorbis_mode_sizes

Thanks to Antonio Morales for finding and reporting the issue.

Fixes GHSL-2024-117 Fixes gstreamer#3875

Also perform out-of-bounds check for accesses to op->packet

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

CVE: CVE-2024-47615
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/006047a23a4e4c146e40e5dab765bc6318a94744]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
 ext/ogg/vorbis_parse.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/ext/ogg/vorbis_parse.c b/ext/ogg/vorbis_parse.c
index 65ef463808..757c7cd82b 100644
--- a/ext/ogg/vorbis_parse.c
+++ b/ext/ogg/vorbis_parse.c
@@ -165,6 +165,10 @@ gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op)
     if (offset == 0) {
       offset = 8;
       current_pos -= 1;
+
+      /* have we underrun? */
+      if (current_pos < op->packet)
+        return -1;
     }
   }
 
@@ -178,6 +182,10 @@ gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op)
     if (offset == 7)
       current_pos -= 1;
 
+    /* have we underrun? */
+    if (current_pos < op->packet + 5)
+      return -1;
+
     if (((current_pos[-5] & ~((1 << (offset + 1)) - 1)) != 0)
         ||
         current_pos[-4] != 0
@@ -199,9 +207,18 @@ gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op)
   /* Give ourselves a chance to recover if we went back too far by using
    * the size check. */
   for (ii = 0; ii < 2; ii++) {
+
     if (offset > 4) {
+      /* have we underrun? */
+      if (current_pos < op->packet)
+        return -1;
+
       size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
     } else {
+      /* have we underrun? */
+      if (current_pos < op->packet + 1)
+        return -1;
+
       /* mask part of byte from current_pos */
       size_check = (current_pos[0] & ((1 << (offset + 1)) - 1));
       /* shift to appropriate position */
@@ -233,6 +250,10 @@ gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op)
 
   mode_size_ptr = pad->vorbis_mode_sizes;
 
+  if (size > G_N_ELEMENTS (pad->vorbis_mode_sizes)) {
+    return -1;
+  }
+
   for (i = 0; i < size; i++) {
     offset = (offset + 1) % 8;
     if (offset == 0)
-- 
2.30.2

