X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=b2a8f555c5fc072b39e1e922a5eef84a2b1b8f43;hp=0dbec232fe90c3dcca0e9fea4166fee09099e592;hb=a5dfbb9db7ba31913657ed921006b13977b7b426;hpb=6f04ed72990f6c72d16fd08d39feac0967da732e diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 0dbec232f..b2a8f555c 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -367,19 +368,19 @@ void setup_consumerd_path(void) /* * runtime env. var. overrides the build default. */ - bin = getenv("LTTNG_CONSUMERD32_BIN"); + bin = lttng_secure_getenv("LTTNG_CONSUMERD32_BIN"); if (bin) { consumerd32_bin = bin; } - bin = getenv("LTTNG_CONSUMERD64_BIN"); + bin = lttng_secure_getenv("LTTNG_CONSUMERD64_BIN"); if (bin) { consumerd64_bin = bin; } - libdir = getenv("LTTNG_CONSUMERD32_LIBDIR"); + libdir = lttng_secure_getenv("LTTNG_CONSUMERD32_LIBDIR"); if (libdir) { consumerd32_libdir = libdir; } - libdir = getenv("LTTNG_CONSUMERD64_LIBDIR"); + libdir = lttng_secure_getenv("LTTNG_CONSUMERD64_LIBDIR"); if (libdir) { consumerd64_libdir = libdir; } @@ -993,10 +994,30 @@ static void update_ust_app(int app_sock) /* For all tracing session(s) */ cds_list_for_each_entry_safe(sess, stmp, &session_list_ptr->head, list) { + struct ust_app *app; + session_lock(sess); - if (sess->ust_session) { - ust_app_global_update(sess->ust_session, app_sock); + if (!sess->ust_session) { + goto unlock_session; } + + rcu_read_lock(); + assert(app_sock >= 0); + app = ust_app_find_by_sock(app_sock); + if (app == NULL) { + /* + * Application can be unregistered before so + * this is possible hence simply stopping the + * update. + */ + DBG3("UST app update failed to find app sock %d", + app_sock); + goto unlock_rcu; + } + ust_app_global_update(sess->ust_session, app); + unlock_rcu: + rcu_read_unlock(); + unlock_session: session_unlock(sess); } } @@ -1059,12 +1080,14 @@ static void *thread_manage_kernel(void *data) update_poll_flag = 0; } - DBG("Thread kernel polling on %d fds", LTTNG_POLL_GETNB(&events)); + DBG("Thread kernel polling"); /* Poll infinite value of time */ restart: health_poll_entry(); ret = lttng_poll_wait(&events, -1); + DBG("Thread kernel return from poll on %d fds", + LTTNG_POLL_GETNB(&events)); health_poll_exit(); if (ret < 0) { /* @@ -1090,6 +1113,11 @@ static void *thread_manage_kernel(void *data) health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -1235,6 +1263,11 @@ restart: health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -1362,6 +1395,11 @@ restart_poll: health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* * Thread quit pipe has been triggered, flag that we should stop * but continue the current loop to handle potential data from @@ -1512,12 +1550,14 @@ static void *thread_manage_apps(void *data) health_code_update(); while (1) { - DBG("Apps thread polling on %d fds", LTTNG_POLL_GETNB(&events)); + DBG("Apps thread polling"); /* Inifinite blocking call, waiting for transmission */ restart: health_poll_entry(); ret = lttng_poll_wait(&events, -1); + DBG("Apps thread return from poll on %d fds", + LTTNG_POLL_GETNB(&events)); health_poll_exit(); if (ret < 0) { /* @@ -1538,6 +1578,11 @@ static void *thread_manage_apps(void *data) health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -1716,6 +1761,11 @@ static void sanitize_wait_queue(struct ust_reg_wait_queue *wait_queue) uint32_t revents = LTTNG_POLL_GETEV(&events, i); int pollfd = LTTNG_POLL_GETFD(&events, i); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + cds_list_for_each_entry_safe(wait_node, tmp_wait_node, &wait_queue->head, head) { if (pollfd == wait_node->app->sock && @@ -2055,6 +2105,11 @@ static void *thread_registration_apps(void *data) 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 = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -2406,7 +2461,7 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) char *tmp; size_t tmplen; - tmp = getenv("LD_LIBRARY_PATH"); + tmp = lttng_secure_getenv("LD_LIBRARY_PATH"); if (!tmp) { tmp = ""; } @@ -2449,7 +2504,7 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) char *tmp; size_t tmplen; - tmp = getenv("LD_LIBRARY_PATH"); + tmp = lttng_secure_getenv("LD_LIBRARY_PATH"); if (!tmp) { tmp = ""; } @@ -2730,7 +2785,16 @@ static int create_ust_session(struct ltt_session *session, lus->snapshot_mode = session->snapshot_mode; lus->live_timer_interval = session->live_timer; session->ust_session = lus; - + if (session->shm_path[0]) { + strncpy(lus->root_shm_path, session->shm_path, + sizeof(lus->root_shm_path)); + lus->root_shm_path[sizeof(lus->root_shm_path) - 1] = '\0'; + strncpy(lus->shm_path, session->shm_path, + sizeof(lus->shm_path)); + lus->shm_path[sizeof(lus->shm_path) - 1] = '\0'; + strncat(lus->shm_path, "/ust", + sizeof(lus->shm_path) - strlen(lus->shm_path) - 1); + } /* Copy session output to the newly created UST session */ ret = copy_session_consumer(domain->type, session); if (ret != LTTNG_OK) { @@ -2855,6 +2919,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_SNAPSHOT_LIST_OUTPUT: case LTTNG_SNAPSHOT_RECORD: case LTTNG_SAVE_SESSION: + case LTTNG_SET_SESSION_SHM_PATH: need_domain = 0; break; default: @@ -2895,6 +2960,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_LIST_CHANNELS: case LTTNG_LIST_EVENTS: case LTTNG_LIST_SYSCALLS: + case LTTNG_LIST_TRACKER_PIDS: break; default: /* Setup lttng message with no payload */ @@ -3207,6 +3273,20 @@ skip_domain: &cmd_ctx->lsm->u.channel.chan, kernel_poll_pipe[1]); break; } + case LTTNG_TRACK_PID: + { + ret = cmd_track_pid(cmd_ctx->session, + cmd_ctx->lsm->domain.type, + cmd_ctx->lsm->u.pid_tracker.pid); + break; + } + case LTTNG_UNTRACK_PID: + { + ret = cmd_untrack_pid(cmd_ctx->session, + cmd_ctx->lsm->domain.type, + cmd_ctx->lsm->u.pid_tracker.pid); + break; + } case LTTNG_ENABLE_EVENT: { struct lttng_event_exclusion *exclusion = NULL; @@ -3416,6 +3496,38 @@ skip_domain: ret = LTTNG_OK; break; } + case LTTNG_LIST_TRACKER_PIDS: + { + int32_t *pids = NULL; + ssize_t nr_pids; + + nr_pids = cmd_list_tracker_pids(cmd_ctx->session, + cmd_ctx->lsm->domain.type, &pids); + if (nr_pids < 0) { + /* Return value is a negative lttng_error_code. */ + ret = -nr_pids; + goto error; + } + + /* + * Setup lttng message with payload size set to the event list size in + * bytes and then copy list into the llm payload. + */ + ret = setup_lttng_msg(cmd_ctx, sizeof(int32_t) * nr_pids); + if (ret < 0) { + free(pids); + goto setup_error; + } + + /* Copy event list into message payload */ + memcpy(cmd_ctx->llm->payload, pids, + sizeof(int) * nr_pids); + + free(pids); + + ret = LTTNG_OK; + break; + } case LTTNG_SET_CONSUMER_URI: { size_t nb_uri, len; @@ -3795,6 +3907,12 @@ skip_domain: &cmd_ctx->creds); break; } + case LTTNG_SET_SESSION_SHM_PATH: + { + ret = cmd_set_session_shm_path(cmd_ctx->session, + cmd_ctx->lsm->u.set_shm_path.shm_path); + break; + } default: ret = LTTNG_ERR_UND; break; @@ -3918,6 +4036,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 = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -4090,6 +4213,11 @@ static void *thread_manage_clients(void *data) health_code_update(); + if (!revents) { + /* No activity for this FD (poll implementation). */ + continue; + } + /* Thread quit pipe has been closed. Killing thread. */ ret = sessiond_check_thread_quit_pipe(pollfd, revents); if (ret) { @@ -4341,10 +4469,20 @@ static int set_option(int opt, const char *arg, const char *optname) } break; case 'c': - snprintf(client_unix_sock_path, PATH_MAX, "%s", arg); + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "-c, --client-sock"); + } else { + snprintf(client_unix_sock_path, PATH_MAX, "%s", arg); + } break; case 'a': - snprintf(apps_unix_sock_path, PATH_MAX, "%s", arg); + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "-a, --apps-sock"); + } else { + snprintf(apps_unix_sock_path, PATH_MAX, "%s", arg); + } break; case 'd': opt_daemon = 1; @@ -4353,20 +4491,25 @@ static int set_option(int opt, const char *arg, const char *optname) opt_background = 1; break; case 'g': - /* - * If the override option is set, the pointer points to a - * *non* const thus freeing it even though the variable type is - * set to const. - */ - if (tracing_group_name_override) { - free((void *) tracing_group_name); - } - tracing_group_name = strdup(arg); - if (!tracing_group_name) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "-g, --group"); + } else { + /* + * If the override option is set, the pointer points to a + * *non* const thus freeing it even though the variable type is + * set to const. + */ + if (tracing_group_name_override) { + free((void *) tracing_group_name); + } + tracing_group_name = strdup(arg); + if (!tracing_group_name) { + PERROR("strdup"); + ret = -ENOMEM; + } + tracing_group_name_override = 1; } - tracing_group_name_override = 1; break; case 'h': usage(); @@ -4378,22 +4521,52 @@ static int set_option(int opt, const char *arg, const char *optname) opt_sig_parent = 1; break; case 'E': - snprintf(kconsumer_data.err_unix_sock_path, PATH_MAX, "%s", arg); + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--kconsumerd-err-sock"); + } else { + snprintf(kconsumer_data.err_unix_sock_path, PATH_MAX, "%s", arg); + } break; case 'C': - snprintf(kconsumer_data.cmd_unix_sock_path, PATH_MAX, "%s", arg); + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--kconsumerd-cmd-sock"); + } else { + snprintf(kconsumer_data.cmd_unix_sock_path, PATH_MAX, "%s", arg); + } break; case 'F': - snprintf(ustconsumer64_data.err_unix_sock_path, PATH_MAX, "%s", arg); + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--ustconsumerd64-err-sock"); + } else { + snprintf(ustconsumer64_data.err_unix_sock_path, PATH_MAX, "%s", arg); + } break; case 'D': - snprintf(ustconsumer64_data.cmd_unix_sock_path, PATH_MAX, "%s", arg); + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--ustconsumerd64-cmd-sock"); + } else { + snprintf(ustconsumer64_data.cmd_unix_sock_path, PATH_MAX, "%s", arg); + } break; case 'H': - snprintf(ustconsumer32_data.err_unix_sock_path, PATH_MAX, "%s", arg); + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--ustconsumerd32-err-sock"); + } else { + snprintf(ustconsumer32_data.err_unix_sock_path, PATH_MAX, "%s", arg); + } break; case 'G': - snprintf(ustconsumer32_data.cmd_unix_sock_path, PATH_MAX, "%s", arg); + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--ustconsumerd32-cmd-sock"); + } else { + snprintf(ustconsumer32_data.cmd_unix_sock_path, PATH_MAX, "%s", arg); + } break; case 'N': opt_no_kernel = 1; @@ -4422,97 +4595,146 @@ static int set_option(int opt, const char *arg, const char *optname) } break; case 'u': - if (consumerd32_bin_override) { - free((void *) consumerd32_bin); - } - consumerd32_bin = strdup(arg); - if (!consumerd32_bin) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--consumerd32-path"); + } else { + if (consumerd32_bin_override) { + free((void *) consumerd32_bin); + } + consumerd32_bin = strdup(arg); + if (!consumerd32_bin) { + PERROR("strdup"); + ret = -ENOMEM; + } + consumerd32_bin_override = 1; } - consumerd32_bin_override = 1; break; case 'U': - if (consumerd32_libdir_override) { - free((void *) consumerd32_libdir); - } - consumerd32_libdir = strdup(arg); - if (!consumerd32_libdir) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--consumerd32-libdir"); + } else { + if (consumerd32_libdir_override) { + free((void *) consumerd32_libdir); + } + consumerd32_libdir = strdup(arg); + if (!consumerd32_libdir) { + PERROR("strdup"); + ret = -ENOMEM; + } + consumerd32_libdir_override = 1; } - consumerd32_libdir_override = 1; break; case 't': - if (consumerd64_bin_override) { - free((void *) consumerd64_bin); - } - consumerd64_bin = strdup(arg); - if (!consumerd64_bin) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--consumerd64-path"); + } else { + if (consumerd64_bin_override) { + free((void *) consumerd64_bin); + } + consumerd64_bin = strdup(arg); + if (!consumerd64_bin) { + PERROR("strdup"); + ret = -ENOMEM; + } + consumerd64_bin_override = 1; } - consumerd64_bin_override = 1; break; case 'T': - if (consumerd64_libdir_override) { - free((void *) consumerd64_libdir); - } - consumerd64_libdir = strdup(arg); - if (!consumerd64_libdir) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--consumerd64-libdir"); + } else { + if (consumerd64_libdir_override) { + free((void *) consumerd64_libdir); + } + consumerd64_libdir = strdup(arg); + if (!consumerd64_libdir) { + PERROR("strdup"); + ret = -ENOMEM; + } + consumerd64_libdir_override = 1; } - consumerd64_libdir_override = 1; break; case 'p': - free(opt_pidfile); - opt_pidfile = strdup(arg); - if (!opt_pidfile) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "-p, --pidfile"); + } else { + free(opt_pidfile); + opt_pidfile = strdup(arg); + if (!opt_pidfile) { + PERROR("strdup"); + ret = -ENOMEM; + } } break; case 'J': /* Agent TCP port. */ { - unsigned long v; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--agent-tcp-port"); + } else { + unsigned long v; - errno = 0; - v = strtoul(arg, NULL, 0); - if (errno != 0 || !isdigit(arg[0])) { - ERR("Wrong value in --agent-tcp-port parameter: %s", arg); - return -1; - } - if (v == 0 || v >= 65535) { - ERR("Port overflow in --agent-tcp-port parameter: %s", arg); - return -1; + if (!arg) { + ret = -EINVAL; + goto end; + } + errno = 0; + v = strtoul(arg, NULL, 0); + if (errno != 0 || !isdigit(arg[0])) { + ERR("Wrong value in --agent-tcp-port parameter: %s", arg); + return -1; + } + if (v == 0 || v >= 65535) { + ERR("Port overflow in --agent-tcp-port parameter: %s", arg); + return -1; + } + agent_tcp_port = (uint32_t) v; + DBG3("Agent TCP port set to non default: %u", agent_tcp_port); } - agent_tcp_port = (uint32_t) v; - DBG3("Agent TCP port set to non default: %u", agent_tcp_port); break; } case 'l': - free(opt_load_session_path); - opt_load_session_path = strdup(arg); - if (!opt_load_session_path) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "-l, --load"); + } else { + free(opt_load_session_path); + opt_load_session_path = strdup(arg); + if (!opt_load_session_path) { + PERROR("strdup"); + ret = -ENOMEM; + } } break; case 'P': /* probe modules list */ - free(kmod_probes_list); - kmod_probes_list = strdup(arg); - if (!kmod_probes_list) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--kmod-probes"); + } else { + free(kmod_probes_list); + kmod_probes_list = strdup(arg); + if (!kmod_probes_list) { + PERROR("strdup"); + ret = -ENOMEM; + } } break; case 'e': - free(kmod_extra_probes_list); - kmod_extra_probes_list = strdup(arg); - if (!kmod_extra_probes_list) { - PERROR("strdup"); - ret = -ENOMEM; + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "--extra-kmod-probes"); + } else { + free(kmod_extra_probes_list); + kmod_extra_probes_list = strdup(arg); + if (!kmod_extra_probes_list) { + PERROR("strdup"); + ret = -ENOMEM; + } } break; case 'f': @@ -4628,9 +4850,14 @@ static 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); + } } } @@ -5165,6 +5392,12 @@ int main(int argc, char **argv) goto exit_ht_cleanup_pipe; } + /* Set up max poll set size */ + if (lttng_poll_set_max_size()) { + retval = -1; + goto exit_set_max_size; + } + /* Create thread to clean up RCU hash tables */ ret = pthread_create(&ht_cleanup_thread, NULL, thread_ht_cleanup, (void *) NULL); @@ -5499,9 +5732,6 @@ int main(int argc, char **argv) */ session_list_ptr = session_get_list(); - /* Set up max poll set size */ - lttng_poll_set_max_size(); - cmd_init(); /* Check for the application socket timeout env variable. */ @@ -5731,6 +5961,7 @@ exit_init_data: retval = -1; } exit_ht_cleanup: +exit_set_max_size: utils_close_pipe(ht_cleanup_pipe); exit_ht_cleanup_pipe: