Relay protocol: check string lengths
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 15 Oct 2015 20:47:14 +0000 (16:47 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 19 Oct 2015 18:54:22 +0000 (14:54 -0400)
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 <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-relayd/cmd-2-1.c
src/bin/lttng-relayd/cmd-2-2.c
src/bin/lttng-relayd/cmd-2-4.c
src/common/relayd/relayd.c

index a9e55c6acb866d427cbf20d6271dee3f4a848155..080dc173fc8361b117b4d335c3c2895bd075342f 100644 (file)
 
 #define _LGPL_SOURCE
 #include <assert.h>
-#include <string.h>
 
 #include <common/common.h>
 #include <common/sessiond-comm/relayd.h>
+#include <common/compat/string.h>
+#include <lttng/constant.h>
 
 #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;
        }
 
index 47567b6203212a6b9ee5408e489d156436253ed1..4f34d8b66470ba90590e8f895f28e27f607bbc89 100644 (file)
 
 #define _LGPL_SOURCE
 #include <assert.h>
-#include <string.h>
 
 #include <common/common.h>
 #include <common/sessiond-comm/relayd.h>
 
 #include <common/compat/endian.h>
+#include <common/compat/string.h>
+#include <lttng/constant.h>
 
 #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;
        }
 
index 98cd92b2a12dcee45b378710fce694f0c9351e93..b269bc68a2e84473e9061afcc32697105e41a81e 100644 (file)
 
 #define _LGPL_SOURCE
 #include <assert.h>
-#include <string.h>
 
 #include <common/common.h>
 #include <common/sessiond-comm/relayd.h>
 
 #include <common/compat/endian.h>
+#include <common/compat/string.h>
+#include <lttng/constant.h>
 
 #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);
index a9fe6a7f1dbe7a84d4ae8f174d89969129a71b3a..fade4b11ed56bc77750bfaed592008c9655e8b33 100644 (file)
@@ -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);
This page took 0.029065 seconds and 4 git commands to generate.