diff options
author | Jeremy Cline <jeremy@jcline.org> | 2021-11-21 17:52:48 -0500 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2022-02-01 23:16:32 +0000 |
commit | 11675e48419e3ef4f70e3bfc17bbeaf6f525e67f (patch) | |
tree | 222bb7fa600e1c96d0a3633fc99dc2f5b49e75c2 | |
parent | 8d6c1cad181d10c7acca9aecd30606f23bbc97f5 (diff) | |
download | gstreamer-plugins-base-11675e48419e3ef4f70e3bfc17bbeaf6f525e67f.tar.gz |
tagdemux: Fix crash when presented with malformed files
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/gst-plugins-base/-/issues/959
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1295>
-rw-r--r-- | gst-libs/gst/tag/gsttagdemux.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/gst-libs/gst/tag/gsttagdemux.c b/gst-libs/gst/tag/gsttagdemux.c index 8164c0d2f..9f6096e4a 100644 --- a/gst-libs/gst/tag/gsttagdemux.c +++ b/gst-libs/gst/tag/gsttagdemux.c @@ -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 */ |