sessiond: exit early if it's possible to self-trace with blocking mode set
authorKienan Stewart <kstewart@efficios.com>
Thu, 23 Nov 2023 19:16:21 +0000 (14:16 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 31 Oct 2024 15:40:41 +0000 (11:40 -0400)
Signed-off-by: Kienan Stewart <kstewart@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I13e76160135e1cd9f0cb7d5ebe16e9662c1aee56

src/bin/lttng-sessiond/main.cpp
src/common/defaults.hpp
src/common/path.cpp
src/common/path.hpp

index 0902969e71dee38b7319e007329e823e785afdc6..cb3896e27d0c5f8f0d320e90921bde2e5acd0b87 100644 (file)
 #include <common/daemonize.hpp>
 #include <common/defaults.hpp>
 #include <common/dynamic-buffer.hpp>
+#include <common/exception.hpp>
 #include <common/futex.hpp>
 #include <common/ini-config/ini-config.hpp>
 #include <common/kernel-consumer/kernel-consumer.hpp>
 #include <common/lockfile.hpp>
 #include <common/logging-utils.hpp>
+#include <common/make-unique-wrapper.hpp>
 #include <common/path.hpp>
 #include <common/relayd/relayd.hpp>
 #include <common/utils.hpp>
@@ -64,6 +66,7 @@
 #include <getopt.h>
 #include <grp.h>
 #include <inttypes.h>
+#include <libgen.h>
 #include <limits.h>
 #include <paths.h>
 #include <pthread.h>
@@ -939,6 +942,97 @@ end:
        return ret;
 }
 
