summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2017-03-31 09:38:15 (GMT)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2017-03-31 10:32:31 (GMT)
commitefbacf1931d2f407e7f1c9f8f7dce994504a1188 (patch)
tree309be801b14ced93435a0fec2ed493ada6d5f54e
parentd8a1bf08b1f94fcb25029bef8b6a6a93693245b7 (diff)
downloadgstreamer-efbacf1931d2f407e7f1c9f8f7dce994504a1188.tar.gz
gstreamer-efbacf1931d2f407e7f1c9f8f7dce994504a1188.tar.xz
streamcollection: fix racy user-after-free
The issue happens when the structure is printed by the logging subsystem: the object is included in the log, and this will cause the full object printout to be done there. However, after dispose, the queue was already cleared, so the access to it (to print the object) would assert, as the queue was already freed. The patch changes it so that the queue is merely empty, and only freed in _finalize. https://bugzilla.gnome.org/show_bug.cgi?id=776293
-rw-r--r--gst/gststreamcollection.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/gst/gststreamcollection.c b/gst/gststreamcollection.c
index df53c59..5ad8940 100644
--- a/gst/gststreamcollection.c
+++ b/gst/gststreamcollection.c
@@ -68,6 +68,7 @@ enum
static guint gst_stream_collection_signals[LAST_SIGNAL] = { 0 };
static void gst_stream_collection_dispose (GObject * object);
+static void gst_stream_collection_finalize (GObject * object);
static void gst_stream_collection_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
@@ -129,6 +130,7 @@ gst_stream_collection_class_init (GstStreamCollectionClass * klass)
2, GST_TYPE_STREAM, G_TYPE_PARAM);
gobject_class->dispose = gst_stream_collection_dispose;
+ gobject_class->finalize = gst_stream_collection_finalize;
}
static void
@@ -159,13 +161,23 @@ gst_stream_collection_dispose (GObject * object)
if (collection->priv->streams) {
g_queue_foreach (collection->priv->streams,
(GFunc) release_gst_stream, collection);
- g_queue_free (collection->priv->streams);
- collection->priv->streams = NULL;
+ g_queue_clear (collection->priv->streams);
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
+static void
+gst_stream_collection_finalize (GObject * object)
+{
+ GstStreamCollection *collection = GST_STREAM_COLLECTION_CAST (object);
+
+ if (collection->priv->streams)
+ g_queue_free (collection->priv->streams);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
/**
* gst_stream_collection_new:
* @upstream_id: (allow-none): The stream id of the parent stream