tagdemux: Fix crash when presented with malformed files
authorJeremy Cline <jeremy@jcline.org>
Sun, 21 Nov 2021 22:52:48 +0000 (17:52 -0500)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 1 Feb 2022 19:04:40 +0000 (19:04 +0000)
There's a race condition in gsttagdemux.c between typefinding and the
end-of-stream event. If TYPE_FIND_MAX_SIZE is exceeded,
demux->priv->collect is set to NULL and an error is returned. However,
the end-of-stream event causes one last attempt at typefinding to occur.

This leads to gst_tag_demux_trim_buffer() being called with the NULL
demux->priv->collect buffer which it attempts to dereference, resulting
in a segfault.

The malicious MP3 can be created by:

printf "\x49\x44\x33\x04\x00\x00\x00\x00\x00\x00%s", \
    "$(dd if=/dev/urandom bs=1K count=200)" > malicious.mp3

This creates a valid ID3 header which gets us as far as typefinding. The
crash can then be reproduced with the following pipeline:

gst-launch-1.0 -e filesrc location=malicious.mp3 ! queue ! decodebin ! audioconvert ! vorbisenc ! oggmux ! filesink location=malicious.ogg

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/967

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

subprojects/gst-plugins-base/gst-libs/gst/tag/gsttagdemux.c

index 8164c0d2f3d8b2bba8414385bed3a1ae796b0185..9f6096e4ae0e08cc971e4893873c262e1331698c 100644 (file)
@@ -655,9 +655,11 @@ gst_tag_demux_chain_buffer (GstTagDemux * demux, GstBuffer * buf,
 
       /* Trim the buffer and adjust offset for typefinding */
       typefind_buf = demux->priv->collect;
-      gst_buffer_ref (typefind_buf);
-      if (!gst_tag_demux_trim_buffer (demux, &typefind_buf, &typefind_size))
-        return GST_FLOW_EOS;
+      if (typefind_buf) {
+        gst_buffer_ref (typefind_buf);
+        if (!gst_tag_demux_trim_buffer (demux, &typefind_buf, &typefind_size))
+          return GST_FLOW_EOS;
+      }
 
       if (typefind_buf == NULL)
         break;                  /* Still need more data */