Fix: Only save kernel enablers in session configuration
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 8 Mar 2016 17:08:12 +0000 (12:08 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 8 Mar 2016 17:08:12 +0000 (12:08 -0500)
The session configuration serialization currently saves the
kernel enablers along with all enabled syscalls. In the case
where a syscall would be enabled with a given filter, this would
result in two events being enabled:

1) the syscall with its filter expression (the enabler)
2) the syscall on its own (an enabled syscall)

The observable effect of this is that the syscall ends up being
traced regardless of the filter's evaluation.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-sessiond/save.c
src/bin/lttng-sessiond/syscall.c
src/bin/lttng-sessiond/syscall.h

index b33287855e373ef0b9f253d02eb78294ccaab3e7..1a98515fa0c73f0272c82b346aa102ff5f5117f8 100644 (file)
@@ -502,57 +502,6 @@ end:
        return ret;
 }
 
-static
-int save_kernel_syscall(struct config_writer *writer,
-               struct ltt_kernel_channel *kchan)
-{
-       int ret, i;
-       ssize_t count;
-       struct lttng_event *events = NULL;
-
-       assert(writer);
-       assert(kchan);
-
-       count = syscall_list_channel(kchan, &events, 0);
-       if (!count) {
-               /* No syscalls, just gracefully return. */
-               ret = 0;
-               goto end;
-       }
-
-       for (i = 0; i < count; i++) {
-               struct ltt_kernel_event *kevent;
-
-               /* Create a temporary kevent in order to save it. */
-               /*
-                * TODO: struct lttng_event does not really work for a filter,
-                * but unfortunately, it is exposed as external API (and used as
-                * internal representation. Using NULL meanwhile.
-                */
-               kevent = trace_kernel_create_event(&events[i],
-                       NULL, NULL);
-               if (!kevent) {
-                       ret = -ENOMEM;
-                       goto end;
-               }
-               /* Init list in order so the destroy call can del the node. */
-               CDS_INIT_LIST_HEAD(&kevent->list);
-
-               ret = save_kernel_event(writer, kevent);
-               trace_kernel_destroy_event(kevent);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       /* Everything went well */
-       ret = 0;
-
-end:
-       free(events);
-       return ret;
-}
-
 static
 int save_kernel_events(struct config_writer *writer,
        struct ltt_kernel_channel *kchan)
@@ -573,12 +522,6 @@ int save_kernel_events(struct config_writer *writer,
                }
        }
 
-       /* Save syscalls if any. */
-       ret = save_kernel_syscall(writer, kchan);
-       if (ret) {
-               goto end;
-       }
-
        /* /events */
        ret = config_writer_close_element(writer);
        if (ret) {
index 4c491995a1295c648d459d1f5a1b42aabab86123..7ae6682bb419c06c6cdd8231c5c92d0dbef475c4 100644 (file)
@@ -333,113 +333,3 @@ error:
        rcu_read_unlock();
        return ret;
 }
-
-/*
- * Add enabled syscall to the events list using the given kernel channel.
- *
- * Return the number of entry of the events array that is different from size
- * if the array grows. On error, return negative value and events is untouched.
- */
-ssize_t syscall_list_channel(struct ltt_kernel_channel *kchan,
-               struct lttng_event **_events, size_t size)
-{
-       int err, i;
-       size_t new_size;
-       ssize_t ret, count;
-       char *mask = NULL;
-       uint32_t len;
-       struct lttng_event *events = NULL;
-       /* Hash table used to filter duplicate out. */
-       struct lttng_ht *syscalls_ht = NULL;
-
-       assert(kchan);
-
-       /* Get syscall mask from the kernel tracer. */
-       err = kernel_syscall_mask(kchan->fd, &mask, &len);
-       if (err < 0) {
-               ret = err;
-               goto error;
-       }
-
-       ret = init_syscall_ht(&syscalls_ht);
-       if (ret < 0) {
-               goto error;
-       }
-
-       count = new_size = size;
-       events = *_events;
-
-       for (i = 0; i < len; i++) {
-               unsigned char val;
-               struct syscall *ksyscall;
-
-               bitfield_read_be(mask, unsigned char, i, 1, &val);
-               if (!val) {
-                       /* Syscall is disabled, continue the loop. */
-                       continue;
-               }
-
-               /* Skip empty syscall. */
-               if (*syscall_table[i].name == '\0') {
-                       continue;
-               }
-
-               /* Syscall is enabled thus add it to the events list. */
-
-               if (count >= new_size) {
-                       struct lttng_event *new_events;
-
-                       /* Get the maximum here since count can be 0. */
-                       new_size = max(count << 1, 1);
-                       DBG3("Listing syscall realloc events array from %zu to %zu", count,
-                                       new_size);
-                       new_events = realloc(events, new_size * sizeof(*new_events));
-                       if (!new_events) {
-                               PERROR("realloc kernel events list");
-                               ret = -ENOMEM;
-                               goto error;
-                       }
-                       memset(new_events + count, 0,
-                                       (new_size - count) * sizeof(*new_events));
-                       events = new_events;
-               }
-
-               rcu_read_lock();
-               ksyscall = lookup_syscall(syscalls_ht, syscall_table[i].name);
-               if (ksyscall) {
-                       update_event_syscall_bitness(events, i, ksyscall->index);
-                       rcu_read_unlock();
-                       continue;
-               }
-               ksyscall = NULL;
-               rcu_read_unlock();
-
-               ret = add_syscall_to_ht(syscalls_ht, i, count);
-               if (ret < 0) {
-                       goto error;
-               }
-
-               update_event_syscall_bitness(events, i, count);
-               strncpy(events[count].name, syscall_table[i].name,
-                               sizeof(events[count].name));
-               events[count].enabled = 1;
-               events[count].type = LTTNG_EVENT_SYSCALL;
-               count++;
-       }
-
-       rcu_read_lock();
-       destroy_syscall_ht(syscalls_ht);
-       rcu_read_unlock();
-
-       *_events = events;
-
-       return count;
-
-error:
-       rcu_read_lock();
-       destroy_syscall_ht(syscalls_ht);
-       rcu_read_unlock();
-
-       free(events);
-       return ret;
-}
index 97fb66960d11bc87e31ac6821f397102526b9fa5..5f065cdbe3fe8cdff24bc8068c311a7cc86946e9 100644 (file)
@@ -53,7 +53,5 @@ extern struct syscall *syscall_table;
 /* Use to list kernel system calls. */
 int syscall_init_table(void);
 ssize_t syscall_table_list(struct lttng_event **events);
-ssize_t syscall_list_channel(struct ltt_kernel_channel *kchan,
-               struct lttng_event **_events, size_t size);
 
 #endif /* SYSCALL_H */
This page took 0.030544 seconds and 5 git commands to generate.