mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-22 17:51:16 +00:00
rtsp-client: make sure sessmedia will not get freed while used
handle_*_request() functions were all retrieving the session media from the session by calling gst_rtsp_session_get_media () which is a transfer-none call. If a session timeout happens at that time, the session media may get freed making the pointer invalid.. Fixes #757 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1053>
This commit is contained in:
parent
ce76a286ed
commit
7ba665995f
3 changed files with 72 additions and 17 deletions
|
@ -1447,7 +1447,7 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
path = klass->make_path_from_uri (client, ctx->uri);
|
||||
|
||||
/* get a handle to the configuration of the media in the session */
|
||||
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
|
||||
sessmedia = gst_rtsp_session_dup_media (session, path, &matched);
|
||||
if (!sessmedia)
|
||||
goto not_found;
|
||||
|
||||
|
@ -1482,6 +1482,7 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
/* unmanage the media in the session, returns false if all media session
|
||||
* are torn down. */
|
||||
keep_session = gst_rtsp_session_release_media (session, sessmedia);
|
||||
g_object_unref (sessmedia);
|
||||
|
||||
/* construct the response now */
|
||||
code = GST_RTSP_STS_OK;
|
||||
|
@ -1532,6 +1533,7 @@ no_aggregate:
|
|||
send_generic_response (client,
|
||||
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
||||
g_free (path);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
sig_failed:
|
||||
|
@ -1541,6 +1543,7 @@ sig_failed:
|
|||
send_generic_response (client, sig_result, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1699,7 +1702,7 @@ handle_pause_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
path = klass->make_path_from_uri (client, ctx->uri);
|
||||
|
||||
/* get a handle to the configuration of the media in the session */
|
||||
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
|
||||
sessmedia = gst_rtsp_session_dup_media (session, path, &matched);
|
||||
if (!sessmedia)
|
||||
goto not_found;
|
||||
|
||||
|
@ -1746,6 +1749,7 @@ handle_pause_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
|
||||
/* the state is now READY */
|
||||
gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_READY);
|
||||
g_object_unref (sessmedia);
|
||||
|
||||
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PAUSE_REQUEST], 0, ctx);
|
||||
|
||||
|
@ -1779,6 +1783,7 @@ no_aggregate:
|
|||
GST_ERROR ("client %p: no aggregate path %s", client, path);
|
||||
send_generic_response (client,
|
||||
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
||||
g_object_unref (sessmedia);
|
||||
g_free (path);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1788,6 +1793,7 @@ sig_failed:
|
|||
gst_rtsp_status_as_text (sig_result));
|
||||
send_generic_response (client, sig_result, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (sessmedia);
|
||||
g_object_unref (media);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1797,6 +1803,7 @@ invalid_state:
|
|||
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
|
||||
ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (sessmedia);
|
||||
g_object_unref (media);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1805,6 +1812,7 @@ not_supported:
|
|||
GST_ERROR ("client %p: pausing not supported", client);
|
||||
send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (sessmedia);
|
||||
g_object_unref (media);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -2068,7 +2076,7 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
path = klass->make_path_from_uri (client, uri);
|
||||
|
||||
/* get a handle to the configuration of the media in the session */
|
||||
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
|
||||
sessmedia = gst_rtsp_session_dup_media (session, path, &matched);
|
||||
if (!sessmedia)
|
||||
goto not_found;
|
||||
|
||||
|
@ -2163,6 +2171,7 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
|||
gst_rtsp_session_media_set_state (sessmedia, GST_STATE_PLAYING);
|
||||
|
||||
gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_PLAYING);
|
||||
g_object_unref (sessmedia);
|
||||
|
||||
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PLAY_REQUEST], 0, ctx);
|
||||
|
||||
|
@ -2195,6 +2204,7 @@ no_aggregate:
|
|||
GST_ERROR ("client %p: no aggregate path %s", client, path);
|
||||
send_generic_response (client,
|
||||
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
||||
g_object_unref (sessmedia);
|
||||
g_free (path);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -2205,6 +2215,7 @@ sig_failed:
|
|||
send_generic_response (client, sig_result, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
invalid_state:
|
||||
|
@ -2214,6 +2225,7 @@ invalid_state:
|
|||
ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
pipeline_error:
|
||||
|
@ -2223,6 +2235,7 @@ pipeline_error:
|
|||
ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
unsuspend_failed:
|
||||
|
@ -2231,6 +2244,7 @@ unsuspend_failed:
|
|||
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
invalid_mode:
|
||||
|
@ -2239,6 +2253,7 @@ invalid_mode:
|
|||
send_generic_response (client, code, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
unsupported_mode:
|
||||
|
@ -2247,6 +2262,7 @@ unsupported_mode:
|
|||
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
get_rates_error:
|
||||
|
@ -2255,6 +2271,7 @@ get_rates_error:
|
|||
send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
adjust_play_response_failed:
|
||||
|
@ -2263,6 +2280,7 @@ adjust_play_response_failed:
|
|||
send_generic_response (client, code, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
rtp_info_error:
|
||||
|
@ -2271,6 +2289,7 @@ rtp_info_error:
|
|||
send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx);
|
||||
gst_rtsp_media_unlock (media);
|
||||
g_object_unref (media);
|
||||
g_object_unref (sessmedia);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,20 +343,9 @@ gst_rtsp_session_release_media (GstRTSPSession * sess,
|
|||
return more;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_get_media:
|
||||
* @sess: a #GstRTSPSession
|
||||
* @path: the path for the media
|
||||
* @matched: (out): the amount of matched characters
|
||||
*
|
||||
* Get the session media for @path. @matched will contain the number of matched
|
||||
* characters of @path.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the configuration for @path in @sess.
|
||||
*/
|
||||
GstRTSPSessionMedia *
|
||||
gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
||||
gint * matched)
|
||||
static GstRTSPSessionMedia *
|
||||
_gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
||||
gint * matched, gboolean dup)
|
||||
{
|
||||
GstRTSPSessionPrivate *priv;
|
||||
GstRTSPSessionMedia *result;
|
||||
|
@ -384,6 +373,9 @@ gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result && dup)
|
||||
result = g_object_ref (result);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
*matched = best;
|
||||
|
@ -391,6 +383,45 @@ gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_get_media:
|
||||
* @sess: a #GstRTSPSession
|
||||
* @path: the path for the media
|
||||
* @matched: (out): the amount of matched characters
|
||||
*
|
||||
* Gets the session media for @path. @matched will contain the number of matched
|
||||
* characters of @path.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the configuration for @path in @sess.
|
||||
*/
|
||||
GstRTSPSessionMedia *
|
||||
gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
||||
gint * matched)
|
||||
{
|
||||
return _gst_rtsp_session_get_media (sess, path, matched, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_dup_media:
|
||||
* @sess: a #GstRTSPSession
|
||||
* @path: the path for the media
|
||||
* @matched: (out): the amount of matched characters
|
||||
*
|
||||
* Gets the session media for @path, increasing its reference count. @matched
|
||||
* will contain the number of matched characters of @path.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the configuration for @path in @sess,
|
||||
* should be unreferenced when no longer needed.
|
||||
*
|
||||
* Since: 1.20
|
||||
*/
|
||||
GstRTSPSessionMedia *
|
||||
gst_rtsp_session_dup_media (GstRTSPSession * sess, const gchar * path,
|
||||
gint * matched)
|
||||
{
|
||||
return _gst_rtsp_session_get_media (sess, path, matched, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_session_filter:
|
||||
* @sess: a #GstRTSPSession
|
||||
|
|
|
@ -141,7 +141,12 @@ GST_RTSP_SERVER_API
|
|||
GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession *sess,
|
||||
const gchar *path,
|
||||
gint * matched);
|
||||
/* get media in a session, increasing its reference count */
|
||||
|
||||
GST_RTSP_SERVER_API
|
||||
GstRTSPSessionMedia * gst_rtsp_session_dup_media (GstRTSPSession *sess,
|
||||
const gchar *path,
|
||||
gint * matched);
|
||||
/**
|
||||
* GstRTSPSessionFilterFunc:
|
||||
* @sess: a #GstRTSPSession object
|
||||
|
|
Loading…
Reference in a new issue