[lttng-dev] [PATCH lttng-tools] Fix: setuid/setgid daemons should not get sensitive env. var./args

Jérémie Galarneau jeremie.galarneau at efficios.com
Thu Jan 22 15:01:51 EST 2015


Merged, thanks!

Jérémie

On Fri, Jan 16, 2015 at 12:48 PM, Mathieu Desnoyers
<mathieu.desnoyers at efficios.com> wrote:
> Also, don't allow lttng command line interface to run as setuid/setgid
> binary.
>
> Fixes #780
>
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> ---
>  src/bin/lttng-consumerd/lttng-consumerd.c |  22 ++-
>  src/bin/lttng-relayd/health-relayd.c      |   3 +-
>  src/bin/lttng-relayd/main.c               | 101 +++++++----
>  src/bin/lttng-sessiond/main.c             | 284 ++++++++++++++++++++----------
>  src/bin/lttng/lttng.c                     |   6 +
>  src/common/compat/Makefile.am             |   3 +-
>  src/common/compat/getenv.h                |  43 +++++
>  src/common/config/config.c                |   3 +-
>  src/common/runas.c                        |   3 +-
>  src/common/utils.c                        |   9 +-
>  10 files changed, 337 insertions(+), 140 deletions(-)
>  create mode 100644 src/common/compat/getenv.h
>
> diff --git a/src/bin/lttng-consumerd/lttng-consumerd.c b/src/bin/lttng-consumerd/lttng-consumerd.c
> index 7122d06..626fbb7 100644
> --- a/src/bin/lttng-consumerd/lttng-consumerd.c
> +++ b/src/bin/lttng-consumerd/lttng-consumerd.c
> @@ -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);
> diff --git a/src/bin/lttng-relayd/health-relayd.c b/src/bin/lttng-relayd/health-relayd.c
> index 75149ba..e3e48c9 100644
> --- a/src/bin/lttng-relayd/health-relayd.c
> +++ b/src/bin/lttng-relayd/health-relayd.c
> @@ -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);
> diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c
> index fb290ba..c843aa5 100644
> --- a/src/bin/lttng-relayd/main.c
> +++ b/src/bin/lttng-relayd/main.c
> @@ -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);
> +                       }
>                 }
>         }
>
> diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c
> index e084aba..e68aa79 100644
> --- a/src/bin/lttng-sessiond/main.c
> +++ b/src/bin/lttng-sessiond/main.c
> @@ -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);
> +                       }
>                 }
>         }
>
> diff --git a/src/bin/lttng/lttng.c b/src/bin/lttng/lttng.c
> index 154f6df..8e5bb0f 100644
> --- a/src/bin/lttng/lttng.c
> +++ b/src/bin/lttng/lttng.c
> @@ -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);
> diff --git a/src/common/compat/Makefile.am b/src/common/compat/Makefile.am
> index 537375b..5df27df 100644
> --- a/src/common/compat/Makefile.am
> +++ b/src/common/compat/Makefile.am
> @@ -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
> index 0000000..23a6dfe
> --- /dev/null
> +++ b/src/common/compat/getenv.h
> @@ -0,0 +1,43 @@
> +#ifndef _COMPAT_GETENV_H
> +#define _COMPAT_GETENV_H
> +
> +/*
> + * Copyright (C) 2015 - Mathieu Desnoyers <mathieu.desnoyers at 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 */
> diff --git a/src/common/config/config.c b/src/common/config/config.c
> index 86b1be8..ece7cdb 100644
> --- a/src/common/config/config.c
> +++ b/src/common/config/config.c
> @@ -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;
>
> diff --git a/src/common/runas.c b/src/common/runas.c
> index c146f65..471bb22 100644
> --- a/src/common/runas.c
> +++ b/src/common/runas.c
> @@ -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
>
> diff --git a/src/common/utils.c b/src/common/utils.c
> index 7f91dcb..9a53330 100644
> --- a/src/common/utils.c
> +++ b/src/common/utils.c
> @@ -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);
>  }
>
>  /*
> --
> 2.1.1
>



-- 
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com



More information about the lttng-dev mailing list