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>
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
pad->nsn_increment = short_size >> 1;
}
-void
+int
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 */
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;
}
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__ */