gstaudioaggregator: segfault in gst_audio_aggregator_aggregate()
GStreamer 1.14.2, OS CentOS 7.3 64-bit
Problem Description
gst_audio_aggregator_aggregate()
function acquires locks on 'agg'
and 'aagg'
then iterates over sink pads:
(at gstaudioaggregator.c:1786)
for (; iter; iter = iter->next) {
GstAudioAggregatorPad *pad = (GstAudioAggregatorPad *) iter->data;
GstAggregatorPad *aggpad = (GstAggregatorPad *) iter->data;
gboolean pad_eos = gst_aggregator_pad_is_eos (aggpad);
During the pads iteration the gst_audio_aggregator_mix_buffer()
function gets called which releases the 'pad'
and 'aagg'
locks temporarily:
(at gstaudioaggregator.c:1577)
GST_OBJECT_UNLOCK (pad);
GST_OBJECT_UNLOCK (aagg);
filled = GST_AUDIO_AGGREGATOR_GET_CLASS (aagg)->aggregate_one_buffer (aagg,
pad, inbuf, in_offset, outbuf, out_start, overlap);
GST_OBJECT_LOCK (aagg);
GST_OBJECT_LOCK (pad);
This makes the removal of a pad from audiomixer possible (executed concurrently from other thread).
The pad removal invalidates current pad iterator because its memory (an element of GList) gets freed.
Next iteration cycle in gst_audio_aggregator_aggregate()
executes 'iter = iter->next'
then accesses an invalid 'iter'
pointer with 'iter->data'
statement.
This results in a segfault due to dereferencing of invalid pointer. Occasionally this error manifests as a lock up on a mutex in gst_aggregator_pad_is_eos()
.