Fix: channel names are not validated
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 27 Nov 2014 22:35:32 +0000 (17:35 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 1 Dec 2014 23:56:08 +0000 (18:56 -0500)
This patch ensures:

  1. A channel name does not contain any '/' character, since
     relative paths may be injected in the channel name
     otherwise (knowing that the channel name is eventually
     part of a file name)
  2. A channel name does not start with a '.' character, since
     trace readers (Babeltrace is one of them) could interpret
     files starting with a dot as hidden files and ignore
     them when opening the CTF trace

Fixes: #751
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Conflicts:
include/lttng/lttng-error.h
src/bin/lttng/commands/enable_channels.c
src/common/error.c

Conflicts:
src/common/error.c

include/lttng/lttng-error.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng/commands/enable_channels.c
src/common/error.c

index 94096ca7f31a445933fe7bd5821afcb06e682e0f..7a686070d21ed14b78c9d1b31b0fcdf1cae9dcbb 100644 (file)
@@ -142,6 +142,8 @@ enum lttng_error_code {
        LTTNG_ERR_NO_CONSUMER            = 109, /* No consumer exist for the session */
        LTTNG_ERR_EXCLUSION_INVAL        = 110, /* Invalid event exclusion data */
        LTTNG_ERR_EXCLUSION_NOMEM        = 111, /* Lack of memory while processing event exclusions */
+       /* 112 */
+       LTTNG_ERR_INVALID_CHANNEL_NAME   = 113, /* Invalid channel name */
 
        /* MUST be last element */
        LTTNG_ERR_NR,                           /* Last element */
index f76a4422ea644b6997b46a6ed8620f27d9ad49b2..f18974b3888a5a49501c438224009b4e357bcf7b 100644 (file)
@@ -17,6 +17,7 @@
 
 #define _GNU_SOURCE
 #include <assert.h>
+#include <string.h>
 #include <inttypes.h>
 #include <urcu/list.h>
 #include <urcu/uatomic.h>
@@ -903,11 +904,21 @@ int cmd_enable_channel(struct ltt_session *session,
        int ret;
        struct ltt_ust_session *usess = session->ust_session;
        struct lttng_ht *chan_ht;
+       size_t len;
 
        assert(session);
        assert(attr);
        assert(domain);
 
+       len = strnlen(attr->name, sizeof(attr->name));
+
+       /* Validate channel name */
+       if (attr->name[0] == '.' ||
+               memchr(attr->name, '/', len) != NULL) {
+               ret = LTTNG_ERR_INVALID_CHANNEL_NAME;
+               goto end;
+       }
+
        DBG("Enabling channel %s for session %s", attr->name, session->name);
 
        rcu_read_lock();
@@ -988,6 +999,7 @@ int cmd_enable_channel(struct ltt_session *session,
 
 error:
        rcu_read_unlock();
+end:
        return ret;
 }
 
index b05ed5271eb8dd6492cc2121de7a3f14a770f6e4..2e636b4a5970721df634f3bfcff1de765663945c 100644 (file)
@@ -258,9 +258,16 @@ static int enable_channel(char *session_name)
        /* Strip channel list (format: chan1,chan2,...) */
        channel_name = strtok(opt_channels, ",");
        while (channel_name != NULL) {
-               /* Copy channel name and normalize it */
-               strncpy(chan.name, channel_name, NAME_MAX);
-               chan.name[NAME_MAX - 1] = '\0';
+               /* Validate channel name's length */
+               if (strlen(channel_name) >= NAME_MAX) {
+                       ERR("Channel name is too long (max. %zu characters)",
+                                       sizeof(chan.name) - 1);
+                       ret = LTTNG_ERR_INVALID_CHANNEL_NAME;
+                       goto error;
+               }
+
+               /* Copy channel name */
+               strcpy(chan.name, channel_name);
 
                DBG("Enabling channel %s", channel_name);
 
@@ -273,6 +280,11 @@ static int enable_channel(char *session_name)
                                WARN("Channel %s: %s (session %s)", channel_name,
                                                lttng_strerror(ret), session_name);
                                goto error;
+                       case LTTNG_ERR_INVALID_CHANNEL_NAME:
+                               ERR("Invalid channel name: \"%s\". "
+                                   "Channel names may not start with '.', and "
+                                   "may not contain '/'.", channel_name);
+                               goto error;
                        default:
                                ERR("Channel %s: %s (session %s)", channel_name,
                                                lttng_strerror(ret), session_name);
@@ -284,7 +296,6 @@ static int enable_channel(char *session_name)
                                        get_domain_str(dom.type), channel_name, session_name);
                }
 
-               /* Next event */
                channel_name = strtok(NULL, ",");
        }
 
index 3e445dab1481673be74ef01fb30e95990e4dc6a4..ea4a621978d10e8f9fb5e000667f081d2b6740b1 100644 (file)
@@ -117,6 +117,7 @@ static const char *error_string_array[] = {
        [ ERROR_INDEX(LTTNG_ERR_SNAPSHOT_NODATA) ] = "No data available in snapshot",
        [ ERROR_INDEX(LTTNG_ERR_NO_CHANNEL) ] = "No channel found in the session",
        [ ERROR_INDEX(LTTNG_ERR_SESSION_INVALID_CHAR) ] = "Invalid character found in session name",
+       [ ERROR_INDEX(LTTNG_ERR_INVALID_CHANNEL_NAME) ] = "Invalid channel name",
 
        /* Last element */
        [ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"
This page took 0.029392 seconds and 4 git commands to generate.