Fix: validate file path creds in autoload mode
authorDavid Goulet <dgoulet@efficios.com>
Wed, 16 Jul 2014 19:50:31 +0000 (15:50 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Wed, 16 Jul 2014 19:50:31 +0000 (15:50 -0400)
Validate the credentials only when in auto load mode for the auto/
directory. The lttng load command now checks the session file creds and
validate if it's readable before trying to do so.

Thus with this, a user can load a session from the system wide directory
as long as she/he has the rights to read it.

Signed-off-by: David Goulet <dgoulet@efficios.com>
doc/man/lttng-sessiond.8
doc/man/lttng.1
src/common/config/config.c

index bc03fb0b3e16dbac9fc62d0654e4b49d07970719..782a9bb18f65ba20707158caf1dbca2aaaaa518b 100644 (file)
@@ -130,7 +130,7 @@ Specify path from which to automatically load session configuration(s).
 .PP
 By default, the session daemon tries to load session configuration(s) located
 in the user default directory \fB~/.lttng/sessions/auto/\fP and in the system
-wide one in \fB/etc/lttng/sessions/auto\fP. Note that the directory containing
+wide one in \fB/etc/lttng/sessions/auto/\fP. Note that the directory containing
 the session's configuration and lttng-sessiond MUST have the same UID for them
 to be automatically loaded.
 
index cd0aae29466ebfe76b0e04317e544a462a338f0d..12ca33d6fbcdecc7faa2019c435acae6ea1fe91e 100644 (file)
@@ -750,7 +750,9 @@ Load tracing session configuration
 
 If NAME is omitted, all session configurations found in both the user's session
 configuration directory (default: ~/.lttng/sessions/) and the system session
-configuration directory (default: /etc/lttng/sessions/) will be loaded.
+configuration directory (default: /etc/lttng/sessions/) will be loaded. Note
+that the sessions in the user directory are loaded first and then the system
+wide directory are loaded.
 
 .B OPTIONS:
 
@@ -781,6 +783,9 @@ If SESSION is omitted, all session configurations will be saved to individual
 ~/.lttng/sessions/). The default session configuration file naming scheme is
 \fBSESSION.lttng\fP.
 
+For instance, a user in the tracing group saving a session from a root session
+daemon will save it in her/his user directory.
+
 .B OPTIONS:
 
 .TP
index 8c926b53ed74ea90151d19bb8097c73cfda26b67..bfb2576f4d5bab954b37958d7c1d672bcbfd7c13 100644 (file)
@@ -2338,6 +2338,31 @@ error:
        return ret;
 }
 
+/*
+ * Return 1 if the given path is readable by the current UID or 0 if not.
+ * Return -1 if the path is EPERM.
+ */
+static int validate_file_read_creds(const char *path)
+{
+       int ret;
+
+       assert(path);
+
+       /* Can we read the file. */
+       ret = access(path, R_OK);
+       if (!ret) {
+               goto valid;
+       }
+       if (errno == EACCES) {
+               return -1;
+       } else {
+               /* Invalid. */
+               return 0;
+       }
+valid:
+       return 1;
+}
+
 static
 int load_session_from_file(const char *path, const char *session_name,
        struct session_config_validation_ctx *validation_ctx, int override)
