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>
This commit is contained in:
Mathieu Duponchelle 2024-10-02 15:16:30 +02:00 committed by GStreamer Marge Bot
parent 2838374d6e
commit 006047a23a

View file

@ -165,6 +165,10 @@ gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op)
if (offset == 0) { if (offset == 0) {
offset = 8; offset = 8;
current_pos -= 1; 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) if (offset == 7)
current_pos -= 1; current_pos -= 1;
/* have we underrun? */
if (current_pos < op->packet + 5)
return -1;
if (((current_pos[-5] & ~((1 << (offset + 1)) - 1)) != 0) if (((current_pos[-5] & ~((1 << (offset + 1)) - 1)) != 0)
|| ||
current_pos[-4] != 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 /* Give ourselves a chance to recover if we went back too far by using
* the size check. */ * the size check. */
for (ii = 0; ii < 2; ii++) { for (ii = 0; ii < 2; ii++) {
if (offset > 4) { if (offset > 4) {
/* have we underrun? */
if (current_pos < op->packet)
return -1;
size_check = (current_pos[0] >> (offset - 5)) & 0x3F; size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
} else { } else {
/* have we underrun? */
if (current_pos < op->packet + 1)
return -1;
/* mask part of byte from current_pos */ /* mask part of byte from current_pos */
size_check = (current_pos[0] & ((1 << (offset + 1)) - 1)); size_check = (current_pos[0] & ((1 << (offset + 1)) - 1));
/* shift to appropriate position */ /* 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; mode_size_ptr = pad->vorbis_mode_sizes;
if (size > G_N_ELEMENTS (pad->vorbis_mode_sizes)) {
return -1;
}
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
offset = (offset + 1) % 8; offset = (offset + 1) % 8;
if (offset == 0) if (offset == 0)