Fix: Memory allocated by xmlNodeGetContent() must be freed by xmlFree()
[lttng-tools.git] / src / common / config / config.c
index 8c926b53ed74ea90151d19bb8097c73cfda26b67..b2a0912b8f5531d75c530875e5593812335803b8 100644 (file)
@@ -1632,6 +1632,24 @@ int process_event_node(xmlNodePtr event_node, struct lttng_handle *handle,
 
        ret = lttng_enable_event_with_exclusions(handle, &event, channel_name,
                        filter_expression, exclusion_count, exclusions);
+       if (ret) {
+               goto end;
+       }
+
+       if (!event.enabled) {
+               /*
+                * Note that we should use lttng_disable_event_ext() (2.6+) to
+                * eliminate the risk of clashing on events of the same
+                * name (with different event types and loglevels).
+                *
+                * Unfortunately, lttng_disable_event_ext() only performs a
+                * match on the name and event type and errors out if any other
+                * event attribute is not set to its default value.
+                *
+                * This will disable all events that match this name.
+                */
+               ret = lttng_disable_event(handle, event.name, channel_name);
+       }
 end:
        for (i = 0; i < exclusion_count; i++) {
                free(exclusions[i]);
@@ -2140,7 +2158,7 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
 {
        int ret, started = -1, snapshot_mode = -1;
        uint64_t live_timer_interval = UINT64_MAX;
-       char *name = NULL;
+       xmlChar *name = NULL;
        xmlNodePtr domains_node = NULL;
        xmlNodePtr output_node = NULL;
        xmlNodePtr node;
@@ -2159,7 +2177,7 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
                                goto error;
                        }
 
-                       name = (char *) node_content;
+                       name = node_content;
                } else if (!domains_node && !strcmp((const char *) node->name,
                        config_element_domains)) {
                        /* domains */
@@ -2229,7 +2247,7 @@ int process_session_node(xmlNodePtr session_node, const char *session_name,
                goto error;
        }
 
-       if (session_name && strcmp(name, session_name)) {
+       if (session_name && strcmp((char *) name, session_name)) {
                /* This is not the session we are looking for */
                ret = -LTTNG_ERR_NO_SESSION;
                goto error;
@@ -2286,7 +2304,7 @@ domain_init_error:
 
        if (override) {
                /* Destroy session if it exists */
-               ret = lttng_destroy_session(name);
+               ret = lttng_destroy_session((const char *) name);
                if (ret && ret != -LTTNG_ERR_SESS_NOT_FOUND) {
                        ERR("Failed to destroy existing session.");
                        goto error;
@@ -2295,15 +2313,17 @@ domain_init_error:
 
        /* Create session type depending on output type */
        if (snapshot_mode && snapshot_mode != -1) {
-               ret = create_snapshot_session(name, output_node);
+               ret = create_snapshot_session((const char *) name, output_node);
        } else if (live_timer_interval &&
                live_timer_interval != UINT64_MAX) {
-               ret = create_session(name, kernel_domain, ust_domain, jul_domain,
-                               output_node, live_timer_interval);
+               ret = create_session((const char *) name, kernel_domain,
+                               ust_domain, jul_domain, output_node,
+                               live_timer_interval);
        } else {
                /* regular session */
-               ret = create_session(name, kernel_domain, ust_domain, jul_domain,
-                               output_node, UINT64_MAX);
+               ret = create_session((const char *) name, kernel_domain,
+                               ust_domain, jul_domain, output_node,
+                               UINT64_MAX);
        }
        if (ret) {
                goto error;
@@ -2311,14 +2331,14 @@ domain_init_error:
 
        for (node = xmlFirstElementChild(domains_node); node;
                node = xmlNextElementSibling(node)) {
-               ret = process_domain_node(node, name);
+               ret = process_domain_node(node, (const char *) name);
                if (ret) {
                        goto end;
                }
        }
 
        if (started) {
-               ret = lttng_start_tracing(name);
+               ret = lttng_start_tracing((const char *) name);
                if (ret) {
                        goto end;
                }
@@ -2326,18 +2346,44 @@ domain_init_error:
 
 end:
        if (ret < 0) {
-               ERR("Failed to load session %s: %s", name, lttng_strerror(ret));
-               lttng_destroy_session(name);
+               ERR("Failed to load session %s: %s", (const char *) name,
+                       lttng_strerror(ret));
+               lttng_destroy_session((const char *) name);
        }
 
 error:
        free(kernel_domain);
        free(ust_domain);
        free(jul_domain);
-       free(name);
+       xmlFree(name);
        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 +2392,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 +2555,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 +2564,7 @@ static int validate_path_creds(const char *path)
 
        assert(path);
 
-       if (uid != 0) {
+       if (uid == 0) {
                goto valid;
        }
 
@@ -2533,9 +2582,9 @@ static int validate_path_creds(const char *path)
        }
 
 valid:
-       return 0;
-invalid:
        return 1;
+invalid:
+       return 0;
 }
 
 LTTNG_HIDDEN
@@ -2543,6 +2592,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 +2617,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 +2653,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.02799 seconds and 4 git commands to generate.