From 62d09f73b72d574d075b68b227710e47c10311d2 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Fri, 8 Apr 2022 11:10:49 +1000 Subject: [PATCH] ogg: fix possible buffer overrun 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: --- subprojects/gst-plugins-base/ext/ogg/gstoggstream.c | 6 ++++-- subprojects/gst-plugins-base/ext/ogg/vorbis_parse.c | 11 ++++++++++- subprojects/gst-plugins-base/ext/ogg/vorbis_parse.h | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/subprojects/gst-plugins-base/ext/ogg/gstoggstream.c b/subprojects/gst-plugins-base/ext/ogg/gstoggstream.c index dbc7473254..548dfa18e2 100644 --- a/subprojects/gst-plugins-base/ext/ogg/gstoggstream.c +++ b/subprojects/gst-plugins-base/ext/ogg/gstoggstream.c @@ -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 diff --git a/subprojects/gst-plugins-base/ext/ogg/vorbis_parse.c b/subprojects/gst-plugins-base/ext/ogg/vorbis_parse.c index 2d85e93975..65ef463808 100644 --- a/subprojects/gst-plugins-base/ext/ogg/vorbis_parse.c +++ b/subprojects/gst-plugins-base/ext/ogg/vorbis_parse.c @@ -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; } diff --git a/subprojects/gst-plugins-base/ext/ogg/vorbis_parse.h b/subprojects/gst-plugins-base/ext/ogg/vorbis_parse.h index 927a92a634..7cdef6fdc4 100644 --- a/subprojects/gst-plugins-base/ext/ogg/vorbis_parse.h +++ b/subprojects/gst-plugins-base/ext/ogg/vorbis_parse.h @@ -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__ */