X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-relayd%2Fmain.c;h=fb1817cd015fdc11ffa3e06c385c79d64eb50fc8;hp=4a2258d34abeb96be16ddcc0ae34a42c167d23f3;hb=87250ba19aec78f36e301494a03f5678fcb6fbb4;hpb=7145f5e9af16907c65a514fe9112e99564cf6333 diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 4a2258d34..fb1817cd0 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -1,21 +1,11 @@ /* - * Copyright (C) 2012 - Julien Desfossez - * David Goulet - * 2013 - Jérémie Galarneau - * 2015 - Mathieu Desnoyers + * Copyright (C) 2012 Julien Desfossez + * Copyright (C) 2012 David Goulet + * Copyright (C) 2013 Jérémie Galarneau + * Copyright (C) 2015 Mathieu Desnoyers * - * 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. + * SPDX-License-Identifier: GPL-2.0-only * - * 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 @@ -240,7 +230,7 @@ static int set_option(int opt, const char *arg, const char *optname) errno = 0; v = strtoul(arg, NULL, 0); - if (errno != 0 || !isdigit(arg[0])) { + if (errno != 0 || !isdigit((unsigned char) arg[0])) { ERR("Wrong value in --fd-pool-size parameter: %s", arg); ret = -1; goto end; @@ -517,7 +507,7 @@ static int set_fd_pool_size(void) goto end; } - DBG("File descriptor pool size argument (%u) adjusted to %u to accomodate transient fd uses", + DBG("File descriptor pool size argument (%u) adjusted to %u to accommodates transient fd uses", lttng_opt_fd_pool_size, lttng_opt_fd_pool_size - DEFAULT_RELAYD_FD_POOL_SIZE_RESERVE); lttng_opt_fd_pool_size -= DEFAULT_RELAYD_FD_POOL_SIZE_RESERVE; @@ -530,7 +520,7 @@ static int set_options(int argc, char **argv) int c, ret = 0, option_index = 0, retval = 0; int orig_optopt = optopt, orig_optind = optind; char *default_address, *optstring; - const char *config_path = NULL; + char *config_path = NULL; optstring = utils_generate_optstring(long_options, sizeof(long_options) / sizeof(struct option)); @@ -554,6 +544,7 @@ static int set_options(int argc, char **argv) WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", "-f, --config"); } else { + free(config_path); config_path = utils_expand_path(optarg); if (!config_path) { ERR("Failed to resolve path: %s", optarg); @@ -666,6 +657,7 @@ static int set_options(int argc, char **argv) } exit: + free(config_path); free(optstring); return retval; } @@ -927,7 +919,11 @@ static int create_named_thread_poll_set(struct lttng_poll_event *events, } ret = fd_tracker_util_poll_create(the_fd_tracker, - name, events, 1, LTTNG_CLOEXEC); + name, events, 1, LTTNG_CLOEXEC); + if (ret) { + PERROR("Failed to create \"%s\" poll file descriptor", name); + goto error; + } /* Add quit pipe */ ret = lttng_poll_add(events, thread_quit_pipe[0], LPOLLIN | LPOLLERR); @@ -984,7 +980,7 @@ static int accept_sock(void *data, int *out_fd) struct lttcomm_sock **socks = data; struct lttcomm_sock *in_sock = socks[0]; - socks[1] = in_sock->ops->accept(in_sock); + socks[1] = in_sock->ops->accept(in_sock); if (!socks[1]) { ret = -1; goto end; @@ -1028,7 +1024,11 @@ static struct lttcomm_sock *relay_socket_create(struct lttng_uri *uri, ret = fd_tracker_open_unsuspendable_fd(the_fd_tracker, &sock_fd, (const char **) (formated_name ? &formated_name : NULL), 1, create_sock, sock); - free(formated_name); + if (ret) { + PERROR("Failed to open \"%s\" relay socket", + formated_name ?: "Unknown"); + goto error; + } DBG("Listening on %s socket %d", name, sock->fd); ret = sock->ops->bind(sock); @@ -1043,12 +1043,14 @@ static struct lttcomm_sock *relay_socket_create(struct lttng_uri *uri, } + free(formated_name); return sock; error: if (sock) { lttcomm_destroy_sock(sock); } + free(formated_name); return NULL; } @@ -1060,7 +1062,7 @@ struct lttcomm_sock *accept_relayd_sock(struct lttcomm_sock *listening_sock, struct lttcomm_sock *socks[2] = { listening_sock, NULL }; struct lttcomm_sock *new_sock = NULL; - ret = fd_tracker_open_unsuspendable_fd( + ret = fd_tracker_open_unsuspendable_fd( the_fd_tracker, &out_fd, (const char **) &name, 1, accept_sock, &socks); @@ -1085,6 +1087,7 @@ static void *relay_thread_listener(void *data) DBG("[thread] Relay listener started"); + rcu_register_thread(); health_register(health_relayd, HEALTH_RELAYD_TYPE_LISTENER); health_code_update(); @@ -1179,7 +1182,7 @@ restart: newsock = accept_relayd_sock(data_sock, "Data socket to relayd"); } else { - assert(pollfd == control_sock->fd); + LTTNG_ASSERT(pollfd == control_sock->fd); type = RELAY_CONTROL; newsock = accept_relayd_sock(control_sock, "Control socket to relayd"); @@ -1268,6 +1271,7 @@ error_sock_control: ERR("Health error occurred in %s", __func__); } health_unregister(health_relayd); + rcu_unregister_thread(); DBG("Relay listener thread cleanup complete"); lttng_relay_stop_threads(); return NULL; @@ -1434,7 +1438,7 @@ static int relay_create_session(const struct lttcomm_relayd_hdr *recv_hdr, ret = -1; goto send_reply; } - assert(!conn->session); + LTTNG_ASSERT(!conn->session); conn->session = session; DBG("Created session %" PRIu64, session->id); @@ -1625,12 +1629,13 @@ static int relay_add_stream(const struct lttcomm_relayd_hdr *recv_hdr, } else if (conn->minor >= 4 && conn->minor < 11) { char *group_by_session_path_name; - assert(session->session_name[0] != '\0'); + LTTNG_ASSERT(session->session_name[0] != '\0'); group_by_session_path_name = backward_compat_group_by_session( path_name, - session->session_name); + session->session_name, + session->creation_time.value); if (!group_by_session_path_name) { ERR("Failed to apply group by session to stream of session %" PRIu64, session->id); @@ -1958,7 +1963,7 @@ static int relay_recv_metadata(const struct lttcomm_relayd_hdr *recv_hdr, packet_view = lttng_buffer_view_from_view(payload, sizeof(metadata_payload_header), metadata_payload_size); - if (!packet_view.data) { + if (!lttng_buffer_view_is_valid(&packet_view)) { ERR("Invalid metadata packet length announced by header"); ret = -1; goto end_put; @@ -2211,8 +2216,8 @@ static int relay_begin_data_pending(const struct lttcomm_relayd_hdr *recv_hdr, struct lttcomm_relayd_generic_reply reply; struct relay_stream *stream; - assert(recv_hdr); - assert(conn); + LTTNG_ASSERT(recv_hdr); + LTTNG_ASSERT(conn); DBG("Init streams for data pending"); @@ -2384,7 +2389,7 @@ static int relay_recv_index(const struct lttcomm_relayd_hdr *recv_hdr, struct relay_stream *stream; size_t msg_len; - assert(conn); + LTTNG_ASSERT(conn); DBG("Relay receiving index"); @@ -2468,7 +2473,7 @@ static int relay_streams_sent(const struct lttcomm_relayd_hdr *recv_hdr, ssize_t send_ret; struct lttcomm_relayd_generic_reply reply; - assert(conn); + LTTNG_ASSERT(conn); DBG("Relay receiving streams_sent"); @@ -2664,7 +2669,6 @@ static int relay_create_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, struct lttcomm_relayd_create_trace_chunk *msg; struct lttcomm_relayd_generic_reply reply = {}; struct lttng_buffer_view header_view; - struct lttng_buffer_view chunk_name_view; struct lttng_trace_chunk *chunk = NULL, *published_chunk = NULL; enum lttng_error_code reply_code = LTTNG_OK; enum lttng_trace_chunk_status chunk_status; @@ -2683,7 +2687,7 @@ static int relay_create_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, } header_view = lttng_buffer_view_from_view(payload, 0, sizeof(*msg)); - if (!header_view.data) { + if (!lttng_buffer_view_is_valid(&header_view)) { ERR("Failed to receive payload of chunk creation command"); ret = -1; goto end_no_reply; @@ -2728,13 +2732,21 @@ static int relay_create_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, if (msg->override_name_length) { const char *name; + const struct lttng_buffer_view chunk_name_view = + lttng_buffer_view_from_view(payload, + sizeof(*msg), + msg->override_name_length); + + if (!lttng_buffer_view_is_valid(&chunk_name_view)) { + ERR("Invalid payload of chunk creation command (protocol error): buffer too short for expected name length"); + ret = -1; + reply_code = LTTNG_ERR_INVALID; + goto end; + } - chunk_name_view = lttng_buffer_view_from_view(payload, - sizeof(*msg), - msg->override_name_length); name = chunk_name_view.data; - if (!name || name[msg->override_name_length - 1]) { - ERR("Failed to receive payload of chunk creation command"); + if (name[msg->override_name_length - 1]) { + ERR("Invalid payload of chunk creation command (protocol error): name is not null-terminated"); ret = -1; reply_code = LTTNG_ERR_INVALID; goto end; @@ -2765,7 +2777,7 @@ static int relay_create_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, goto end; } - assert(conn->session->output_directory); + LTTNG_ASSERT(conn->session->output_directory); chunk_status = lttng_trace_chunk_set_as_owner(chunk, conn->session->output_directory); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { @@ -2869,7 +2881,7 @@ static int relay_close_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, } header_view = lttng_buffer_view_from_view(payload, 0, sizeof(*msg)); - if (!header_view.data) { + if (!lttng_buffer_view_is_valid(&header_view)) { ERR("Failed to receive payload of chunk close command"); ret = -1; goto end_no_reply; @@ -2942,7 +2954,7 @@ static int relay_close_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, new_path); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { ret = -1; - goto end; + goto end_unlock_session; } session->ongoing_rotation = false; } @@ -2960,7 +2972,7 @@ static int relay_close_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, chunk_status = lttng_trace_chunk_rename_path(chunk, old_path); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { ret = -1; - goto end; + goto end_unlock_session; } } chunk_status = lttng_trace_chunk_set_close_timestamp( @@ -3102,20 +3114,20 @@ static int relay_trace_chunk_exists(const struct lttcomm_relayd_hdr *recv_hdr, bool chunk_exists; if (!session || !conn->version_check_done) { - ERR("Trying to close a trace chunk before version check"); + ERR("Trying to check for the existance of a trace chunk before version check"); ret = -1; goto end_no_reply; } if (session->major == 2 && session->minor < 11) { - ERR("Chunk close command is unsupported before 2.11"); + ERR("Chunk exists command is unsupported before 2.11"); ret = -1; goto end_no_reply; } header_view = lttng_buffer_view_from_view(payload, 0, sizeof(*msg)); - if (!header_view.data) { - ERR("Failed to receive payload of chunk close command"); + if (!lttng_buffer_view_is_valid(&header_view)) { + ERR("Failed to receive payload of chunk exists command"); ret = -1; goto end_no_reply; } @@ -3166,7 +3178,7 @@ static int relay_get_configuration(const struct lttcomm_relayd_hdr *recv_hdr, uint64_t result_flags = 0; header_view = lttng_buffer_view_from_view(payload, 0, sizeof(*msg)); - if (!header_view.data) { + if (!lttng_buffer_view_is_valid(&header_view)) { ERR("Failed to receive payload of chunk close command"); ret = -1; goto end_no_reply; @@ -3327,8 +3339,8 @@ static enum relay_connection_status relay_process_control_receive_payload( goto end; } - assert(ret > 0); - assert(ret <= state->left_to_receive); + LTTNG_ASSERT(ret > 0); + LTTNG_ASSERT(ret <= state->left_to_receive); state->left_to_receive -= ret; state->received += ret; @@ -3382,7 +3394,7 @@ static enum relay_connection_status relay_process_control_receive_header( struct ctrl_connection_state_receive_header *state = &conn->protocol.ctrl.state.receive_header; - assert(state->left_to_receive != 0); + LTTNG_ASSERT(state->left_to_receive != 0); ret = conn->sock->ops->recvmsg(conn->sock, reception_buffer->data + state->received, @@ -3400,8 +3412,8 @@ static enum relay_connection_status relay_process_control_receive_header( goto end; } - assert(ret > 0); - assert(ret <= state->left_to_receive); + LTTNG_ASSERT(ret > 0); + LTTNG_ASSERT(ret <= state->left_to_receive); state->left_to_receive -= ret; state->received += ret; @@ -3493,7 +3505,7 @@ static enum relay_connection_status relay_process_data_receive_header( struct lttcomm_relayd_data_hdr header; struct relay_stream *stream; - assert(state->left_to_receive != 0); + LTTNG_ASSERT(state->left_to_receive != 0); ret = conn->sock->ops->recvmsg(conn->sock, state->header_reception_buffer + state->received, @@ -3511,8 +3523,8 @@ static enum relay_connection_status relay_process_data_receive_header( goto end; } - assert(ret > 0); - assert(ret <= state->left_to_receive); + LTTNG_ASSERT(ret > 0); + LTTNG_ASSERT(ret <= state->left_to_receive); state->left_to_receive -= ret; state->received += ret; @@ -3648,7 +3660,7 @@ static enum relay_connection_status relay_process_data_receive_payload( packet_chunk = lttng_buffer_view_init(data_buffer, 0, recv_size); - assert(packet_chunk.data); + LTTNG_ASSERT(packet_chunk.data); ret = stream_write(stream, &packet_chunk, 0); if (ret) { @@ -3904,7 +3916,7 @@ restart: ctrl_conn = connection_get_by_sock(relay_connections_ht, pollfd); /* If not found, there is a synchronization issue. */ - assert(ctrl_conn); + LTTNG_ASSERT(ctrl_conn); if (ctrl_conn->type == RELAY_DATA) { if (revents & LPOLLIN) { @@ -3917,7 +3929,7 @@ restart: } goto put_ctrl_connection; } - assert(ctrl_conn->type == RELAY_CONTROL); + LTTNG_ASSERT(ctrl_conn->type == RELAY_CONTROL); if (revents & LPOLLIN) { enum relay_connection_status status; @@ -4015,7 +4027,7 @@ restart: if (data_conn->type == RELAY_CONTROL) { goto put_data_connection; } - assert(data_conn->type == RELAY_DATA); + LTTNG_ASSERT(data_conn->type == RELAY_DATA); if (revents & LPOLLIN) { enum relay_connection_status status;