X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=lttng-syscalls.c;h=96d90c58c586a2affa6d46ed17c993c69bcb98cb;hb=12e579dbcb23fab949879ed03a1757d22bd8a6b2;hp=05b369dad182fa8f8023bafe4e6eb74a29f682de;hpb=3bc29f0a41b3c803245b845db2e1909042e72e9c;p=lttng-modules.git diff --git a/lttng-syscalls.c b/lttng-syscalls.c index 05b369da..96d90c58 100644 --- a/lttng-syscalls.c +++ b/lttng-syscalls.c @@ -27,9 +27,11 @@ #include #include #include +#include #include #include +#include "lib/bitfield.h" #include "wrapper/tracepoint.h" #include "lttng-events.h" @@ -101,17 +103,17 @@ struct mmap_arg_struct; /* Hijack probe callback for system call enter */ #undef TP_PROBE_CB #define TP_PROBE_CB(_template) &syscall_entry_probe -#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT(syscall_enter_##_name, PARAMS(_proto), PARAMS(_args), \ PARAMS(_struct), PARAMS(_assign), PARAMS(_printk)) -#define SC_LTTNG_TRACE_EVENT(_name, _proto, _args, _locvar, _code, _struct, _assign, _printk) \ - LTTNG_TRACEPOINT_EVENT_CODE(syscall_enter_##_name, PARAMS(_proto), PARAMS(_args),\ - PARAMS(_locvar), PARAMS(_code),\ +#define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code, _struct, _assign, _printk) \ + LTTNG_TRACEPOINT_EVENT_CODE(syscall_enter_##_name, PARAMS(_proto), PARAMS(_args), \ + PARAMS(_locvar), PARAMS(_code), \ PARAMS(_struct), PARAMS(_assign), PARAMS(_printk)) -#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_enter_##_name, PARAMS(_struct), PARAMS(_assign), \ PARAMS(_printk)) -#define SC_DEFINE_EVENT_NOARGS(_template, _name) \ +#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \ LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_enter_##_template, syscall_enter_##_name) #undef TRACE_SYSTEM #define TRACE_SYSTEM syscall_enter_integers @@ -124,28 +126,28 @@ struct mmap_arg_struct; #include "instrumentation/syscalls/headers/syscalls_pointers.h" #undef TRACE_INCLUDE_FILE #undef TRACE_SYSTEM -#undef SC_LTTNG_TRACE_EVENT -#undef SC_TRACE_EVENT -#undef SC_DECLARE_EVENT_CLASS_NOARGS -#undef SC_DEFINE_EVENT_NOARGS +#undef SC_LTTNG_TRACEPOINT_EVENT_CODE +#undef SC_LTTNG_TRACEPOINT_EVENT +#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS +#undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS #undef TP_PROBE_CB #undef _TRACE_SYSCALLS_INTEGERS_H #undef _TRACE_SYSCALLS_POINTERS_H /* Hijack probe callback for compat system call enter */ #define TP_PROBE_CB(_template) &syscall_entry_probe -#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT(compat_syscall_enter_##_name, PARAMS(_proto), PARAMS(_args), \ - PARAMS(_struct), PARAMS(_assign), \ + PARAMS(_struct), PARAMS(_assign), \ PARAMS(_printk)) -#define SC_LTTNG_TRACE_EVENT(_name, _proto, _args, _locvar, _code, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_enter_##_name, PARAMS(_proto), PARAMS(_args), \ - PARAMS(_locvar), PARAMS(_code),\ + PARAMS(_locvar), PARAMS(_code), \ PARAMS(_struct), PARAMS(_assign), PARAMS(_printk)) -#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_enter_##_name, PARAMS(_struct), \ PARAMS(_assign), PARAMS(_printk)) -#define SC_DEFINE_EVENT_NOARGS(_template, _name) \ +#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \ LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_enter_##_template, \ compat_syscall_enter_##_name) #define TRACE_SYSTEM compat_syscall_enter_integers @@ -158,10 +160,10 @@ struct mmap_arg_struct; #include "instrumentation/syscalls/headers/compat_syscalls_pointers.h" #undef TRACE_INCLUDE_FILE #undef TRACE_SYSTEM -#undef SC_LTTNG_TRACE_EVENT -#undef SC_TRACE_EVENT -#undef SC_DECLARE_EVENT_CLASS_NOARGS -#undef SC_DEFINE_EVENT_NOARGS +#undef SC_LTTNG_TRACEPOINT_EVENT_CODE +#undef SC_LTTNG_TRACEPOINT_EVENT +#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS +#undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS #undef TP_PROBE_CB #undef _TRACE_SYSCALLS_INTEGERS_H #undef _TRACE_SYSCALLS_POINTERS_H @@ -181,18 +183,18 @@ struct mmap_arg_struct; /* Hijack probe callback for system call exit */ #define TP_PROBE_CB(_template) &syscall_exit_probe -#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \ PARAMS(_struct), PARAMS(_assign), PARAMS(_printk)) -#define SC_LTTNG_TRACE_EVENT(_name, _proto, _args, _locvar, _code, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT_CODE(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \ - PARAMS(_locvar), PARAMS(_code), \ + PARAMS(_locvar), PARAMS(_code), \ PARAMS(_struct), PARAMS(_assign), PARAMS(_printk)) -#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_exit_##_name, PARAMS(_struct), \ PARAMS(_assign), PARAMS(_printk)) -#define SC_DEFINE_EVENT_NOARGS(_template, _name) \ - LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template, \ +#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \ + LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template, \ syscall_exit_##_name) #define TRACE_SYSTEM syscall_exit_integers #define TRACE_INCLUDE_FILE syscalls_integers @@ -204,10 +206,10 @@ struct mmap_arg_struct; #include "instrumentation/syscalls/headers/syscalls_pointers.h" #undef TRACE_INCLUDE_FILE #undef TRACE_SYSTEM -#undef SC_LTTNG_TRACE_EVENT -#undef SC_TRACE_EVENT -#undef SC_DECLARE_EVENT_CLASS_NOARGS -#undef SC_DEFINE_EVENT_NOARGS +#undef SC_LTTNG_TRACEPOINT_EVENT_CODE +#undef SC_LTTNG_TRACEPOINT_EVENT +#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS +#undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS #undef TP_PROBE_CB #undef _TRACE_SYSCALLS_INTEGERS_H #undef _TRACE_SYSCALLS_POINTERS_H @@ -215,17 +217,17 @@ struct mmap_arg_struct; /* Hijack probe callback for compat system call exit */ #define TP_PROBE_CB(_template) &syscall_exit_probe -#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \ PARAMS(_struct), PARAMS(_assign), PARAMS(_printk)) -#define SC_LTTNG_TRACE_EVENT(_name, _proto, _args, _locvar, _code, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \ - PARAMS(_locvar), PARAMS(_code), \ + PARAMS(_locvar), PARAMS(_code), \ PARAMS(_struct), PARAMS(_assign), PARAMS(_printk)) -#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ +#define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_exit_##_name, PARAMS(_struct), \ PARAMS(_assign), PARAMS(_printk)) -#define SC_DEFINE_EVENT_NOARGS(_template, _name) \ +#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \ LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_exit_##_template, \ compat_syscall_exit_##_name) #define TRACE_SYSTEM compat_syscall_exit_integers @@ -238,10 +240,10 @@ struct mmap_arg_struct; #include "instrumentation/syscalls/headers/compat_syscalls_pointers.h" #undef TRACE_INCLUDE_FILE #undef TRACE_SYSTEM -#undef SC_LTTNG_TRACE_EVENT -#undef SC_TRACE_EVENT -#undef SC_DECLARE_EVENT_CLASS_NOARGS -#undef SC_DEFINE_EVENT_NOARGS +#undef SC_LTTNG_TRACEPOINT_EVENT_CODE +#undef SC_LTTNG_TRACEPOINT_EVENT +#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS +#undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS #undef TP_PROBE_CB #undef _TRACE_SYSCALLS_INTEGERS_H #undef _TRACE_SYSCALLS_POINTERS_H @@ -949,6 +951,12 @@ int get_compat_syscall_nr(const char *syscall_name) return syscall_nr; } +static +uint32_t get_sc_tables_len(void) +{ + return ARRAY_SIZE(sc_table) + ARRAY_SIZE(compat_sc_table); +} + int lttng_syscall_filter_enable(struct lttng_channel *chan, const char *name) { @@ -1033,6 +1041,12 @@ int lttng_syscall_filter_disable(struct lttng_channel *chan, filter = chan->sc_filter; } + if (!name) { + /* Disable all system calls */ + bitmap_clear(filter->sc, 0, NR_syscalls); + bitmap_clear(filter->sc_compat, 0, NR_compat_syscalls); + goto apply_filter; + } syscall_nr = get_syscall_nr(name); compat_syscall_nr = get_compat_syscall_nr(name); if (syscall_nr < 0 && compat_syscall_nr < 0) { @@ -1053,6 +1067,7 @@ int lttng_syscall_filter_disable(struct lttng_channel *chan, } bitmap_clear(chan->sc_filter->sc_compat, compat_syscall_nr, 1); } +apply_filter: if (!chan->sc_filter) rcu_assign_pointer(chan->sc_filter, filter); chan->syscall_all = 0; @@ -1063,3 +1078,142 @@ error: kfree(filter); return ret; } + +static +const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos) +{ + const struct trace_syscall_entry *entry; + int iter = 0; + + for (entry = sc_table; + entry < sc_table + ARRAY_SIZE(sc_table); + entry++) { + if (iter++ >= *pos) + return entry; + } + for (entry = compat_sc_table; + entry < compat_sc_table + ARRAY_SIZE(compat_sc_table); + entry++) { + if (iter++ >= *pos) + return entry; + } + /* End of list */ + return NULL; +} + +static +void *syscall_list_start(struct seq_file *m, loff_t *pos) +{ + return (void *) syscall_list_get_entry(pos); +} + +static +void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos) +{ + (*ppos)++; + return (void *) syscall_list_get_entry(ppos); +} + +static +void syscall_list_stop(struct seq_file *m, void *p) +{ +} + +static +int get_sc_table(const struct trace_syscall_entry *entry, + const struct trace_syscall_entry **table, + unsigned int *bitness) +{ + if (entry >= sc_table && entry < sc_table + ARRAY_SIZE(sc_table)) { + if (bitness) + *bitness = BITS_PER_LONG; + if (table) + *table = sc_table; + return 0; + } + if (!(entry >= compat_sc_table + && entry < compat_sc_table + ARRAY_SIZE(compat_sc_table))) { + return -EINVAL; + } + if (bitness) + *bitness = 32; + if (table) + *table = compat_sc_table; + return 0; +} + +static +int syscall_list_show(struct seq_file *m, void *p) +{ + const struct trace_syscall_entry *table, *entry = p; + unsigned int bitness; + int ret; + + ret = get_sc_table(entry, &table, &bitness); + if (ret) + return ret; + seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n", + entry - table, + entry->desc->name, + bitness); + return 0; +} + +static +const struct seq_operations lttng_syscall_list_seq_ops = { + .start = syscall_list_start, + .next = syscall_list_next, + .stop = syscall_list_stop, + .show = syscall_list_show, +}; + +static +int lttng_syscall_list_open(struct inode *inode, struct file *file) +{ + return seq_open(file, <tng_syscall_list_seq_ops); +} + +const struct file_operations lttng_syscall_list_fops = { + .owner = THIS_MODULE, + .open = lttng_syscall_list_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +long lttng_channel_syscall_mask(struct lttng_channel *channel, + struct lttng_kernel_syscall_mask __user *usyscall_mask) +{ + uint32_t len, sc_tables_len, bitmask_len; + int ret = 0, bit; + char *tmp_mask; + struct lttng_syscall_filter *filter; + + ret = get_user(len, &usyscall_mask->len); + if (ret) + return ret; + sc_tables_len = get_sc_tables_len(); + bitmask_len = ALIGN(sc_tables_len, 8) >> 3; + if (len < sc_tables_len) { + return put_user(sc_tables_len, &usyscall_mask->len); + } + /* Array is large enough, we can copy array to user-space. */ + tmp_mask = kzalloc(bitmask_len, GFP_KERNEL); + if (!tmp_mask) + return -ENOMEM; + filter = channel->sc_filter; + + for (bit = 0; bit < ARRAY_SIZE(sc_table); bit++) { + bt_bitfield_write_be(tmp_mask, char, bit, 1, + test_bit(bit, filter->sc)); + } + for (; bit < sc_tables_len; bit++) { + bt_bitfield_write_be(tmp_mask, char, bit, 1, + test_bit(bit - ARRAY_SIZE(sc_table), + filter->sc_compat)); + } + if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len)) + ret = -EFAULT; + kfree(tmp_mask); + return ret; +}