From 246777db6078ff9dd8046d5701fc12cb34547402 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 15 Oct 2015 16:47:14 -0400 Subject: [PATCH] Relay protocol: check string lengths MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Ensure that string lengths are not longer than what the protocol supports on both send and receive. Ensure that path lengths fit in the local filename length limits on the receive side. Ensure that strings exchanged in the relay protocol are zero-terminated. Signed-off-by: Mathieu Desnoyers Signed-off-by: Jérémie Galarneau --- src/bin/lttng-relayd/cmd-2-1.c | 20 +++++++++++++++++--- src/bin/lttng-relayd/cmd-2-2.c | 20 +++++++++++++++++--- src/bin/lttng-relayd/cmd-2-4.c | 19 +++++++++++++++++-- src/common/relayd/relayd.c | 24 ++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/src/bin/lttng-relayd/cmd-2-1.c b/src/bin/lttng-relayd/cmd-2-1.c index a9e55c6ac..080dc173f 100644 --- a/src/bin/lttng-relayd/cmd-2-1.c +++ b/src/bin/lttng-relayd/cmd-2-1.c @@ -19,10 +19,11 @@ #define _LGPL_SOURCE #include -#include #include #include +#include +#include #include "cmd-generic.h" #include "cmd-2-1.h" @@ -38,6 +39,7 @@ int cmd_recv_stream_2_1(struct relay_connection *conn, struct lttcomm_relayd_add_stream stream_info; char *path_name = NULL; char *channel_name = NULL; + size_t len; ret = cmd_recv(conn->sock, &stream_info, sizeof(stream_info)); if (ret < 0) { @@ -45,17 +47,29 @@ int cmd_recv_stream_2_1(struct relay_connection *conn, goto error; } + len = lttng_strnlen(stream_info.pathname, sizeof(stream_info.pathname)); + /* Ensure that NULL-terminated and fits in local filename length. */ + if (len == sizeof(stream_info.pathname) || len >= LTTNG_NAME_MAX) { + ret = -ENAMETOOLONG; + ERR("Path name too long"); + goto error; + } path_name = create_output_path(stream_info.pathname); if (!path_name) { PERROR("Path name allocation"); ret = -ENOMEM; goto error; } - + len = lttng_strnlen(stream_info.channel_name, sizeof(stream_info.channel_name)); + if (len == sizeof(stream_info.channel_name) || len >= DEFAULT_STREAM_NAME_LEN) { + ret = -ENAMETOOLONG; + ERR("Channel name too long"); + goto error; + } channel_name = strdup(stream_info.channel_name); if (!channel_name) { ret = -errno; - PERROR("Path name allocation"); + PERROR("Channel name allocation"); goto error; } diff --git a/src/bin/lttng-relayd/cmd-2-2.c b/src/bin/lttng-relayd/cmd-2-2.c index 47567b620..4f34d8b66 100644 --- a/src/bin/lttng-relayd/cmd-2-2.c +++ b/src/bin/lttng-relayd/cmd-2-2.c @@ -19,12 +19,13 @@ #define _LGPL_SOURCE #include -#include #include #include #include +#include +#include #include "cmd-generic.h" #include "cmd-2-1.h" @@ -41,6 +42,7 @@ int cmd_recv_stream_2_2(struct relay_connection *conn, struct lttcomm_relayd_add_stream_2_2 stream_info; char *path_name = NULL; char *channel_name = NULL; + size_t len; ret = cmd_recv(conn->sock, &stream_info, sizeof(stream_info)); if (ret < 0) { @@ -48,17 +50,29 @@ int cmd_recv_stream_2_2(struct relay_connection *conn, goto error; } + len = lttng_strnlen(stream_info.pathname, sizeof(stream_info.pathname)); + /* Ensure that NULL-terminated and fits in local filename length. */ + if (len == sizeof(stream_info.pathname) || len >= LTTNG_NAME_MAX) { + ret = -ENAMETOOLONG; + ERR("Path name too long"); + goto error; + } path_name = create_output_path(stream_info.pathname); if (!path_name) { PERROR("Path name allocation"); ret = -ENOMEM; goto error; } - + len = lttng_strnlen(stream_info.channel_name, sizeof(stream_info.channel_name)); + if (len == sizeof(stream_info.channel_name) || len >= DEFAULT_STREAM_NAME_LEN) { + ret = -ENAMETOOLONG; + ERR("Channel name too long"); + goto error; + } channel_name = strdup(stream_info.channel_name); if (!channel_name) { ret = -errno; - PERROR("Path name allocation"); + PERROR("Channel name allocation"); goto error; } diff --git a/src/bin/lttng-relayd/cmd-2-4.c b/src/bin/lttng-relayd/cmd-2-4.c index 98cd92b2a..b269bc68a 100644 --- a/src/bin/lttng-relayd/cmd-2-4.c +++ b/src/bin/lttng-relayd/cmd-2-4.c @@ -19,12 +19,13 @@ #define _LGPL_SOURCE #include -#include #include #include #include +#include +#include #include "cmd-generic.h" #include "lttng-relayd.h" @@ -35,15 +36,29 @@ int cmd_create_session_2_4(struct relay_connection *conn, { int ret; struct lttcomm_relayd_create_session_2_4 session_info; + size_t len; ret = cmd_recv(conn->sock, &session_info, sizeof(session_info)); if (ret < 0) { ERR("Unable to recv session info version 2.4"); goto error; } - + len = lttng_strnlen(session_info.session_name, sizeof(session_info.session_name)); + /* Ensure that NULL-terminated and fits in local filename length. */ + if (len == sizeof(session_info.session_name) || len >= LTTNG_NAME_MAX) { + ret = -ENAMETOOLONG; + ERR("Session name too long"); + goto error; + } strncpy(session_name, session_info.session_name, sizeof(session_info.session_name)); + + len = lttng_strnlen(session_info.hostname, sizeof(session_info.hostname)); + if (len == sizeof(session_info.hostname) || len >= LTTNG_HOST_NAME_MAX) { + ret = -ENAMETOOLONG; + ERR("Session name too long"); + goto error; + } strncpy(hostname, session_info.hostname, sizeof(session_info.hostname)); *live_timer = be32toh(session_info.live_timer); diff --git a/src/common/relayd/relayd.c b/src/common/relayd/relayd.c index a9fe6a7f1..fade4b11e 100644 --- a/src/common/relayd/relayd.c +++ b/src/common/relayd/relayd.c @@ -129,7 +129,15 @@ static int relayd_create_session_2_4(struct lttcomm_relayd_sock *rsock, int ret; struct lttcomm_relayd_create_session_2_4 msg; + if (strlen(session_name) >= sizeof(msg.session_name)) { + ret = -1; + goto error; + } strncpy(msg.session_name, session_name, sizeof(msg.session_name)); + if (strlen(hostname) >= sizeof(msg.hostname)) { + ret = -1; + goto error; + } strncpy(msg.hostname, hostname, sizeof(msg.hostname)); msg.live_timer = htobe32(session_live_timer); msg.snapshot = htobe32(snapshot); @@ -247,7 +255,15 @@ int relayd_add_stream(struct lttcomm_relayd_sock *rsock, const char *channel_nam /* Compat with relayd 2.1 */ if (rsock->minor == 1) { memset(&msg, 0, sizeof(msg)); + if (strlen(channel_name) >= sizeof(msg.channel_name)) { + ret = -1; + goto error; + } strncpy(msg.channel_name, channel_name, sizeof(msg.channel_name)); + if (strlen(pathname) >= sizeof(msg.pathname)) { + ret = -1; + goto error; + } strncpy(msg.pathname, pathname, sizeof(msg.pathname)); /* Send command */ @@ -258,7 +274,15 @@ int relayd_add_stream(struct lttcomm_relayd_sock *rsock, const char *channel_nam } else { memset(&msg_2_2, 0, sizeof(msg_2_2)); /* Compat with relayd 2.2+ */ + if (strlen(channel_name) >= sizeof(msg_2_2.channel_name)) { + ret = -1; + goto error; + } strncpy(msg_2_2.channel_name, channel_name, sizeof(msg_2_2.channel_name)); + if (strlen(pathname) >= sizeof(msg_2_2.pathname)) { + ret = -1; + goto error; + } strncpy(msg_2_2.pathname, pathname, sizeof(msg_2_2.pathname)); msg_2_2.tracefile_size = htobe64(tracefile_size); msg_2_2.tracefile_count = htobe64(tracefile_count); -- 2.34.1