ogg: fix possible buffer overrun
authorMatthew Waters <matthew@centricular.com>
Fri, 8 Apr 2022 01:10:49 +0000 (11:10 +1000)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 8 Apr 2022 08:52:45 +0000 (08:52 +0000)
If an ogg stream does not match our expectations of how the end of a
buffer may be structured, it was possible to read memory past the end of
the buffer parsed by libogg.  Include a bounds check for this case and
stop parsing.

Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3930

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

subprojects/gst-plugins-base/ext/ogg/gstoggstream.c
subprojects/gst-plugins-base/ext/ogg/vorbis_parse.c
subprojects/gst-plugins-base/ext/ogg/vorbis_parse.h

index dbc7473..548dfa1 100644 (file)
@@ -916,14 +916,16 @@ setup_vorbis_mapper (GstOggStream * pad, ogg_packet * packet)
 static gboolean
 is_header_vorbis (GstOggStream * pad, ogg_packet * packet)
 {
+  int res = 0;
+
   if (packet->bytes == 0 || (packet->packet[0] & 0x01) == 0)
     return FALSE;
 
   if (packet->packet[0] == 5) {
-    gst_parse_vorbis_setup_packet (pad, packet);
+    res = gst_parse_vorbis_setup_packet (pad, packet);
   }
 
-  return TRUE;
+  return res == 0;
 }
 
 static void
index 2d85e93..65ef463 100644 (file)
@@ -97,7 +97,7 @@ gst_parse_vorbis_header_packet (GstOggStream * pad, ogg_packet * packet)
   pad->nsn_increment = short_size >> 1;
 }
 
-void
+int
 gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op)
 {
   /*
@@ -220,6 +220,10 @@ gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op)
       current_pos += 1;
     current_pos += 5;
     size -= 1;
+
+    /* have we overrun? */
+    if (current_pos >= op->packet + op->bytes)
+      return -1;
   }
 
   /* Store mode size information in our info struct */
@@ -235,6 +239,11 @@ gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op)
       current_pos += 1;
     *mode_size_ptr++ = (current_pos[0] >> offset) & 0x1;
     current_pos += 5;
+
+    /* have we overrun? */
+    if (current_pos >= op->packet + op->bytes)
+      return -1;
   }
 
+  return 0;
 }
index 927a92a..7cdef6f 100644 (file)
@@ -27,6 +27,6 @@
 G_GNUC_INTERNAL
 void gst_parse_vorbis_header_packet (GstOggStream * pad, ogg_packet * packet);
 G_GNUC_INTERNAL
-void gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op);
+int gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op);
 
 #endif /* __GST_VORBIS_PARSE_H__ */