Fix: setuid/setgid daemons should not get sensitive env. var./args
[lttng-tools.git] / src / bin / lttng-relayd / main.c
index 1ec1eeaa4b14be22fa0a8cde2d708279a50bcf4b..c843aa5ad355c930f49fc63d51692a3973f73c8c 100644 (file)
@@ -46,6 +46,7 @@
 #include <common/compat/poll.h>
 #include <common/compat/socket.h>
 #include <common/compat/endian.h>
+#include <common/compat/getenv.h>
 #include <common/defaults.h>
 #include <common/daemonize.h>
 #include <common/futex.h>
@@ -197,33 +198,48 @@ int set_option(int opt, const char *arg, const char *optname)
                }
                break;
        case 'C':
-               ret = uri_parse(arg, &control_uri);
-               if (ret < 0) {
-                       ERR("Invalid control URI specified");
-                       goto end;
-               }
-               if (control_uri->port == 0) {
-                       control_uri->port = DEFAULT_NETWORK_CONTROL_PORT;
+               if (lttng_is_setuid_setgid()) {
+                       WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                               "-C, --control-port");
+               } else {
+                       ret = uri_parse(arg, &control_uri);
+                       if (ret < 0) {
+                               ERR("Invalid control URI specified");
+                               goto end;
+                       }
+                       if (control_uri->port == 0) {
+                               control_uri->port = DEFAULT_NETWORK_CONTROL_PORT;
+                       }
                }
                break;
        case 'D':
-               ret = uri_parse(arg, &data_uri);
-               if (ret < 0) {
-                       ERR("Invalid data URI specified");
-                       goto end;
-               }
-               if (data_uri->port == 0) {
-                       data_uri->port = DEFAULT_NETWORK_DATA_PORT;
+               if (lttng_is_setuid_setgid()) {
+                       WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                               "-D, -data-port");
+               } else {
+                       ret = uri_parse(arg, &data_uri);
+                       if (ret < 0) {
+                               ERR("Invalid data URI specified");
+                               goto end;
+                       }
+                       if (data_uri->port == 0) {
+                               data_uri->port = DEFAULT_NETWORK_DATA_PORT;
+                       }
                }
                break;
        case 'L':
-               ret = uri_parse(arg, &live_uri);
-               if (ret < 0) {
-                       ERR("Invalid live URI specified");
-                       goto end;
-               }
-               if (live_uri->port == 0) {
-                       live_uri->port = DEFAULT_NETWORK_VIEWER_PORT;
+               if (lttng_is_setuid_setgid()) {
+                       WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                               "-L, -live-port");
+               } else {
+                       ret = uri_parse(arg, &live_uri);
+                       if (ret < 0) {
+                               ERR("Invalid live URI specified");
+                               goto end;
+                       }
+                       if (live_uri->port == 0) {
+                               live_uri->port = DEFAULT_NETWORK_VIEWER_PORT;
+                       }
                }
                break;
        case 'd':
@@ -233,23 +249,33 @@ int set_option(int opt, const char *arg, const char *optname)
                opt_background = 1;
                break;
        case 'g':
-               tracing_group_name = strdup(arg);
-               if (tracing_group_name == NULL) {
-                       ret = -errno;
-                       PERROR("strdup");
-                       goto end;
+               if (lttng_is_setuid_setgid()) {
+                       WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                               "-g, --group");
+               } else {
+                       tracing_group_name = strdup(arg);
+                       if (tracing_group_name == NULL) {
+                               ret = -errno;
+                               PERROR("strdup");
+                               goto end;
+                       }
+                       tracing_group_name_override = 1;
                }
-               tracing_group_name_override = 1;
                break;
        case 'h':
                usage();
                exit(EXIT_FAILURE);
        case 'o':
-               ret = asprintf(&opt_output_path, "%s", arg);
-               if (ret < 0) {
-                       ret = -errno;
-                       PERROR("asprintf opt_output_path");
-                       goto end;
+               if (lttng_is_setuid_setgid()) {
+                       WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                               "-o, --output");
+               } else {
+                       ret = asprintf(&opt_output_path, "%s", arg);
+                       if (ret < 0) {
+                               ret = -errno;
+                               PERROR("asprintf opt_output_path");
+                               goto end;
+                       }
                }
                break;
        case 'v':
@@ -359,9 +385,14 @@ int set_options(int argc, char **argv)
                        continue;
                }
 
-               config_path = utils_expand_path(optarg);
-               if (!config_path) {
-                       ERR("Failed to resolve path: %s", optarg);
+               if (lttng_is_setuid_setgid()) {
+                       WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                               "-f, --config");
+               } else {
+                       config_path = utils_expand_path(optarg);
+                       if (!config_path) {
+                               ERR("Failed to resolve path: %s", optarg);
+                       }
                }
        }
 
