From f86f6389a47137d2f5e8fc707916b6650fd1de00 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Thu, 10 May 2018 10:13:22 -0400 Subject: [PATCH] Dynamic payload for relayd create session command MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Move away from static constant defined char array. Perform the length check based on constant defined value on reception. Signed-off-by: Jonathan Rajotte Signed-off-by: Jérémie Galarneau --- src/bin/lttng-relayd/Makefile.am | 1 + src/bin/lttng-relayd/cmd-2-11.c | 108 ++++++++++++++++++++++++++++++ src/bin/lttng-relayd/cmd-2-11.h | 27 ++++++++ src/bin/lttng-relayd/cmd.h | 1 + src/bin/lttng-relayd/main.c | 17 +++-- src/common/relayd/relayd.c | 79 ++++++++++++++++++---- src/common/sessiond-comm/relayd.h | 9 +++ 7 files changed, 223 insertions(+), 19 deletions(-) create mode 100644 src/bin/lttng-relayd/cmd-2-11.c create mode 100644 src/bin/lttng-relayd/cmd-2-11.h diff --git a/src/bin/lttng-relayd/Makefile.am b/src/bin/lttng-relayd/Makefile.am index 751b5766c..cf56ea495 100644 --- a/src/bin/lttng-relayd/Makefile.am +++ b/src/bin/lttng-relayd/Makefile.am @@ -12,6 +12,7 @@ lttng_relayd_SOURCES = main.c lttng-relayd.h utils.h utils.c cmd.h \ cmd-2-1.c cmd-2-1.h \ cmd-2-2.c cmd-2-2.h \ cmd-2-4.c cmd-2-4.h \ + cmd-2-11.c cmd-2-11.h \ health-relayd.c health-relayd.h \ lttng-viewer-abi.h testpoint.h \ viewer-stream.h viewer-stream.c \ diff --git a/src/bin/lttng-relayd/cmd-2-11.c b/src/bin/lttng-relayd/cmd-2-11.c new file mode 100644 index 000000000..993062ba7 --- /dev/null +++ b/src/bin/lttng-relayd/cmd-2-11.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2018 - Jonathan Rajotte + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define _LGPL_SOURCE +#include +#include + +#include +#include + +#include +#include +#include + +#include "cmd-2-11.h" +#include "lttng-relayd.h" + +int cmd_create_session_2_11(const struct lttng_buffer_view *payload, + char *session_name, char *hostname, + uint32_t *live_timer, bool *snapshot) +{ + int ret; + struct lttcomm_relayd_create_session_2_11 header; + size_t header_len, received_names_size; + struct lttng_buffer_view session_name_view; + struct lttng_buffer_view hostname_view; + + header_len = sizeof(header); + + if (payload->size < header_len) { + ERR("Unexpected payload size in \"cmd_create_session_2_11\": expected >= %zu bytes, got %zu bytes", + header_len, payload->size); + ret = -1; + goto error; + } + memcpy(&header, payload->data, header_len); + + header.session_name_len = be32toh(header.session_name_len); + header.hostname_len = be32toh(header.hostname_len); + header.live_timer = be32toh(header.live_timer); + + received_names_size = header.session_name_len + header.hostname_len; + if (payload->size < header_len + received_names_size) { + ERR("Unexpected payload size in \"cmd_create_session_2_11\": expected >= %zu bytes, got %zu bytes", + header_len + received_names_size, payload->size); + ret = -1; + goto error; + } + + /* Validate length against defined constant. */ + if (header.session_name_len > LTTNG_NAME_MAX) { + ret = -ENAMETOOLONG; + ERR("Length of session name (%" PRIu32 " bytes) received in create_session command exceeds maximum length (%d bytes)", header.session_name_len, LTTNG_NAME_MAX); + goto error; + } + if (header.hostname_len > LTTNG_HOST_NAME_MAX) { + ret = -ENAMETOOLONG; + ERR("Length of hostname (%" PRIu32 " bytes) received in create_session command exceeds maximum length (%d bytes)", header.hostname_len, LTTNG_HOST_NAME_MAX); + goto error; + } + + session_name_view = lttng_buffer_view_from_view(payload, header_len, + header.session_name_len); + hostname_view = lttng_buffer_view_from_view(payload, + header_len + header.session_name_len, header.hostname_len); + + /* Validate that names are NULL terminated. */ + if (session_name_view.data[session_name_view.size - 1] != '\0') { + ERR("cmd_create_session_2_11 session_name is invalid (not NULL terminated)"); + ret = -1; + goto error; + } + + if (hostname_view.data[hostname_view.size - 1] != '\0') { + ERR("cmd_create_session_2_11 hostname is invalid (not NULL terminated)"); + ret = -1; + goto error; + } + + /* + * Length and null-termination check are already performed. + * LTTNG_NAME_MAX and LTTNG_HOST_NAME_MAX max size are expected. + */ + strcpy(session_name, session_name_view.data); + strcpy(hostname, hostname_view.data); + + *live_timer = header.live_timer; + *snapshot = !!header.snapshot; + + ret = 0; + +error: + return ret; +} diff --git a/src/bin/lttng-relayd/cmd-2-11.h b/src/bin/lttng-relayd/cmd-2-11.h new file mode 100644 index 000000000..d63195854 --- /dev/null +++ b/src/bin/lttng-relayd/cmd-2-11.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 - Jonathan Rajotte + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef RELAYD_CMD_2_11_H +#define RELAYD_CMD_2_11_H + +#include "lttng-relayd.h" +#include + +int cmd_create_session_2_11(const struct lttng_buffer_view *payload, + char *session_name, char *hostname, + uint32_t *live_timer, bool *snapshot); + +#endif /* RELAYD_CMD_2_11_H */ diff --git a/src/bin/lttng-relayd/cmd.h b/src/bin/lttng-relayd/cmd.h index 468a693e5..6845fabfc 100644 --- a/src/bin/lttng-relayd/cmd.h +++ b/src/bin/lttng-relayd/cmd.h @@ -23,5 +23,6 @@ #include "cmd-2-1.h" #include "cmd-2-2.h" #include "cmd-2-4.h" +#include "cmd-2-11.h" #endif /* RELAYD_CMD_H */ diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index cb4643b76..1313091b1 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -1106,16 +1106,19 @@ static int relay_create_session(const struct lttcomm_relayd_hdr *recv_hdr, memset(&reply, 0, sizeof(reply)); - switch (conn->minor) { - case 1: - case 2: - case 3: - break; - case 4: /* LTTng sessiond 2.4 */ - default: + if (conn->minor < 4) { + /* From 2.1 to 2.3 */ + ret = 0; + } else if (conn->minor >= 4 && conn->minor < 11) { + /* From 2.4 to 2.10 */ ret = cmd_create_session_2_4(payload, session_name, hostname, &live_timer, &snapshot); + } else { + /* From 2.11 to ... */ + ret = cmd_create_session_2_11(payload, session_name, + hostname, &live_timer, &snapshot); } + if (ret < 0) { goto send_reply; } diff --git a/src/common/relayd/relayd.c b/src/common/relayd/relayd.c index b4fd35c73..45f965c79 100644 --- a/src/common/relayd/relayd.c +++ b/src/common/relayd/relayd.c @@ -119,7 +119,62 @@ error: } /* - * Starting at 2.4, RELAYD_CREATE_SESSION takes additional parameters to + * Starting from 2.11, RELAYD_CREATE_SESSION payload (session_name & hostname) + * have no length restriction on the sender side. + * Length for both payloads is stored in the msg struct. A new dynamic size + * payload size is introduced. + */ +static int relayd_create_session_2_11(struct lttcomm_relayd_sock *rsock, + char *session_name, char *hostname, + int session_live_timer, unsigned int snapshot) +{ + int ret; + struct lttcomm_relayd_create_session_2_11 *msg = NULL; + size_t session_name_len; + size_t hostname_len; + size_t msg_length; + + /* The two names are sent with a '\0' delimiter between them. */ + session_name_len = strlen(session_name) + 1; + hostname_len = strlen(hostname) + 1; + + msg_length = sizeof(*msg) + session_name_len + hostname_len; + msg = zmalloc(msg_length); + if (!msg) { + PERROR("zmalloc create_session_2_11 command message"); + ret = -1; + goto error; + } + + assert(session_name_len <= UINT32_MAX); + msg->session_name_len = htobe32(session_name_len); + + assert(hostname_len <= UINT32_MAX); + msg->hostname_len = htobe32(hostname_len); + + if (lttng_strncpy(msg->names, session_name, session_name_len)) { + ret = -1; + goto error; + } + if (lttng_strncpy(msg->names + session_name_len, hostname, hostname_len)) { + ret = -1; + goto error; + } + + msg->live_timer = htobe32(session_live_timer); + msg->snapshot = !!snapshot; + + /* Send command */ + ret = send_command(rsock, RELAYD_CREATE_SESSION, msg, msg_length, 0); + if (ret < 0) { + goto error; + } +error: + free(msg); + return ret; +} +/* + * From 2.4 to 2.10, RELAYD_CREATE_SESSION takes additional parameters to * support the live reading capability. */ static int relayd_create_session_2_4(struct lttcomm_relayd_sock *rsock, @@ -187,17 +242,17 @@ int relayd_create_session(struct lttcomm_relayd_sock *rsock, uint64_t *session_i DBG("Relayd create session"); - switch(rsock->minor) { - case 1: - case 2: - case 3: - ret = relayd_create_session_2_1(rsock); - break; - case 4: - default: - ret = relayd_create_session_2_4(rsock, session_name, - hostname, session_live_timer, snapshot); - break; + if (rsock->minor < 4) { + /* From 2.1 to 2.3 */ + ret = relayd_create_session_2_1(rsock); + } else if (rsock->minor >= 4 && rsock->minor < 11) { + /* From 2.4 to 2.10 */ + ret = relayd_create_session_2_4(rsock, session_name, + hostname, session_live_timer, snapshot); + } else { + /* From 2.11 to ... */ + ret = relayd_create_session_2_11(rsock, session_name, + hostname, session_live_timer, snapshot); } if (ret < 0) { diff --git a/src/common/sessiond-comm/relayd.h b/src/common/sessiond-comm/relayd.h index 306e2e4dd..25d09980e 100644 --- a/src/common/sessiond-comm/relayd.h +++ b/src/common/sessiond-comm/relayd.h @@ -191,6 +191,15 @@ struct lttcomm_relayd_create_session_2_4 { uint32_t snapshot; } LTTNG_PACKED; +struct lttcomm_relayd_create_session_2_11 { + uint32_t session_name_len; + uint32_t hostname_len; + uint32_t live_timer; + uint8_t snapshot; + /* Contains the session_name and hostname */ + char names[]; +} LTTNG_PACKED; + /* * Used to ask the relay to reset the metadata trace file (regeneration). * Send the new version of the metadata (starts at 0). -- 2.34.1