From a7396f637e7c0c9083281b562d514506c465fc02 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Fri, 26 Jun 2015 10:22:37 +0200 Subject: [PATCH] PR18571: tapset support bpf and seccomp syscalls NEWS: Deprecate seccomp's 'uargs' in favor of 'uargs_uaddr'. tapset/linux/aux_syscalls.stp: New _seccomp_op_str() and _bpf_cmd_str(). tapset/linux/nd_syscalls.stp: New probe nd_syscall.bpf. tapset/linux/nd_syscalls2.stp: Update probe nd_syscall.seccomp. tapset/linux/syscalls.stp: New probe syscall.bpf. tapset/linux/syscalls2.stp: Update probe syscall.seccomp. testsuite/buildok/aux_syscalls-embedded.stp: Test _seccomp_op_str(), _bpf_cmd_str(). testsuite/buildok/nd_syscalls-detailed.stp: Test probe nd_syscall.bpf. testsuite/buildok/nd_syscalls2-detailed.stp: Update test for probe nd_syscall.seccomp. testsuite/buildok/syscalls-detailed.stp: Test probe syscall.bpf. testsuite/buildok/syscalls2-detailed.stp: Update test for probe syscall.seccomp. testsuite/systemtap.syscall/bpf.c: New testcase. testsuite/systemtap.syscall/seccomp.c: New testcase. --- NEWS | 2 + tapset/linux/aux_syscalls.stp | 46 ++++++++++++++++++ tapset/linux/nd_syscalls.stp | 20 ++++++++ tapset/linux/nd_syscalls2.stp | 8 +++- tapset/linux/syscalls.stp | 18 +++++++ tapset/linux/syscalls2.stp | 8 +++- testsuite/buildok/aux_syscalls-embedded.stp | 2 + testsuite/buildok/nd_syscalls-detailed.stp | 10 ++++ testsuite/buildok/nd_syscalls2-detailed.stp | 5 +- testsuite/buildok/syscalls-detailed.stp | 10 ++++ testsuite/buildok/syscalls2-detailed.stp | 5 +- testsuite/systemtap.syscall/bpf.c | 49 +++++++++++++++++++ testsuite/systemtap.syscall/seccomp.c | 52 +++++++++++++++++++++ 13 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 testsuite/systemtap.syscall/bpf.c create mode 100644 testsuite/systemtap.syscall/seccomp.c diff --git a/NEWS b/NEWS index d93206a57..8564275a0 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ version 2.9: - The '__int32_compat' library macro got deprecated in favor of new '__compat_long' library macro. + - The 'uargs' convenience variable of the 'seccomp' syscall probe + got deprecated in favor of new 'uargs_uaddr' variable. * What's new in version 2.8, 2015-06-17 diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index 6604cb76a..b38c7f94e 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -5913,3 +5913,49 @@ function _struct_sched_attr_u:string(uaddr:long) } %} +%{ +#ifdef CONFIG_SECCOMP +#include +#endif + +static const _stp_val_array const _stp_seccomp_op_list[] = { +#ifdef SECCOMP_SET_MODE_STRICT + V(SECCOMP_SET_MODE_STRICT), +#endif +#ifdef SECCOMP_SET_MODE_FILTER + V(SECCOMP_SET_MODE_FILTER), +#endif + {0, NULL} +}; +%} + +function _seccomp_op_str:string(op:long) +%{ + _stp_lookup_str(_stp_seccomp_op_list, (unsigned int)STAP_ARG_op, + STAP_RETVALUE, MAXSTRINGLEN); +%} + +%{ +#ifdef CONFIG_BPF_SYSCALL +#include +#endif + +static const _stp_val_array const _stp_bpf_cmd_list[] = { +#ifdef CONFIG_BPF_SYSCALL + V(BPF_MAP_CREATE), + V(BPF_MAP_LOOKUP_ELEM), + V(BPF_MAP_UPDATE_ELEM), + V(BPF_MAP_DELETE_ELEM), + V(BPF_MAP_GET_NEXT_KEY), + V(BPF_PROG_LOAD), +#endif + {0, NULL} +}; +%} + +function _bpf_cmd_str:string(cmd:long) +%{ + _stp_lookup_str(_stp_bpf_cmd_list, (int)STAP_ARG_cmd, + STAP_RETVALUE, MAXSTRINGLEN); +%} + diff --git a/tapset/linux/nd_syscalls.stp b/tapset/linux/nd_syscalls.stp index 921c290d3..075ea8938 100644 --- a/tapset/linux/nd_syscalls.stp +++ b/tapset/linux/nd_syscalls.stp @@ -345,6 +345,26 @@ probe __nd_syscall.socketcall.bind.return = if (@entry(__asmlinkage_int_arg(1)) != %{ SYS_BIND %}) next; } +# bpf ________________________________________________________ +# SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, +# unsigned int, size) +probe nd_syscall.bpf = kprobe.function("sys_bpf") ? +{ + name = "bpf" + asmlinkage() + cmd = int_arg(1) + cmd_str = _bpf_cmd_str(cmd) + attr_uaddr = pointer_arg(2) + size = uint_arg(3) + argstr = sprintf("%s, %p, %u", cmd_str, attr_uaddr, size) + +} +probe nd_syscall.bpf.return = kprobe.function("sys_bpf").return ? +{ + name = "bpf" + retstr = returnstr(1) +} + # brk ________________________________________________________ # unsigned long sys_brk(unsigned long brk) probe nd_syscall.brk = kprobe.function("ia64_brk") ?, diff --git a/tapset/linux/nd_syscalls2.stp b/tapset/linux/nd_syscalls2.stp index 3c965a86e..a07ab032f 100644 --- a/tapset/linux/nd_syscalls2.stp +++ b/tapset/linux/nd_syscalls2.stp @@ -2288,10 +2288,14 @@ probe nd_syscall.seccomp = kprobe.function("sys_seccomp") ? name = "seccomp" asmlinkage() op = uint_arg(1) + op_str = _seccomp_op_str(op) flags = uint_arg(2) - flags_str = _seccomp_flags_str(uint_arg(2)) + flags_str = _seccomp_flags_str(flags) +%( systemtap_v <= "2.9" %? uargs = user_string_quoted(pointer_arg(3)) - argstr = sprintf("%u, %s, %s", uint_arg(1), flags_str, user_string_quoted(pointer_arg(3))) +%) + uargs_uaddr = pointer_arg(3) + argstr = sprintf("%s, %s, %p", op_str, flags_str, uargs_uaddr) } probe nd_syscall.seccomp.return = kprobe.function("sys_seccomp").return ? { diff --git a/tapset/linux/syscalls.stp b/tapset/linux/syscalls.stp index fb277c62b..2c139a735 100644 --- a/tapset/linux/syscalls.stp +++ b/tapset/linux/syscalls.stp @@ -317,6 +317,24 @@ probe __syscall.socketcall.bind.return = if ($call != %{ SYS_BIND %}) next; } +# bpf ________________________________________________________ +# SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, +# unsigned int, size) +probe syscall.bpf = kernel.function("sys_bpf") ? +{ + name = "bpf" + cmd = __int32($cmd) + cmd_str = _bpf_cmd_str(cmd) + attr_uaddr = $uattr + size = __uint32($size) + argstr = sprintf("%s, %p, %u", cmd_str, attr_uaddr, size) +} +probe syscall.bpf.return = kernel.function("sys_bpf").return ? +{ + name = "bpf" + retstr = return_str(1, $return) +} + # brk ________________________________________________________ # unsigned long sys_brk(unsigned long brk) probe syscall.brk = kernel.function("ia64_brk").call ?, diff --git a/tapset/linux/syscalls2.stp b/tapset/linux/syscalls2.stp index 9885ebd81..beefd8d4e 100644 --- a/tapset/linux/syscalls2.stp +++ b/tapset/linux/syscalls2.stp @@ -2213,10 +2213,14 @@ probe syscall.seccomp = kernel.function("sys_seccomp").call ? { name = "seccomp" op = $op + op_str = _seccomp_op_str(op) flags = $flags - flags_str = _seccomp_flags_str($flags) + flags_str = _seccomp_flags_str(flags) +%( systemtap_v <= "2.9" %? uargs = user_string_quoted($uargs) - argstr = sprintf("%u, %s, %s", $op, flags_str, user_string_quoted($uargs)) +%) + uargs_uaddr = $uargs + argstr = sprintf("%s, %s, %p", op_str, flags_str, uargs_uaddr) } probe syscall.seccomp.return = kernel.function("sys_seccomp").return ? { diff --git a/testsuite/buildok/aux_syscalls-embedded.stp b/testsuite/buildok/aux_syscalls-embedded.stp index ab5b00b69..da3b2eb09 100755 --- a/testsuite/buildok/aux_syscalls-embedded.stp +++ b/testsuite/buildok/aux_syscalls-embedded.stp @@ -75,6 +75,8 @@ probe begin { print (_ptrace_event_name(0)) print (_wait_status_str(0)) + print (_seccomp_op_str(0)) + print (_bpf_cmd_str(0)) print (_seccomp_flags_str(0)) print (_msg_flags_str(0)) %(systemtap_v <= "2.5" %? diff --git a/testsuite/buildok/nd_syscalls-detailed.stp b/testsuite/buildok/nd_syscalls-detailed.stp index 33d43fa43..eb39852c6 100755 --- a/testsuite/buildok/nd_syscalls-detailed.stp +++ b/testsuite/buildok/nd_syscalls-detailed.stp @@ -99,6 +99,16 @@ probe nd_syscall.bind.return printf("%s, %s\n", name, retstr) } +probe nd_syscall.bpf ? +{ + printf("%s, %s\n", name, argstr) + printf("%s, %p, %u\n", cmd_str, attr_uaddr, size) +} +probe nd_syscall.bpf.return ? +{ + printf("%s, %s\n", name, retstr) +} + probe nd_syscall.brk { printf("%s, %s\n", name, argstr) diff --git a/testsuite/buildok/nd_syscalls2-detailed.stp b/testsuite/buildok/nd_syscalls2-detailed.stp index 2d880912b..76b0ce26a 100755 --- a/testsuite/buildok/nd_syscalls2-detailed.stp +++ b/testsuite/buildok/nd_syscalls2-detailed.stp @@ -659,7 +659,10 @@ probe nd_syscall.sched_setscheduler.return ? probe nd_syscall.seccomp ? { printf("%s %s\n", name, argstr) - printf("%d %d %s\n", op, flags, uargs) +%( systemtap_v <= "2.9" %? + printf("%d %s %d %s %s %p\n", op, op_str, flags, flags_str, uargs, uargs_uaddr) +%) + printf("%d %s %d %s %p\n", op, op_str, flags, flags_str, uargs_uaddr) } probe nd_syscall.seccomp.return ? { diff --git a/testsuite/buildok/syscalls-detailed.stp b/testsuite/buildok/syscalls-detailed.stp index 72d0e9a99..693c209d5 100755 --- a/testsuite/buildok/syscalls-detailed.stp +++ b/testsuite/buildok/syscalls-detailed.stp @@ -99,6 +99,16 @@ probe syscall.bind.return printf("%s, %s\n", name, retstr) } +probe syscall.bpf ? +{ + printf("%s, %s\n", name, argstr) + printf("%s, %p, %u\n", cmd_str, attr_uaddr, size) +} +probe syscall.bpf.return ? +{ + printf("%s, %s\n", name, retstr) +} + probe syscall.brk { printf("%s, %s\n", name, argstr) diff --git a/testsuite/buildok/syscalls2-detailed.stp b/testsuite/buildok/syscalls2-detailed.stp index 9eef475ce..4328b523d 100755 --- a/testsuite/buildok/syscalls2-detailed.stp +++ b/testsuite/buildok/syscalls2-detailed.stp @@ -664,7 +664,10 @@ probe syscall.sched_yield.return probe syscall.seccomp ? { printf("%s %s\n", name, argstr) - printf("%d %d %s\n", op, flags, uargs) +%( systemtap_v <= "2.9" %? + printf("%d %s %d %s %s %p\n", op, op_str, flags, flags_str, uargs, uargs_uaddr) +%) + printf("%d %s %d %s %p\n", op, op_str, flags, flags_str, uargs_uaddr) } probe syscall.seccomp.return ? { diff --git a/testsuite/systemtap.syscall/bpf.c b/testsuite/systemtap.syscall/bpf.c new file mode 100644 index 000000000..6165f014b --- /dev/null +++ b/testsuite/systemtap.syscall/bpf.c @@ -0,0 +1,49 @@ +/* COVERAGE: bpf */ + +#define _GNU_SOURCE +#include +#include + +#ifdef __NR_bpf + +#include + +static inline int __bpf(int cmd, union bpf_attr *attr, unsigned int size) +{ + return syscall(__NR_bpf, cmd, attr, size); +} + +int main() +{ + int fd; + + union bpf_attr attr = { + .map_type = BPF_MAP_TYPE_HASH, + .key_size = 4, + .value_size = 4, + .max_entries = 2 + }; + + fd = __bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); + //staptest// [[[[bpf (BPF_MAP_CREATE, XXXX, NNNN) = NNNN!!!!ni_syscall () = -NNNN]]]] + close(fd); + + // Limit testing + + __bpf(-1, NULL, 0); + //staptest// [[[[bpf (0x[f]+, 0x0, 0)!!!!ni_syscall ()]]]] = -NNNN + + __bpf(0, (union bpf_attr *)-1, 0); + //staptest// [[[[bpf (BPF_MAP_CREATE, 0x[f]+, 0)!!!!ni_syscall ()]]]] = -NNNN + + __bpf(0, NULL, -1); + //staptest// [[[[bpf (BPF_MAP_CREATE, 0x0, 4294967295)!!!!ni_syscall ()]]]] = -NNNN + + return 0; +} +#else +int main() +{ + return 0; +} +#endif diff --git a/testsuite/systemtap.syscall/seccomp.c b/testsuite/systemtap.syscall/seccomp.c new file mode 100644 index 000000000..f5f99c331 --- /dev/null +++ b/testsuite/systemtap.syscall/seccomp.c @@ -0,0 +1,52 @@ +/* COVERAGE: seccomp */ + +#define _GNU_SOURCE +#include +#include + +#ifdef __NR_seccomp + +#include +#include +#include +#include +#include + +struct sock_filter filter[] = { + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), +}; + +struct sock_fprog prog = { + .len = (unsigned short) (sizeof(filter) / sizeof(filter[0])), + .filter = filter, +}; + +static inline int __seccomp(unsigned int operation, unsigned int flags, void *args) +{ + return syscall(__NR_seccomp, operation, flags, args); +} + +int main() +{ + __seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog); + //staptest// seccomp (SECCOMP_SET_MODE_FILTER, 0x0, XXXX) = 0 + + // Limit testing + + __seccomp(-1, 0, NULL); + //staptest// seccomp (0x[f]+, 0x0, 0x0) = -NNNN + + __seccomp(SECCOMP_SET_MODE_FILTER, -1, NULL); + //staptest// seccomp (SECCOMP_SET_MODE_FILTER, 0x[f]+, 0x0) = -NNNN + + __seccomp(SECCOMP_SET_MODE_FILTER, 0, (void *)-1); + //staptest// seccomp (SECCOMP_SET_MODE_FILTER, 0x0, 0x[f]+) = -NNNN + + return 0; +} +#else +int main() +{ + return 0; +} +#endif -- 2.43.5