@@ -868,6 +899,11 @@ restart:
                        revents = LTTNG_POLL_GETEV(&events, i);
                        pollfd = LTTNG_POLL_GETFD(&events, i);
 
+                       if (!revents) {
+                               /* No activity for this FD (poll implementation). */
+                               continue;
+                       }
+
                        /* Thread quit pipe has been closed. Killing thread. */
                        ret = check_thread_quit_pipe(pollfd, revents);
                        if (ret) {
@@ -2354,7 +2390,7 @@ int relay_process_data(struct relay_connection *conn)
                                pthread_mutex_lock(&vstream->overwrite_lock);
                                vstream->abort_flag = 1;
                                pthread_mutex_unlock(&vstream->overwrite_lock);
-                               DBG("Streaming side setting abort_flag on stream %s_%lu\n",
+                               DBG("Streaming side setting abort_flag on stream %s_%" PRIu64 "\n",
                                                stream->channel_name, new_id);
                        } else if (vstream->tracefile_count_current ==
                                        stream->tracefile_count_current) {
@@ -2536,6 +2572,11 @@ restart:
 
                        health_code_update();
 
+                       if (!revents) {
+                               /* No activity for this FD (poll implementation). */
+                               continue;
+                       }
+
                        /* Thread quit pipe has been closed. Killing thread. */
                        ret = check_thread_quit_pipe(pollfd, revents);
                        if (ret) {
@@ -2638,46 +2679,49 @@ restart:
 
                        health_code_update();
 
+                       if (!revents) {
+                               /* No activity for this FD (poll implementation). */
+                               continue;
+                       }
+
                        /* Skip the command pipe. It's handled in the first loop. */
                        if (pollfd == relay_conn_pipe[0]) {
                                continue;
                        }
 
-                       if (revents) {
-                               rcu_read_lock();
-                               conn = connection_find_by_sock(relay_connections_ht, pollfd);
-                               if (!conn) {
-                                       /* Skip it. Might be removed before. */
+                       rcu_read_lock();
+                       conn = connection_find_by_sock(relay_connections_ht, pollfd);
+                       if (!conn) {
+                               /* Skip it. Might be removed before. */
+                               rcu_read_unlock();
+                               continue;
+                       }
+
+                       if (revents & LPOLLIN) {
+                               if (conn->type != RELAY_DATA) {
                                        rcu_read_unlock();
                                        continue;
                                }
 
-                               if (revents & LPOLLIN) {
-                                       if (conn->type != RELAY_DATA) {
-                                               rcu_read_unlock();
-                                               continue;
-                                       }
-
-                                       ret = relay_process_data(conn);
-                                       /* Connection closed */
-                                       if (ret < 0) {
-                                               cleanup_connection_pollfd(&events, pollfd);
-                                               destroy_connection(relay_connections_ht, conn);
-                                               DBG("Data connection closed with %d", pollfd);
-                                               /*
-                                                * Every goto restart call sets the last seen fd where
-                                                * here we don't really care since we gracefully
-                                                * continue the loop after the connection is deleted.
-                                                */
-                                       } else {
-                                               /* Keep last seen port. */
-                                               last_seen_data_fd = pollfd;
-                                               rcu_read_unlock();
-                                               goto restart;
-                                       }
+                               ret = relay_process_data(conn);
+                               /* Connection closed */
+                               if (ret < 0) {
+                                       cleanup_connection_pollfd(&events, pollfd);
+                                       destroy_connection(relay_connections_ht, conn);
+                                       DBG("Data connection closed with %d", pollfd);
+                                       /*
+                                        * Every goto restart call sets the last seen fd where
+                                        * here we don't really care since we gracefully
+                                        * continue the loop after the connection is deleted.
+                                        */
+                               } else {
+                                       /* Keep last seen port. */
+                                       last_seen_data_fd = pollfd;
+                                       rcu_read_unlock();
+                                       goto restart;
                                }
-                               rcu_read_unlock();
                        }
+                       rcu_read_unlock();
                }
                last_seen_data_fd = -1;
        }
@@ -2837,7 +2881,10 @@ int main(int argc, char **argv)
        cds_wfcq_init(&relay_conn_queue.head, &relay_conn_queue.tail);
 
        /* Set up max poll set size */
-       lttng_poll_set_max_size();
+       if (lttng_poll_set_max_size()) {
+               retval = -1;
+               goto exit_init_data;
+       }
 
        /* Initialize communication library */
        lttcomm_init();
This page took 0.027754 seconds and 4 git commands to generate.