From 1f345e94095b14037b3f39bc0b48db6b6543efd6 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Thu, 27 Nov 2014 17:35:32 -0500 Subject: [PATCH] Fix: channel names are not validated MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Jérémie Galarneau --- include/lttng/lttng-error.h | 1 + src/bin/lttng-sessiond/cmd.c | 12 ++++++++++++ src/bin/lttng/commands/enable_channels.c | 20 +++++++++++++++++--- src/common/error.c | 1 + 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/include/lttng/lttng-error.h b/include/lttng/lttng-error.h index 1220e489a..efdca6520 100644 --- a/include/lttng/lttng-error.h +++ b/include/lttng/lttng-error.h @@ -133,6 +133,7 @@ enum lttng_error_code { LTTNG_ERR_EXCLUSION_INVAL = 110, /* Invalid event exclusion data */ LTTNG_ERR_EXCLUSION_NOMEM = 111, /* Lack of memory while processing event exclusions */ LTTNG_ERR_INVALID_EVENT_NAME = 112, /* Invalid event name */ + LTTNG_ERR_INVALID_CHANNEL_NAME = 113, /* Invalid channel name */ /* MUST be last element */ LTTNG_ERR_NR, /* Last element */ diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index c1e33693f..11ff9b489 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -18,6 +18,7 @@ #define _GNU_SOURCE #define _LGPL_SOURCE #include +#include #include #include #include @@ -939,11 +940,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(); @@ -1024,6 +1035,7 @@ int cmd_enable_channel(struct ltt_session *session, error: rcu_read_unlock(); +end: return ret; } diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index f8272e922..101617fa8 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -275,9 +275,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); + error = 1; + goto skip_enable; + } + + /* Copy channel name */ + strcpy(chan.name, channel_name); DBG("Enabling channel %s", channel_name); @@ -292,6 +299,12 @@ static int enable_channel(char *session_name) lttng_strerror(ret), session_name); warn = 1; break; + case LTTNG_ERR_INVALID_CHANNEL_NAME: + ERR("Invalid channel name: \"%s\". " + "Channel names may not start with '.', and " + "may not contain '/'.", channel_name); + error = 1; + break; default: ERR("Channel %s: %s (session %s)", channel_name, lttng_strerror(ret), session_name); @@ -304,6 +317,7 @@ static int enable_channel(char *session_name) success = 1; } +skip_enable: if (lttng_opt_mi) { /* Mi print the channel element and leave it open */ ret = mi_lttng_channel(writer, &chan, 1); diff --git a/src/common/error.c b/src/common/error.c index 2cebbf9ef..d3e3b949d 100644 --- a/src/common/error.c +++ b/src/common/error.c @@ -166,6 +166,7 @@ static const char *error_string_array[] = { [ ERROR_INDEX(LTTNG_ERR_MI_IO_FAIL) ] = "IO error while writing MI output", [ ERROR_INDEX(LTTNG_ERR_MI_NOT_IMPLEMENTED) ] = "Mi feature not implemented", [ ERROR_INDEX(LTTNG_ERR_INVALID_EVENT_NAME) ] = "Invalid event name", + [ ERROR_INDEX(LTTNG_ERR_INVALID_CHANNEL_NAME) ] = "Invalid channel name", /* Last element */ [ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code" -- 2.34.1