mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 03:45:39 +00:00
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>
This commit is contained in:
parent
f9c24cd7e7
commit
b75114983e
3 changed files with 30 additions and 5 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue