Fix: setuid/setgid daemons should not get sensitive env. var./args
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 16 Jan 2015 17:48:20 +0000 (12:48 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 19 Jan 2015 19:06:09 +0000 (14:06 -0500)
Also, don't allow lttng command line interface to run as setuid/setgid
binary.

Fixes #780

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-consumerd/lttng-consumerd.c
src/bin/lttng-relayd/health-relayd.c
src/bin/lttng-relayd/main.c
src/bin/lttng-sessiond/main.c
src/bin/lttng/lttng.c
src/common/compat/Makefile.am
src/common/compat/getenv.h [new file with mode: 0644]
src/common/config/config.c
src/common/runas.c
src/common/utils.c

index 7122d065e649aa41533d4319af9d88010d4b4890..626fbb73a1fe960b1cdfc03fc44789c46442e8e6 100644 (file)
@@ -47,6 +47,7 @@
 #include <common/consumer.h>
 #include <common/consumer-timer.h>
 #include <common/compat/poll.h>
+#include <common/compat/getenv.h>
 #include <common/sessiond-comm/sessiond-comm.h>
 #include <common/utils.h>
 
@@ -223,16 +224,31 @@ static int parse_args(int argc, char **argv)
                        }
                        break;
                case 'c':
-                       snprintf(command_sock_path, PATH_MAX, "%s", optarg);
+                       if (lttng_is_setuid_setgid()) {
+                               WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                                       "-c, --consumerd-cmd-sock");
+                       } else {
+                               snprintf(command_sock_path, PATH_MAX, "%s", optarg);
+                       }
                        break;
                case 'e':
-                       snprintf(error_sock_path, PATH_MAX, "%s", optarg);
+                       if (lttng_is_setuid_setgid()) {
+                               WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                                       "-e, --consumerd-err-sock");
+                       } else {
+                               snprintf(error_sock_path, PATH_MAX, "%s", optarg);
+                       }
                        break;
                case 'd':
                        opt_daemon = 1;
                        break;
                case 'g':
-                       tracing_group_name = optarg;
+                       if (lttng_is_setuid_setgid()) {
+                               WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+                                       "-g, --group");
+                       } else {
+                               tracing_group_name = optarg;
+                       }
                        break;
                case 'h':
                        usage(stdout);
index 75149ba4b46526a0494bfea623b3115c676064d4..e3e48c9195a6bdd2a411c8e31aa1a2f198d19afe 100644 (file)
@@ -49,6 +49,7 @@
 #include <common/compat/poll.h>
 #include <common/sessiond-comm/sessiond-comm.h>
 #include <common/utils.h>
+#include <common/compat/getenv.h>
 
 #include "lttng-relayd.h"
 #include "health-relayd.h"
@@ -136,7 +137,7 @@ int parse_health_env(void)
 {
        const char *health_path;
 
-       health_path = getenv(LTTNG_RELAYD_HEALTH_ENV);
+       health_path = lttng_secure_getenv(LTTNG_RELAYD_HEALTH_ENV);
        if (health_path) {
                strncpy(health_unix_sock_path, health_path,
                        PATH_MAX);
index fb290bacc1a4345e12850d475fa10c720115f77f..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);
+                       }
                }
        }
 
index e084aba61437961fe0f2d505bef57ed0f991c283..e68aa79d4c053ecd5aa598a7f10d7cee4ac383e4 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <common/common.h>
 #include <common/compat/socket.h>
+#include <common/compat/getenv.h>
 #include <common/defaults.h>
 #include <common/kernel-consumer/kernel-consumer.h>
 #include <common/futex.h>
@@ -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;
        }
@@ -2440,7 +2441,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 = "";
                                }
@@ -2483,7 +2484,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 = "";
                                }
@@ -4385,10 +4386,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;
@@ -4397,20 +4408,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();
@@ -4422,22 +4438,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;
@@ -4466,97 +4512,142 @@ 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;
+                       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':
@@ -4672,9 +4763,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);
+                       }
                }
        }
 
index 154f6df6b5e31e16d54e275e183290dd61775b33..8e5bb0fd468cd52b670f8dfef3b62250b7ec5aed 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <lttng/lttng.h>
 #include <common/error.h>
+#include <common/compat/getenv.h>
 
 #include "command.h"
 
@@ -445,6 +446,11 @@ static int parse_args(int argc, char **argv)
        int opt, ret;
        char *user;
 