+namespace {
+std::string dirname_str(const char *dir)
+{
+       auto dir_copy = lttng::make_unique_wrapper<char, lttng::memory::free>(strdup(dir));
+
+       if (!dir_copy) {
+               LTTNG_THROW_ALLOCATION_FAILURE_ERROR("Failed to copy path before use of dirname",
+                                                    strlen(dir) + 1);
+       }
+
+       return std::string(dirname(dir_copy.get()));
+}
+
+/*
+ * Check to see if there the settings of LTTNG_UST_APP_PATH and LTTNG_UST_CTL_PATH
+ * are such that the sessiond could potentially trace itself while blocking mode
+ * can be enabled for any of the sessions.
+ *
+ * Throws lttng::unsupported_error is the configuration is illegal.
+ */
+void check_trace_self_blocking()
+{
+       const auto *allow_blocking = lttng_secure_getenv("LTTNG_UST_ALLOW_BLOCKING");
+       if (!allow_blocking) {
+               return;
+       }
+
+       const auto *ust_app_path = lttng_secure_getenv(DEFAULT_LTTNG_UST_APP_PATH_ENV_VAR);
+       const auto *ust_ctl_path = lttng_secure_getenv(DEFAULT_LTTNG_UST_CTL_PATH_ENV_VAR);
+       if (ust_app_path == nullptr && ust_ctl_path == nullptr) {
+               /* Session daemon could block, disallow this configuration. */
+               LTTNG_THROW_UNSUPPORTED_ERROR(
+                       "Cannot launch session daemon with LTTNG_UST_ALLOW_BLOCKING set using default application and control paths");
+       }
+
+       /* Use the resolved ctl path from the configuration. */
+       ust_ctl_path = the_config.apps_unix_sock_path.value;
+       LTTNG_ASSERT(ust_ctl_path);
+
+       std::string canonical_ust_app_path;
+       const auto canonical_ust_ctl_path = lttng::make_unique_wrapper<char, lttng::memory::free>(
+               utils_partial_realpath(dirname_str(ust_ctl_path).c_str()));
+       if (!canonical_ust_ctl_path) {
+               LTTNG_THROW_ERROR("Failed to determine canonical ust-ctl path from override");
+       }
+
+       /*
+        * When the environment variable for ust app path isn't set, assume it
+        * will be in the rundir. This might not actually be correct when root.
+        */
+       if (!ust_app_path) {
+               ust_app_path = the_config.rundir.value;
+               LTTNG_ASSERT(the_config.rundir.value);
+
+               auto resolved_app_path = lttng::make_unique_wrapper<char, lttng::memory::free>(
+                       utils_partial_realpath(ust_app_path));
+               if (!resolved_app_path) {
+                       LTTNG_THROW_ERROR(
+                               "Failed to determine canonical ust app path from override");
+               }
+
+               canonical_ust_app_path = resolved_app_path.get();
+       } else {
+               /*
+                * Find the position of ':' or the end of the c-string in case the variable is a
+                * list of values.
+                */
+               const auto end =
+                       std::find(ust_app_path, ust_app_path + std::strlen(ust_app_path), ':');
+
+               std::string first_entry_of_list;
+               std::copy(ust_app_path, end, std::back_inserter(first_entry_of_list));
+
+               auto resolved_app_path = lttng::make_unique_wrapper<char, lttng::memory::free>(
+                       utils_partial_realpath(first_entry_of_list.c_str()));
+               if (!resolved_app_path) {
+                       LTTNG_THROW_ERROR(
+                               "Failed to determine canonical ust app path from override");
+               }
+
+               canonical_ust_app_path = resolved_app_path.get();
+       }
+
+       if (canonical_ust_app_path != canonical_ust_ctl_path.get()) {
+               return;
+       }
+
+       LTTNG_THROW_UNSUPPORTED_ERROR("Cannot trace self with LTTNG_UST_ALLOW_BLOCKING set");
+}
+} /* namespace */
+
 static void sessiond_cleanup_lock_file()
 {
        int ret;
@@ -1488,6 +1582,18 @@ static int _main(int argc, char **argv)
        sessiond_uuid_log();
        lttng::logging::log_system_information(PRINT_DBG);
 
+       /*
+        * If the lttng-sessiond may trace itself, stop startup if blocking mode
+        * is allowed by the LTTNG_UST_ALLOW_BLOCKING environment variable.
+        */
+       try {
+               check_trace_self_blocking();
+       } catch (const std::exception& ex) {
+               ERR_FMT(ex.what());
+               retval = -1;
+               goto exit_options;
+       }
+
        if (opt_print_version) {
                print_version();
                retval = 0;
index 8fbe819f313618ca343ba5e96390f6a9e747a483..a2664a433c85479bb4fef4e134b3f8a727dceead 100644 (file)
 #define DEFAULT_LTTNG_HOME_ENV_VAR           "LTTNG_HOME"
 #define DEFAULT_LTTNG_FALLBACK_HOME_ENV_VAR   "HOME"
 #define DEFAULT_LTTNG_UST_CTL_PATH_ENV_VAR    "LTTNG_UST_CTL_PATH"
+#define DEFAULT_LTTNG_UST_APP_PATH_ENV_VAR    "LTTNG_UST_APP_PATH"
 #define DEFAULT_LTTNG_RUNDIR                 CONFIG_LTTNG_SYSTEM_RUNDIR
 #define DEFAULT_LTTNG_HOME_RUNDIR            "%s/.lttng"
 #define DEFAULT_LTTNG_SESSIOND_PIDFILE       "lttng-sessiond.pid"
index 14611c2164812245f0d0a2c48a6675e80db40610..c4fb41e233a4f525fd9c9ce58c28a4447dd34ec3 100644 (file)
@@ -21,7 +21,7 @@
  *
  * Return a newly-allocated string.
  */
-static char *utils_partial_realpath(const char *path)
+char *utils_partial_realpath(const char *path)
 {
        char *cut_path = nullptr, *try_path = nullptr, *try_path_prev = nullptr;
        const char *next, *prev, *end;
index 3f81eeb202e0f1bdd82214dd8c2fffcfd9e33945..19d9e05637464b7c29583f7d691044c2e2ee0044 100644 (file)
@@ -9,5 +9,6 @@
 
 char *utils_expand_path(const char *path);
 char *utils_expand_path_keep_symlink(const char *path);
+char *utils_partial_realpath(const char *path);
 
 #endif /* _COMMON_PATH_H */
This page took 0.028244 seconds and 4 git commands to generate.