X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsyscall.c;h=7ae6682bb419c06c6cdd8231c5c92d0dbef475c4;hb=234cd6367843a2106a4cb10f8fb99443208516df;hp=95d30d07459dc98d12dfb2ca680f1773cdac7c52;hpb=834978fd9e2392f20867351ca99bf7bdf31b4f56;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/syscall.c b/src/bin/lttng-sessiond/syscall.c index 95d30d074..7ae6682bb 100644 --- a/src/bin/lttng-sessiond/syscall.c +++ b/src/bin/lttng-sessiond/syscall.c @@ -15,7 +15,7 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE +#define _LGPL_SOURCE #include #include #include @@ -35,7 +35,7 @@ static size_t syscall_table_nb_entry; * Populate the system call table using the kernel tracer. * * Return 0 on success and the syscall table is allocated. On error, a negative - * value is returned and the syscall table is set to NULL. + * value is returned. */ int syscall_init_table(void) { @@ -72,7 +72,7 @@ int syscall_init_table(void) } while (fscanf(fp, - "syscall { index = %lu; \ + "syscall { index = %zu; \ name = %" XSTR(SYSCALL_NAME_LEN) "[^;]; \ bitness = %u; };\n", &index, name, &bitness) == 3) { @@ -81,7 +81,15 @@ int syscall_init_table(void) size_t new_nbmem; /* Double memory size. */ - new_nbmem = index << 1; + new_nbmem = max(index, nbmem << 1); + if (new_nbmem < nbmem) { + /* Overflow, stop everything, something went really wrong. */ + ERR("Syscall listing memory size overflow. Stopping"); + free(syscall_table); + syscall_table = NULL; + ret = -EINVAL; + goto error; + } DBG("Reallocating syscall table from %zu to %zu entries", nbmem, new_nbmem); @@ -325,102 +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; - } - - ksyscall = lookup_syscall(syscalls_ht, syscall_table[i].name); - if (ksyscall) { - update_event_syscall_bitness(events, i, ksyscall->index); - continue; - } - - 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_KERNEL_SYSCALL; - count++; - } - - *_events = events; - - return count; - -error: - destroy_syscall_ht(syscalls_ht); - free(events); - return ret; -}