From: Jérémie Galarneau Date: Tue, 16 Jul 2019 01:24:41 +0000 (-0400) Subject: Don't allow slashes and dots in overriden trace chunk names X-Git-Tag: v2.11.0-rc3~104 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=cb034ca241b062822de342b1b380fa195cb8272a;p=lttng-tools.git Don't allow slashes and dots in overriden trace chunk names A trace chunk's name is used when building its path. Therefore, we ensure that a chunk's name can never contain '/' or '.' in order to prevent malicious trace chunk names that would escape a session's output directory. Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-relayd/cmd-2-11.c b/src/bin/lttng-relayd/cmd-2-11.c index 269eeb9b0..363e0f000 100644 --- a/src/bin/lttng-relayd/cmd-2-11.c +++ b/src/bin/lttng-relayd/cmd-2-11.c @@ -33,7 +33,7 @@ int cmd_create_session_2_11(const struct lttng_buffer_view *payload, char *session_name, char *hostname, uint32_t *live_timer, bool *snapshot, uint64_t *id_sessiond, lttng_uuid sessiond_uuid, - uint64_t *current_chunk_id) + bool *has_current_chunk, uint64_t *current_chunk_id) { int ret; struct lttcomm_relayd_create_session_2_11 header; @@ -54,6 +54,8 @@ int cmd_create_session_2_11(const struct lttng_buffer_view *payload, header.session_name_len = be32toh(header.session_name_len); header.hostname_len = be32toh(header.hostname_len); header.live_timer = be32toh(header.live_timer); + header.current_chunk_id.value = be64toh(header.current_chunk_id.value); + header.current_chunk_id.is_set = !!header.current_chunk_id.is_set; lttng_uuid_copy(sessiond_uuid, header.sessiond_uuid); @@ -104,6 +106,8 @@ int cmd_create_session_2_11(const struct lttng_buffer_view *payload, *live_timer = header.live_timer; *snapshot = !!header.snapshot; + *current_chunk_id = header.current_chunk_id.value; + *has_current_chunk = header.current_chunk_id.is_set; ret = 0; diff --git a/src/bin/lttng-relayd/cmd-2-11.h b/src/bin/lttng-relayd/cmd-2-11.h index eedf54187..7961d91ff 100644 --- a/src/bin/lttng-relayd/cmd-2-11.h +++ b/src/bin/lttng-relayd/cmd-2-11.h @@ -25,7 +25,7 @@ int cmd_create_session_2_11(const struct lttng_buffer_view *payload, char *session_name, char *hostname, uint32_t *live_timer, bool *snapshot, uint64_t *id_sessiond, lttng_uuid sessiond_uuid, - uint64_t *current_chunk_id); + bool *has_current_chunk, uint64_t *current_chunk_id); int cmd_recv_stream_2_11(const struct lttng_buffer_view *payload, char **ret_path_name, char **ret_channel_name, diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 8f0767af3..85c4fe9b9 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -1113,10 +1113,13 @@ static int relay_create_session(const struct lttcomm_relayd_hdr *recv_hdr, ret = cmd_create_session_2_4(payload, session_name, hostname, &live_timer, &snapshot); } else { + bool has_current_chunk; + /* From 2.11 to ... */ ret = cmd_create_session_2_11(payload, session_name, hostname, &live_timer, &snapshot, &id_sessiond.value, sessiond_uuid, + &has_current_chunk, ¤t_chunk_id.value); if (lttng_uuid_is_nil(sessiond_uuid)) { /* The nil UUID is reserved for pre-2.11 clients. */ @@ -1125,7 +1128,7 @@ static int relay_create_session(const struct lttcomm_relayd_hdr *recv_hdr, goto send_reply; } id_sessiond.is_set = true; - current_chunk_id.is_set = true; + current_chunk_id.is_set = has_current_chunk; } if (ret < 0) { @@ -1147,14 +1150,6 @@ static int relay_create_session(const struct lttcomm_relayd_hdr *recv_hdr, reply.session_id = htobe64(session->id); - session->current_trace_chunk = - sessiond_trace_chunk_registry_get_anonymous_chunk( - sessiond_trace_chunk_registry, sessiond_uuid, - session->id); - if (!session->current_trace_chunk) { - ret = -1; - } - send_reply: if (ret < 0) { reply.ret_code = htobe32(LTTNG_ERR_FATAL); diff --git a/src/common/trace-chunk.c b/src/common/trace-chunk.c index 26c7ce07d..488d7ebc4 100644 --- a/src/common/trace-chunk.c +++ b/src/common/trace-chunk.c @@ -399,6 +399,27 @@ end: return status; } +static +bool is_valid_chunk_name(const char *name) +{ + size_t len; + + if (!name) { + return false; + } + + len = strnlen(name, LTTNG_NAME_MAX); + if (len == 0 || len == LTTNG_NAME_MAX) { + return false; + } + + if (strchr(name, '/') || strchr(name, '.')) { + return false; + } + + return true; +} + LTTNG_HIDDEN enum lttng_trace_chunk_status lttng_trace_chunk_override_name( struct lttng_trace_chunk *chunk, const char *name) @@ -407,7 +428,7 @@ enum lttng_trace_chunk_status lttng_trace_chunk_override_name( char *new_name; enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK; - if (!name || !*name || strnlen(name, LTTNG_NAME_MAX) == LTTNG_NAME_MAX) { + if (!is_valid_chunk_name(name)) { ERR("Attempted to set an invalid name on a trace chunk: name = %s", name ? : "NULL"); status = LTTNG_TRACE_CHUNK_STATUS_INVALID_ARGUMENT;