From 3d0bbd40fe75966a80942d24c212b357d787767b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Mon, 28 Oct 2019 23:57:01 -0400 Subject: [PATCH] Fix: relayd: live: crash when creating viewer streams MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Viewer streams can be creating while serving a "GET_STREAMS" viewer client command for a session that is being destroyed. If this happens, the viewer streams will be created with a NULL viewer trace chunk, which would result in a crash. The fix consists in returning a stream error when such a command happens during the destruction of a session. This is the same behaviour than if the session could not be found at all, introducing no meaningful change in behaviour from the viewer's perspective. Signed-off-by: Jérémie Galarneau --- src/bin/lttng-relayd/live.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/bin/lttng-relayd/live.c b/src/bin/lttng-relayd/live.c index e480f86e4..9a3d78ef0 100644 --- a/src/bin/lttng-relayd/live.c +++ b/src/bin/lttng-relayd/live.c @@ -954,15 +954,22 @@ int viewer_get_new_streams(struct relay_connection *conn) } if (!viewer_session_is_attached(conn->viewer_session, session)) { - send_streams = 0; response.status = htobe32(LTTNG_VIEWER_NEW_STREAMS_ERR); goto send_reply; } - send_streams = 1; - response.status = htobe32(LTTNG_VIEWER_NEW_STREAMS_OK); - pthread_mutex_lock(&session->lock); + if (!session->current_trace_chunk) { + /* + * Means the session is being destroyed. React the same way + * as if it could not be found at all. + */ + DBG("Relay session %" PRIu64 " has no current trace chunk, replying LTTNG_VIEWER_NEW_STREAMS_ERR", + session_id); + response.status = htobe32(LTTNG_VIEWER_NEW_STREAMS_ERR); + goto send_reply_unlock; + } + if (!conn->viewer_session->current_trace_chunk && session->current_trace_chunk) { ret = viewer_session_set_trace_chunk(conn->viewer_session, @@ -978,7 +985,8 @@ int viewer_get_new_streams(struct relay_connection *conn) if (ret < 0) { goto error_unlock_session; } - pthread_mutex_unlock(&session->lock); + send_streams = 1; + response.status = htobe32(LTTNG_VIEWER_NEW_STREAMS_OK); /* Only send back the newly created streams with the unsent ones. */ nb_streams = nb_created + nb_unsent; @@ -992,8 +1000,10 @@ int viewer_get_new_streams(struct relay_connection *conn) send_streams = 0; response.streams_count = 0; response.status = htobe32(LTTNG_VIEWER_NEW_STREAMS_HUP); - goto send_reply; + goto send_reply_unlock; } +send_reply_unlock: + pthread_mutex_unlock(&session->lock); send_reply: health_code_update(); -- 2.34.1