From 76d7553fcee76da7c103c3b51a6b01f46cd784c8 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 2 Mar 2012 12:57:38 -0500 Subject: [PATCH] Fix: large audit of close() use in sessiond main.c Signed-off-by: Mathieu Desnoyers --- src/bin/lttng-sessiond/main.c | 244 ++++++++++++++++++++++------------ src/common/compat/poll.h | 8 +- src/common/error.h | 3 +- 3 files changed, 168 insertions(+), 87 deletions(-) diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index efe2143dd..17ef7f71c 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -125,19 +125,19 @@ static char wait_shm_path[PATH_MAX]; static int client_sock = -1; static int apps_sock = -1; static int kernel_tracer_fd = -1; -static int kernel_poll_pipe[2]; +static int kernel_poll_pipe[2] = { -1, -1 }; /* * Quit pipe for all threads. This permits a single cancellation point * for all threads when receiving an event on the pipe. */ -static int thread_quit_pipe[2]; +static int thread_quit_pipe[2] = { -1, -1 }; /* * This pipe is used to inform the thread managing application communication * that a command is queued and ready to be processed. */ -static int apps_cmd_pipe[2]; +static int apps_cmd_pipe[2] = { -1, -1 }; /* Pthread, Mutexes and Semaphores */ static pthread_t apps_thread; @@ -299,7 +299,7 @@ static int init_thread_quit_pipe(void) ret = pipe2(thread_quit_pipe, O_CLOEXEC); if (ret < 0) { - perror("thread quit pipe"); + PERROR("thread quit pipe"); goto error; } @@ -378,7 +378,7 @@ static void stop_threads(void) */ static void cleanup(void) { - int ret; + int ret, i; char *cmd; struct ltt_session *sess, *stmp; @@ -420,14 +420,43 @@ static void cleanup(void) if (is_root && !opt_no_kernel) { DBG2("Closing kernel fd"); if (kernel_tracer_fd >= 0) { - close(kernel_tracer_fd); + ret = close(kernel_tracer_fd); + if (ret) { + PERROR("close"); + } } DBG("Unloading kernel modules"); modprobe_remove_lttng_all(); } - close(thread_quit_pipe[0]); - close(thread_quit_pipe[1]); + /* + * Closing all pipes used for communication between threads. + */ + for (i = 0; i < 2; i++) { + if (kernel_poll_pipe[i] >= 0) { + ret = close(kernel_poll_pipe[i]); + if (ret) { + PERROR("close"); + } + + } + } + for (i = 0; i < 2; i++) { + if (thread_quit_pipe[i] >= 0) { + ret = close(thread_quit_pipe[i]); + if (ret) { + PERROR("close"); + } + } + } + for (i = 0; i < 2; i++) { + if (apps_cmd_pipe[i] >= 0) { + ret = close(apps_cmd_pipe[i]); + if (ret) { + PERROR("close"); + } + } + } /* */ DBG("%c[%d;%dm*** assert failed :-) *** ==> %c[%dm%c[%d;%dm" @@ -491,7 +520,7 @@ static int send_kconsumer_channel_streams(struct consumer_data *consumer_data, DBG("Sending channel %d to consumer", lkm.u.channel.channel_key); ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm)); if (ret < 0) { - perror("send consumer channel"); + PERROR("send consumer channel"); goto error; } @@ -513,12 +542,12 @@ static int send_kconsumer_channel_streams(struct consumer_data *consumer_data, DBG("Sending stream %d to consumer", lkm.u.stream.stream_key); ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm)); if (ret < 0) { - perror("send consumer stream"); + PERROR("send consumer stream"); goto error; } ret = lttcomm_send_fds_unix_sock(sock, &stream->fd, 1); if (ret < 0) { - perror("send consumer stream ancillary data"); + PERROR("send consumer stream ancillary data"); goto error; } } @@ -558,7 +587,7 @@ static int send_kconsumer_session_streams(struct consumer_data *consumer_data, DBG("Sending metadata channel %d to consumer", lkm.u.stream.stream_key); ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm)); if (ret < 0) { - perror("send consumer channel"); + PERROR("send consumer channel"); goto error; } @@ -576,12 +605,12 @@ static int send_kconsumer_session_streams(struct consumer_data *consumer_data, DBG("Sending metadata stream %d to consumer", lkm.u.stream.stream_key); ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm)); if (ret < 0) { - perror("send consumer stream"); + PERROR("send consumer stream"); goto error; } ret = lttcomm_send_fds_unix_sock(sock, &session->metadata_stream_fd, 1); if (ret < 0) { - perror("send consumer stream"); + PERROR("send consumer stream"); goto error; } } @@ -642,7 +671,7 @@ static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size) cmd_ctx->llm = zmalloc(sizeof(struct lttcomm_lttng_msg) + buf_size); if (cmd_ctx->llm == NULL) { - perror("zmalloc"); + PERROR("zmalloc"); ret = -ENOMEM; goto error; } @@ -802,7 +831,7 @@ static void *thread_manage_kernel(void *data) ret = create_thread_poll_set(&events, 2); if (ret < 0) { - goto error; + goto error_poll_create; } ret = lttng_poll_add(&events, kernel_poll_pipe[0], LPOLLIN); @@ -887,12 +916,9 @@ static void *thread_manage_kernel(void *data) } error: - DBG("Kernel thread dying"); - close(kernel_poll_pipe[0]); - close(kernel_poll_pipe[1]); - lttng_poll_clean(&events); - +error_poll_create: + DBG("Kernel thread dying"); return NULL; } @@ -901,7 +927,7 @@ error: */ static void *thread_manage_consumer(void *data) { - int sock = 0, i, ret, pollfd; + int sock = -1, i, ret, pollfd; uint32_t revents, nb_fd; enum lttcomm_return_code code; struct lttng_poll_event events; @@ -911,7 +937,7 @@ static void *thread_manage_consumer(void *data) ret = lttcomm_listen_unix_sock(consumer_data->err_sock); if (ret < 0) { - goto error; + goto error_listen; } /* @@ -920,7 +946,7 @@ static void *thread_manage_consumer(void *data) */ ret = create_thread_poll_set(&events, 2); if (ret < 0) { - goto error; + goto error_poll; } ret = lttng_poll_add(&events, consumer_data->err_sock, LPOLLIN | LPOLLRDHUP); @@ -1052,16 +1078,33 @@ restart_poll: ERR("consumer return code : %s", lttcomm_get_readable_code(-code)); error: - DBG("consumer thread dying"); - close(consumer_data->err_sock); - close(consumer_data->cmd_sock); - close(sock); + if (consumer_data->err_sock >= 0) { + ret = close(consumer_data->err_sock); + if (ret) { + PERROR("close"); + } + } + if (consumer_data->cmd_sock >= 0) { + ret = close(consumer_data->cmd_sock); + if (ret) { + PERROR("close"); + } + } + if (sock >= 0) { + ret = close(sock); + if (ret) { + PERROR("close"); + } + } unlink(consumer_data->err_unix_sock_path); unlink(consumer_data->cmd_unix_sock_path); consumer_data->pid = 0; lttng_poll_clean(&events); +error_poll: +error_listen: + DBG("consumer thread cleanup completed"); return NULL; } @@ -1083,7 +1126,7 @@ static void *thread_manage_apps(void *data) ret = create_thread_poll_set(&events, 2); if (ret < 0) { - goto error; + goto error_poll_create; } ret = lttng_poll_add(&events, apps_cmd_pipe[0], LPOLLIN | LPOLLRDHUP); @@ -1132,7 +1175,7 @@ static void *thread_manage_apps(void *data) /* Empty pipe */ ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd)); if (ret < 0 || ret < sizeof(ust_cmd)) { - perror("read apps cmd pipe"); + PERROR("read apps cmd pipe"); goto error; } @@ -1203,12 +1246,9 @@ static void *thread_manage_apps(void *data) } error: - DBG("Application communication apps dying"); - close(apps_cmd_pipe[0]); - close(apps_cmd_pipe[1]); - lttng_poll_clean(&events); - +error_poll_create: + DBG("Application communication apps thread cleanup complete"); rcu_thread_offline(); rcu_unregister_thread(); return NULL; @@ -1255,7 +1295,7 @@ static void *thread_dispatch_ust_registration(void *data) ret = write(apps_cmd_pipe[1], ust_cmd, sizeof(struct ust_command)); if (ret < 0) { - perror("write apps cmd pipe"); + PERROR("write apps cmd pipe"); if (errno == EBADF) { /* * We can't inform the application thread to process @@ -1296,7 +1336,7 @@ static void *thread_registration_apps(void *data) ret = lttcomm_listen_unix_sock(apps_sock); if (ret < 0) { - goto error; + goto error_listen; } /* @@ -1305,13 +1345,13 @@ static void *thread_registration_apps(void *data) */ ret = create_thread_poll_set(&events, 2); if (ret < 0) { - goto error; + goto error_create_poll; } /* Add the application registration socket */ ret = lttng_poll_add(&events, apps_sock, LPOLLIN | LPOLLRDHUP); if (ret < 0) { - goto error; + goto error_poll_add; } /* Notify all applications to register */ @@ -1365,7 +1405,7 @@ static void *thread_registration_apps(void *data) /* Create UST registration command for enqueuing */ ust_cmd = zmalloc(sizeof(struct ust_command)); if (ust_cmd == NULL) { - perror("ust command zmalloc"); + PERROR("ust command zmalloc"); goto error; } @@ -1377,12 +1417,16 @@ static void *thread_registration_apps(void *data) sizeof(struct ust_register_msg)); if (ret < 0 || ret < sizeof(struct ust_register_msg)) { if (ret < 0) { - perror("lttcomm_recv_unix_sock register apps"); + PERROR("lttcomm_recv_unix_sock register apps"); } else { ERR("Wrong size received on apps register"); } free(ust_cmd); - close(sock); + ret = close(sock); + if (ret) { + PERROR("close"); + } + sock = -1; continue; } @@ -1412,20 +1456,28 @@ static void *thread_registration_apps(void *data) } error: - DBG("UST Registration thread dying"); - /* Notify that the registration thread is gone */ notify_ust_apps(0); if (apps_sock >= 0) { - close(apps_sock); + ret = close(apps_sock); + if (ret) { + PERROR("close"); + } } if (clock >= 0) { - close(sock); + ret = close(sock); + if (ret) { + PERROR("close"); + } } unlink(apps_unix_sock_path); +error_poll_add: lttng_poll_clean(&events); +error_listen: +error_create_poll: + DBG("UST Registration thread cleanup complete"); return NULL; } @@ -1665,17 +1717,17 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) break; } default: - perror("unknown consumer type"); + PERROR("unknown consumer type"); exit(EXIT_FAILURE); } if (errno != 0) { - perror("kernel start consumer exec"); + PERROR("kernel start consumer exec"); } exit(EXIT_FAILURE); } else if (pid > 0) { ret = pid; } else { - perror("start consumer fork"); + PERROR("start consumer fork"); ret = -errno; } error: @@ -1766,12 +1818,18 @@ static int init_kernel_tracer(void) error_version: modprobe_remove_lttng_control(); - close(kernel_tracer_fd); - kernel_tracer_fd = 0; + ret = close(kernel_tracer_fd); + if (ret) { + PERROR("close"); + } + kernel_tracer_fd = -1; return LTTCOMM_KERN_VERSION; error_modules: - close(kernel_tracer_fd); + ret = close(kernel_tracer_fd); + if (ret) { + PERROR("close"); + } error_open: modprobe_remove_lttng_control(); @@ -2948,7 +3006,7 @@ static int cmd_destroy_session(struct ltt_session *session, char *name) */ ret = notify_thread_pipe(kernel_poll_pipe[1]); if (ret < 0) { - perror("write kernel poll pipe"); + PERROR("write kernel poll pipe"); } ret = session_destroy(session); @@ -3685,14 +3743,14 @@ static void *thread_manage_clients(void *data) /* Allocate context command to process the client request */ cmd_ctx = zmalloc(sizeof(struct command_ctx)); if (cmd_ctx == NULL) { - perror("zmalloc cmd_ctx"); + PERROR("zmalloc cmd_ctx"); goto error; } /* Allocate data buffer for reception */ cmd_ctx->lsm = zmalloc(sizeof(struct lttcomm_session_msg)); if (cmd_ctx->lsm == NULL) { - perror("zmalloc cmd_ctx->lsm"); + PERROR("zmalloc cmd_ctx->lsm"); goto error; } @@ -3709,7 +3767,11 @@ static void *thread_manage_clients(void *data) sizeof(struct lttcomm_session_msg), &cmd_ctx->creds); if (ret <= 0) { DBG("Nothing recv() from client... continuing"); - close(sock); + ret = close(sock); + if (ret) { + PERROR("close"); + } + sock = -1; free(cmd_ctx); continue; } @@ -3745,7 +3807,11 @@ static void *thread_manage_clients(void *data) } /* End of transmission */ - close(sock); + ret = close(sock); + if (ret) { + PERROR("close"); + } + sock = -1; clean_command_ctx(&cmd_ctx); } @@ -3753,11 +3819,17 @@ static void *thread_manage_clients(void *data) error: DBG("Client thread dying"); unlink(client_unix_sock_path); - if (sock >= 0) { - close(client_sock); + if (client_sock >= 0) { + ret = close(client_sock); + if (ret) { + PERROR("close"); + } } if (sock >= 0) { - close(sock); + ret = close(sock); + if (ret) { + PERROR("close"); + } } lttng_poll_clean(&events); @@ -3942,7 +4014,7 @@ static int init_daemon_socket(void) ret = chmod(client_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (ret < 0) { ERR("Set file permissions failed: %s", client_unix_sock_path); - perror("chmod"); + PERROR("chmod"); goto end; } @@ -3959,7 +4031,7 @@ static int init_daemon_socket(void) S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (ret < 0) { ERR("Set file permissions failed: %s", apps_unix_sock_path); - perror("chmod"); + PERROR("chmod"); goto end; } @@ -4004,42 +4076,42 @@ static int set_permissions(char *rundir) ret = chown(rundir, 0, gid); if (ret < 0) { ERR("Unable to set group on %s", rundir); - perror("chown"); + PERROR("chown"); } /* Ensure tracing group can search the run dir */ ret = chmod(rundir, S_IRWXU | S_IXGRP | S_IXOTH); if (ret < 0) { ERR("Unable to set permissions on %s", rundir); - perror("chmod"); + PERROR("chmod"); } /* lttng client socket path */ ret = chown(client_unix_sock_path, 0, gid); if (ret < 0) { ERR("Unable to set group on %s", client_unix_sock_path); - perror("chown"); + PERROR("chown"); } /* kconsumer error socket path */ ret = chown(kconsumer_data.err_unix_sock_path, 0, gid); if (ret < 0) { ERR("Unable to set group on %s", kconsumer_data.err_unix_sock_path); - perror("chown"); + PERROR("chown"); } /* 64-bit ustconsumer error socket path */ ret = chown(ustconsumer64_data.err_unix_sock_path, 0, gid); if (ret < 0) { ERR("Unable to set group on %s", ustconsumer64_data.err_unix_sock_path); - perror("chown"); + PERROR("chown"); } /* 32-bit ustconsumer compat32 error socket path */ ret = chown(ustconsumer32_data.err_unix_sock_path, 0, gid); if (ret < 0) { ERR("Unable to set group on %s", ustconsumer32_data.err_unix_sock_path); - perror("chown"); + PERROR("chown"); } DBG("All permissions are set"); @@ -4050,6 +4122,7 @@ end: /* * Create the pipe used to wake up the kernel thread. + * Closed in cleanup(). */ static int create_kernel_poll_pipe(void) { @@ -4058,6 +4131,7 @@ static int create_kernel_poll_pipe(void) /* * Create the application command pipe to wake thread_manage_apps. + * Closed in cleanup(). */ static int create_apps_cmd_pipe(void) { @@ -4182,7 +4256,7 @@ static int set_signal_handler(void) sigset_t sigset; if ((ret = sigemptyset(&sigset)) < 0) { - perror("sigemptyset"); + PERROR("sigemptyset"); return ret; } @@ -4190,17 +4264,17 @@ static int set_signal_handler(void) sa.sa_mask = sigset; sa.sa_flags = 0; if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) { - perror("sigaction"); + PERROR("sigaction"); return ret; } if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) { - perror("sigaction"); + PERROR("sigaction"); return ret; } if ((ret = sigaction(SIGPIPE, &sa, NULL)) < 0) { - perror("sigaction"); + PERROR("sigaction"); return ret; } @@ -4224,7 +4298,7 @@ static void set_ulimit(void) ret = setrlimit(RLIMIT_NOFILE, &lim); if (ret < 0) { - perror("failed to set open files limit"); + PERROR("failed to set open files limit"); } } @@ -4258,7 +4332,7 @@ int main(int argc, char **argv) if (opt_daemon) { ret = daemon(0, 0); if (ret < 0) { - perror("daemon"); + PERROR("daemon"); goto error; } } @@ -4462,7 +4536,7 @@ int main(int argc, char **argv) ret = pthread_create(&client_thread, NULL, thread_manage_clients, (void *) NULL); if (ret != 0) { - perror("pthread_create clients"); + PERROR("pthread_create clients"); goto exit_client; } @@ -4470,7 +4544,7 @@ int main(int argc, char **argv) ret = pthread_create(&dispatch_thread, NULL, thread_dispatch_ust_registration, (void *) NULL); if (ret != 0) { - perror("pthread_create dispatch"); + PERROR("pthread_create dispatch"); goto exit_dispatch; } @@ -4478,7 +4552,7 @@ int main(int argc, char **argv) ret = pthread_create(®_apps_thread, NULL, thread_registration_apps, (void *) NULL); if (ret != 0) { - perror("pthread_create registration"); + PERROR("pthread_create registration"); goto exit_reg_apps; } @@ -4486,7 +4560,7 @@ int main(int argc, char **argv) ret = pthread_create(&apps_thread, NULL, thread_manage_apps, (void *) NULL); if (ret != 0) { - perror("pthread_create apps"); + PERROR("pthread_create apps"); goto exit_apps; } @@ -4494,47 +4568,47 @@ int main(int argc, char **argv) ret = pthread_create(&kernel_thread, NULL, thread_manage_kernel, (void *) NULL); if (ret != 0) { - perror("pthread_create kernel"); + PERROR("pthread_create kernel"); goto exit_kernel; } ret = pthread_join(kernel_thread, &status); if (ret != 0) { - perror("pthread_join"); + PERROR("pthread_join"); goto error; /* join error, exit without cleanup */ } exit_kernel: ret = pthread_join(apps_thread, &status); if (ret != 0) { - perror("pthread_join"); + PERROR("pthread_join"); goto error; /* join error, exit without cleanup */ } exit_apps: ret = pthread_join(reg_apps_thread, &status); if (ret != 0) { - perror("pthread_join"); + PERROR("pthread_join"); goto error; /* join error, exit without cleanup */ } exit_reg_apps: ret = pthread_join(dispatch_thread, &status); if (ret != 0) { - perror("pthread_join"); + PERROR("pthread_join"); goto error; /* join error, exit without cleanup */ } exit_dispatch: ret = pthread_join(client_thread, &status); if (ret != 0) { - perror("pthread_join"); + PERROR("pthread_join"); goto error; /* join error, exit without cleanup */ } ret = join_consumer_thread(&kconsumer_data); if (ret != 0) { - perror("join_consumer"); + PERROR("join_consumer"); goto error; /* join error, exit without cleanup */ } diff --git a/src/common/compat/poll.h b/src/common/compat/poll.h index 1580a4fb2..7af2ef050 100644 --- a/src/common/compat/poll.h +++ b/src/common/compat/poll.h @@ -50,6 +50,7 @@ static inline void __lttng_poll_free(void *events) */ #ifdef HAVE_EPOLL #include +#include /* See man epoll(7) for this define path */ #define COMPAT_EPOLL_PROC_PATH "/proc/sys/fs/epoll/max_user_watches" @@ -146,8 +147,13 @@ static inline void lttng_poll_reset(struct lttng_poll_event *events) */ static inline void lttng_poll_clean(struct lttng_poll_event *events) { + int ret; + if (events) { - close(events->epfd); + ret = close(events->epfd); + if (ret) { + perror("close"); + } __lttng_poll_free((void *) events->events); } } diff --git a/src/common/error.h b/src/common/error.h index 81c20223d..822dccfed 100644 --- a/src/common/error.h +++ b/src/common/error.h @@ -75,7 +75,8 @@ extern int opt_verbose; " [in %s() at " __FILE__ ":" XSTR(__LINE__) "]\n", ## args, __func__) #define _PERROR(fmt, args...) \ - __lttng_print(PRINT_ERR, "perror " fmt "\n", ## args) + __lttng_print(PRINT_ERR, "PERROR: " fmt \ + " [in %s() at " __FILE__ ":" XSTR(__LINE__) "]\n", ## args, __func__) #define PERROR(call, args...) \ do { \ -- 2.34.1