+       if (lttng_is_setuid_setgid()) {
+               ERR("'%s' is not allowed to be executed as a setuid/setgid binary for security reasons. Aborting.", argv[0]);
+               clean_exit(EXIT_FAILURE);
+       }
+
        if (argc < 2) {
                usage(stderr);
                clean_exit(EXIT_FAILURE);
index 537375b91f5ed6244f0013b499e0e3586b52de32..5df27dfa3f4dd3a9628cfe15a2a950a55a5af0ef 100644 (file)
@@ -9,4 +9,5 @@ COMPAT=compat-poll.c
 endif
 
 libcompat_la_SOURCES = poll.h fcntl.h endian.h mman.h clone.h \
-                       socket.h compat-fcntl.c uuid.h tid.h $(COMPAT)
+               socket.h compat-fcntl.c uuid.h tid.h \
+               getenv.h $(COMPAT)
diff --git a/src/common/compat/getenv.h b/src/common/compat/getenv.h
new file mode 100644 (file)
index 0000000..23a6dfe
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef _COMPAT_GETENV_H
+#define _COMPAT_GETENV_H
+
+/*
+ * Copyright (C) 2015 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <common/error.h>
+
+static inline
+int lttng_is_setuid_setgid(void)
+{
+       return geteuid() != getuid() || getegid() != getgid();
+}
+
+static inline
+char *lttng_secure_getenv(const char *name)
+{
+       if (lttng_is_setuid_setgid()) {
+               WARN("Getting environment variable '%s' from setuid/setgid binary refused for security reasons.",
+                       name);
+               return NULL;
+       }
+       return getenv(name);
+}
+
+#endif /* _COMPAT_GETENV_H */
index 86b1be8b5c41c218cc2f6252188410e2ce2a741e..ece7cdb2a0e161339f661cfa1bd8b6cb37fc7138 100644 (file)
@@ -32,6 +32,7 @@
 #include <common/error.h>
 #include <common/macros.h>
 #include <common/utils.h>
+#include <common/compat/getenv.h>
 #include <lttng/lttng-error.h>
 #include <libxml/parser.h>
 #include <libxml/valid.h>
@@ -595,7 +596,7 @@ static
 char *get_session_config_xsd_path()
 {
        char *xsd_path;
-       const char *base_path = getenv(DEFAULT_SESSION_CONFIG_XSD_PATH_ENV);
+       const char *base_path = lttng_secure_getenv(DEFAULT_SESSION_CONFIG_XSD_PATH_ENV);
        size_t base_path_len;
        size_t max_path_len;
 
index c146f652dfa324ef86c19ca2362c8f7c04ffe25c..471bb22046c3d3bf9f44dbf24c176f089a3e3c2e 100644 (file)
@@ -35,6 +35,7 @@
 #include <common/utils.h>
 #include <common/compat/mman.h>
 #include <common/compat/clone.h>
+#include <common/compat/getenv.h>
 
 #include "runas.h"
 
@@ -88,7 +89,7 @@ int use_clone(void)
 static
 int use_clone(void)
 {
-       return !getenv("LTTNG_DEBUG_NOCLONE");
+       return !lttng_secure_getenv("LTTNG_DEBUG_NOCLONE");
 }
 #endif
 
index 7f91dcb8151ea6ae6083668e78df123f73521758..9a53330004931408df017fb4b2ebbd87ad31a61e 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <common/common.h>
 #include <common/runas.h>
+#include <common/compat/getenv.h>
 
 #include "utils.h"
 #include "defaults.h"
@@ -885,11 +886,11 @@ char *utils_get_home_dir(void)
        char *val = NULL;
        struct passwd *pwd;
 
-       val = getenv(DEFAULT_LTTNG_HOME_ENV_VAR);
+       val = lttng_secure_getenv(DEFAULT_LTTNG_HOME_ENV_VAR);
        if (val != NULL) {
                goto end;
        }
-       val = getenv(DEFAULT_LTTNG_FALLBACK_HOME_ENV_VAR);
+       val = lttng_secure_getenv(DEFAULT_LTTNG_FALLBACK_HOME_ENV_VAR);
        if (val != NULL) {
                goto end;
        }
@@ -954,7 +955,7 @@ end:
 LTTNG_HIDDEN
 char *utils_get_kmod_probes_list(void)
 {
-       return getenv(DEFAULT_LTTNG_KMOD_PROBES);
+       return lttng_secure_getenv(DEFAULT_LTTNG_KMOD_PROBES);
 }
 
 /*
@@ -964,7 +965,7 @@ char *utils_get_kmod_probes_list(void)
 LTTNG_HIDDEN
 char *utils_get_extra_kmod_probes_list(void)
 {
-       return getenv(DEFAULT_LTTNG_EXTRA_KMOD_PROBES);
+       return lttng_secure_getenv(DEFAULT_LTTNG_EXTRA_KMOD_PROBES);
 }
 
 /*
This page took 0.037787 seconds and 4 git commands to generate.