From ce9ee1fb2847b1603c4382c82aef95121f0e3d07 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Wed, 16 May 2018 18:24:01 -0400 Subject: [PATCH] relayd: introduce --working-directory/-w options MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This new option allows the user to specify the working directory (CWD) of the lttng-relayd process. This is especially useful when lttng-relayd is started in daemon mode (-d) because by default the CWD is set to "/". This can help control where coredumps, if any, get generated. Signed-off-by: Jonathan Rajotte Signed-off-by: Jérémie Galarneau --- src/bin/lttng-relayd/main.c | 27 +++++++++++++++++++++++++-- src/common/utils.c | 32 ++++++++++++++++++++++++++++++++ src/common/utils.h | 1 + 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 2836c489c..ad97a0b9b 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -96,7 +96,7 @@ enum relay_connection_status { }; /* command line options */ -char *opt_output_path; +char *opt_output_path, *opt_working_directory; static int opt_daemon, opt_background, opt_print_version; /* @@ -184,6 +184,7 @@ static struct option long_options[] = { { "verbose", 0, 0, 'v', }, { "config", 1, 0, 'f' }, { "version", 0, 0, 'V' }, + { "working-directory", 1, 0, 'w', }, { NULL, 0, 0, 0, }, }; @@ -311,6 +312,20 @@ static int set_option(int opt, const char *arg, const char *optname) } } break; + case 'w': + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "-w, --working-directory"); + } else { + ret = asprintf(&opt_working_directory, "%s", arg); + if (ret < 0) { + ret = -errno; + PERROR("asprintf opt_working_directory"); + goto end; + } + } + break; + case 'v': /* Verbose level can increase using multiple -v */ if (arg) { @@ -541,8 +556,8 @@ static void relayd_cleanup(void) if (sessions_ht) lttng_ht_destroy(sessions_ht); - /* free the dynamically allocated opt_output_path */ free(opt_output_path); + free(opt_working_directory); /* Close thread quit pipes */ utils_close_pipe(thread_quit_pipe); @@ -3729,6 +3744,14 @@ int main(int argc, char **argv) } } + if (opt_working_directory) { + ret = utils_change_working_directory(opt_working_directory); + if (ret) { + /* All errors are already logged. */ + goto exit_options; + } + } + sessiond_trace_chunk_registry = sessiond_trace_chunk_registry_create(); if (!sessiond_trace_chunk_registry) { ERR("Failed to initialize session daemon trace chunk registry"); diff --git a/src/common/utils.c b/src/common/utils.c index 3cdb6b760..0147c8c99 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -1501,3 +1501,35 @@ int utils_get_memory_total(size_t *value) { return read_proc_meminfo_field(PROC_MEMINFO_MEMTOTAL_LINE, value); } + +LTTNG_HIDDEN +int utils_change_working_directory(const char *path) +{ + int ret; + + assert(path); + + DBG("Changing working directory to \"%s\"", path); + ret = chdir(path); + if (ret) { + PERROR("Failed to change working directory to \"%s\"", path); + goto end; + } + + /* Check for write access */ + if (access(path, W_OK)) { + if (errno == EACCES) { + /* + * Do not treat this as an error since the permission + * might change in the lifetime of the process + */ + DBG("Working directory \"%s\" is not writable", path); + } else { + PERROR("Failed to check if working directory \"%s\" is writable", + path); + } + } + +end: + return ret; +} diff --git a/src/common/utils.h b/src/common/utils.h index 11388c903..27a6f4849 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -63,5 +63,6 @@ int utils_truncate_stream_file(int fd, off_t length); int utils_show_help(int section, const char *page_name, const char *help_msg); int utils_get_memory_available(size_t *value); int utils_get_memory_total(size_t *value); +int utils_change_working_directory(const char *path); #endif /* _COMMON_UTILS_H */ -- 2.34.1