Fix: Don't spam session daemon logs on invalid UST context
[lttng-tools.git] / src / bin / lttng-sessiond / trace-ust.c
index 9ec6e43b0baa8bae6c8d4602cd94743148787977..4d39e213326b6ce903e459b6bb243d807051696a 100644 (file)
@@ -15,7 +15,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#define _GNU_SOURCE
 #define _LGPL_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
@@ -71,12 +70,15 @@ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key)
 {
        struct ltt_ust_event *event;
        const struct ltt_ust_ht_key *key;
+       int ev_loglevel_value;
+       int ll_match;
 
        assert(node);
        assert(_key);
 
        event = caa_container_of(node, struct ltt_ust_event, node.node);
        key = _key;
+       ev_loglevel_value = event->attr.loglevel;
 
        /* Match the 4 elements of the key: name, filter, loglevel, exclusions. */
 
@@ -85,19 +87,13 @@ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key)
                goto no_match;
        }
 
-       /* Event loglevel. */
-       if (event->attr.loglevel != key->loglevel) {
-               if (event->attr.loglevel_type == LTTNG_UST_LOGLEVEL_ALL
-                               && key->loglevel == 0 && event->attr.loglevel == -1) {
-                       /*
-                        * Match is accepted. This is because on event creation, the
-                        * loglevel is set to -1 if the event loglevel type is ALL so 0 and
-                        * -1 are accepted for this loglevel type since 0 is the one set by
-                        * the API when receiving an enable event.
-                        */
-               } else {
-                       goto no_match;
-               }
+       /* Event loglevel value and type. */
+       ll_match = loglevels_match(event->attr.loglevel_type,
+               ev_loglevel_value, key->loglevel_type,
+               key->loglevel_value, LTTNG_UST_LOGLEVEL_ALL);
+
+       if (!ll_match) {
+               goto no_match;
        }
 
        /* Only one of the filters is NULL, fail. */
@@ -120,12 +116,46 @@ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key)
        }
 
        if (key->exclusion && event->exclusion) {
-               /* Both exclusions exist; check count followed by names. */
-               if (event->exclusion->count != key->exclusion->count ||
-                               memcmp(event->exclusion->names, key->exclusion->names,
-                                       event->exclusion->count * LTTNG_SYMBOL_NAME_LEN) != 0) {
+               size_t i;
+
+               /* Check exclusion counts first. */
+               if (event->exclusion->count != key->exclusion->count) {
                        goto no_match;
                }
+
+               /* Compare names individually. */
+               for (i = 0; i < event->exclusion->count; ++i) {
+                       size_t j;
+                       bool found = false;
+                       const char *name_ev =
+                               LTTNG_EVENT_EXCLUSION_NAME_AT(
+                                       event->exclusion, i);
+
+                       /*
+                        * Compare this exclusion name to all the key's
+                        * exclusion names.
+                        */
+                       for (j = 0; j < key->exclusion->count; ++j) {
+                               const char *name_key =
+                                       LTTNG_EVENT_EXCLUSION_NAME_AT(
+                                               key->exclusion, j);
+
+                               if (!strncmp(name_ev, name_key,
+                                               LTTNG_SYMBOL_NAME_LEN)) {
+                                       /* Names match! */
+                                       found = true;
+                                       break;
+                               }
+                       }
+
+                       /*
+                        * If the current exclusion name was not found amongst
+                        * the key's exclusion names, then there's no match.
+                        */
+                       if (!found) {
+                               goto no_match;
+                       }
+               }
        }
        /* Match. */
        return 1;
@@ -171,7 +201,8 @@ error:
  * MUST be acquired before calling this.
  */
 struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht,
-               char *name, struct lttng_filter_bytecode *filter, int loglevel,
+               char *name, struct lttng_filter_bytecode *filter,
+               enum lttng_ust_loglevel_type loglevel_type, int loglevel_value,
                struct lttng_event_exclusion *exclusion)
 {
        struct lttng_ht_node_str *node;
@@ -183,7 +214,8 @@ struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht,
 
        key.name = name;
        key.filter = filter;
-       key.loglevel = loglevel;
+       key.loglevel_type = loglevel_type;
+       key.loglevel_value = loglevel_value;
        key.exclusion = exclusion;
 
        cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
@@ -361,6 +393,39 @@ error:
        return luc;
 }
 
+/*
+ * Validates an exclusion list.
+ *
+ * Returns 0 if valid, negative value if invalid.
+ */
+static int validate_exclusion(struct lttng_event_exclusion *exclusion)
+{
+       size_t i;
+       int ret = 0;
+
+       assert(exclusion);
+
+       for (i = 0; i < exclusion->count; ++i) {
+               size_t j;
+               const char *name_a =
+                       LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, i);
+
+               for (j = 0; j < i; ++j) {
+                       const char *name_b =
+                               LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, j);
+
+                       if (!strncmp(name_a, name_b, LTTNG_SYMBOL_NAME_LEN)) {
+                               /* Match! */
+                               ret = -1;
+                               goto end;
+                       }
+               }
+       }
+
+end:
+       return ret;
+}
+
 /*
  * Allocate and initialize a ust event. Set name and event type.
  * We own filter_expression, filter, and exclusion.
@@ -377,6 +442,10 @@ struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev,
 
        assert(ev);
 
+       if (exclusion && validate_exclusion(exclusion)) {
+               goto error;
+       }
+
        lue = zmalloc(sizeof(struct ltt_ust_event));
        if (lue == NULL) {
                PERROR("ust event zmalloc");
@@ -478,7 +547,6 @@ int trace_ust_context_type_event_to_ust(enum lttng_event_context_type type)
                }
                break;
        default:
-               ERR("Invalid UST context");
                utype = -1;
                break;
        }
@@ -538,6 +606,7 @@ struct ltt_ust_context *trace_ust_create_context(
 
        utype = trace_ust_context_type_event_to_ust(ctx->ctx);
        if (utype < 0) {
+               ERR("Invalid UST context");
                return NULL;
        }
 
This page took 0.025074 seconds and 4 git commands to generate.