Don't allow slashes and dots in overriden trace chunk names
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 16 Jul 2019 01:24:41 +0000 (21:24 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 25 Jul 2019 19:51:47 +0000 (15:51 -0400)
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 <jeremie.galarneau@efficios.com>
src/bin/lttng-relayd/cmd-2-11.c
src/bin/lttng-relayd/cmd-2-11.h
src/bin/lttng-relayd/main.c
src/common/trace-chunk.c

index 269eeb9b078a707d4f22e8995a89cc7aa73147d9..363e0f00022984a2b758eca59811017d80bb0e1c 100644 (file)
@@ -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;
 
index eedf541873a865f1ef4c69f0cbc3873fceb5a554..7961d91ffa6d7a78226c702773142dac0c1342a5 100644 (file)
@@ -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,
index 8f0767af373cf10c28dbdcdf078758c22c889941..85c4fe9b9aca282ca2d35af5bfa18c910c261b55 100644 (file)
@@ -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,
                                &current_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);
index 26c7ce07d3486be1a4101920f100653dc2e19b03..488d7ebc4ffffcf19938cdb5f1da4036311417e6 100644 (file)
@@ -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;
This page took 0.030212 seconds and 4 git commands to generate.