diff options
author | Philippe Normand <philn@igalia.com> | 2023-03-12 14:55:22 +0000 |
---|---|---|
committer | GStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2023-05-08 19:20:22 +0000 |
commit | b75114983e85cef70da398c985e8ee7f8f68e3a1 (patch) | |
tree | e32d65efe3e90546b4fa3d8bf4e2130e14305b0c /subprojects | |
parent | f9c24cd7e70c8b8e50a6b8df87623a009c37c7ec (diff) | |
download | gstreamer-b75114983e85cef70da398c985e8ee7f8f68e3a1.tar.gz |
webrtcdatachannel: Bind to parent webrtcbin using a weak reference
The previous approach of using a simple pointer could lead to a use-after-free
in case a data-channel was created and its parent webrtcbin was disposed soon
after.
Fixes #2103
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4160>
Diffstat (limited to 'subprojects')
3 files changed, 30 insertions, 5 deletions
diff --git a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c index 4f327c5858..4e9cd2e7f5 100644 --- a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +++ b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c @@ -2544,7 +2544,7 @@ _on_sctpdec_pad_added (GstElement * sctpdec, GstPad * pad, if (!channel) { channel = g_object_new (WEBRTC_TYPE_DATA_CHANNEL, NULL); channel->parent.id = stream_id; - channel->webrtcbin = webrtc; + webrtc_data_channel_set_webrtcbin (channel, webrtc); g_signal_emit (webrtc, gst_webrtc_bin_signals[PREPARE_DATA_CHANNEL_SIGNAL], 0, channel, FALSE); @@ -7196,7 +7196,7 @@ gst_webrtc_bin_create_data_channel (GstWebRTCBin * webrtc, const gchar * label, gst_element_sync_state_with_parent (ret->sink_bin); ret = gst_object_ref (ret); - ret->webrtcbin = webrtc; + webrtc_data_channel_set_webrtcbin (ret, webrtc); g_ptr_array_add (webrtc->priv->data_channels, ret); DC_UNLOCK (webrtc); diff --git a/subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.c b/subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.c index 8c9c59a829..1305c740ac 100644 --- a/subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.c +++ b/subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.c @@ -51,6 +51,7 @@ typedef void (*ChannelTask) (GstWebRTCDataChannel * channel, struct task { + GstWebRTCBin *webrtcbin; GstWebRTCDataChannel *channel; ChannelTask func; gpointer user_data; @@ -69,6 +70,7 @@ _execute_task (GstWebRTCBin * webrtc, struct task *task) static void _free_task (struct task *task) { + g_object_unref (task->webrtcbin); gst_object_unref (task->channel); if (task->notify) @@ -80,14 +82,22 @@ static void _channel_enqueue_task (WebRTCDataChannel * channel, ChannelTask func, gpointer user_data, GDestroyNotify notify) { - struct task *task = g_new0 (struct task, 1); + GstWebRTCBin *webrtcbin = NULL; + struct task *task = NULL; + webrtcbin = g_weak_ref_get (&channel->webrtcbin_weak); + if (!webrtcbin) + return; + + task = g_new0 (struct task, 1); + + task->webrtcbin = webrtcbin; task->channel = gst_object_ref (channel); task->func = func; task->user_data = user_data; task->notify = notify; - gst_webrtc_bin_enqueue_task (channel->webrtcbin, + gst_webrtc_bin_enqueue_task (task->webrtcbin, (GstWebRTCBinFunc) _execute_task, task, (GDestroyNotify) _free_task, NULL); } @@ -1139,6 +1149,8 @@ gst_webrtc_data_channel_finalize (GObject * object) g_clear_object (&channel->appsrc); g_clear_object (&channel->appsink); + g_weak_ref_clear (&channel->webrtcbin_weak); + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -1164,6 +1176,8 @@ webrtc_data_channel_init (WebRTCDataChannel * channel) G_LOCK (outstanding_channels_lock); outstanding_channels = g_list_prepend (outstanding_channels, channel); G_UNLOCK (outstanding_channels_lock); + + g_weak_ref_init (&channel->webrtcbin_weak, NULL); } static void @@ -1213,3 +1227,10 @@ webrtc_data_channel_link_to_sctp (WebRTCDataChannel * channel, } } } + +void +webrtc_data_channel_set_webrtcbin (WebRTCDataChannel * channel, + GstWebRTCBin * webrtcbin) +{ + g_weak_ref_set (&channel->webrtcbin_weak, webrtcbin); +} diff --git a/subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.h b/subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.h index dd65a66ae3..919949f682 100644 --- a/subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.h +++ b/subprojects/gst-plugins-bad/ext/webrtc/webrtcdatachannel.h @@ -51,7 +51,7 @@ struct _WebRTCDataChannel GstElement *sink_bin; GstElement *appsink; - GstWebRTCBin *webrtcbin; + GWeakRef webrtcbin_weak; gboolean opened; gulong src_probe; GError *stored_error; @@ -72,6 +72,10 @@ G_GNUC_INTERNAL void webrtc_data_channel_link_to_sctp (WebRTCDataChannel *channel, WebRTCSCTPTransport *sctp_transport); +G_GNUC_INTERNAL +void webrtc_data_channel_set_webrtcbin (WebRTCDataChannel *channel, + GstWebRTCBin *webrtcbin); + G_DECLARE_FINAL_TYPE (WebRTCErrorIgnoreBin, webrtc_error_ignore_bin, WEBRTC, ERROR_IGNORE_BIN, GstBin); G_END_DECLS |