@@ -2346,14 +2371,17 @@ int load_session_from_file(const char *path, const char *session_name,
        xmlDocPtr doc = NULL;
        xmlNodePtr sessions_node;
        xmlNodePtr session_node;
-       struct stat sb;
 
        assert(path);
        assert(validation_ctx);
 
-       ret = stat(path, &sb);
-       if (ret) {
-               ret = -LTTNG_ERR_LOAD_SESSION_NOENT;
+       ret = validate_file_read_creds(path);
+       if (ret != 1) {
+               if (ret == -1) {
+                       ret = -LTTNG_ERR_EPERM;
+               } else {
+                       ret = -LTTNG_ERR_LOAD_SESSION_NOENT;
+               }
                goto end;
        }
 
@@ -2506,7 +2534,7 @@ end:
 
 /*
  * Validate that the given path's credentials and the current process have the
- * same UID. If so, return 0 else return 1 if it does NOT match.
+ * same UID. If so, return 1 else return 0 if it does NOT match.
  */
 static int validate_path_creds(const char *path)
 {
@@ -2515,7 +2543,7 @@ static int validate_path_creds(const char *path)
 
        assert(path);
 
-       if (uid != 0) {
+       if (uid == 0) {
                goto valid;
        }
 
@@ -2533,9 +2561,9 @@ static int validate_path_creds(const char *path)
        }
 
 valid:
-       return 0;
-invalid:
        return 1;
+invalid:
+       return 0;
 }
 
 LTTNG_HIDDEN
@@ -2543,6 +2571,7 @@ int config_load_session(const char *path, const char *session_name,
                int override, unsigned int autoload)
 {
        int ret;
+       const char *path_ptr = NULL;
        struct session_config_validation_ctx validation_ctx = { 0 };
 
        ret = init_session_config_validation_ctx(&validation_ctx);
@@ -2567,18 +2596,31 @@ int config_load_session(const char *path, const char *session_name,
                                ret = snprintf(path, sizeof(path),
                                                DEFAULT_SESSION_HOME_CONFIGPATH "/"
                                                DEFAULT_SESSION_CONFIG_AUTOLOAD, home_path);
+                               if (ret < 0) {
+                                       PERROR("snprintf session autoload home config path");
+                                       goto end;
+                               }
+
+                               /*
+                                * Credentials are only validated for the autoload in order to
+                                * avoid any user session daemon to try to load kernel sessions
+                                * automatically and failing all the times.
+                                */
+                               ret = validate_path_creds(path);
+                               if (ret) {
+                                       path_ptr = path;
+                               }
                        } else {
                                ret = snprintf(path, sizeof(path),
                                                DEFAULT_SESSION_HOME_CONFIGPATH, home_path);
+                               if (ret < 0) {
+                                       PERROR("snprintf session home config path");
+                                       goto end;
+                               }
+                               path_ptr = path;
                        }
-                       if (ret < 0) {
-                               PERROR("snprintf session home config path");
-                               goto end;
-                       }
-
-                       ret = validate_path_creds(path);
-                       if (!ret && autoload) {
-                               ret = load_session_from_path(path, session_name,
+                       if (path_ptr) {
+                               ret = load_session_from_path(path_ptr, session_name,
                                                &validation_ctx, override);
                                if (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT) {
                                        goto end;
@@ -2590,19 +2632,25 @@ int config_load_session(const char *path, const char *session_name,
                        }
                }
 
+               /* Reset path pointer for the system wide dir. */
+               path_ptr = NULL;
+
                /* Try system wide configuration directory. */
                if (autoload) {
                        sys_path = DEFAULT_SESSION_SYSTEM_CONFIGPATH "/"
                                DEFAULT_SESSION_CONFIG_AUTOLOAD;
+                       ret = validate_path_creds(sys_path);
+                       if (ret) {
+                               path_ptr = sys_path;
+                       }
                } else {
-                       sys_path = DEFAULT_SESSION_HOME_CONFIGPATH;
+                       sys_path = DEFAULT_SESSION_SYSTEM_CONFIGPATH;
+                       path_ptr = sys_path;
                }
 
-               ret = validate_path_creds(sys_path);
-               if (!ret && autoload) {
-                       ret = load_session_from_path(sys_path, session_name,
+               if (path_ptr) {
+                       ret = load_session_from_path(path_ptr, session_name,
                                        &validation_ctx, override);
-                       goto end;
                }
        } else {
                ret = access(path, F_OK);
This page took 0.041465 seconds and 4 git commands to generate.