From a4c43fc294c9442ad45e9433a5af8fc3a2c25806 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Thu, 9 Oct 2014 08:30:06 +0200 Subject: [PATCH] PR16716 partial fix: Fix types in syscall.{getrlimit,ioctl} * tapset/linux/nd_syscalls.stp: Fix types, add compat support * tapset/linux/syscalls.stp: Fix types, add compat support * tapset/linux/syscalls.stpm: New macro __syscall_gate_compat_simple * testsuite/systemtap.syscall/getrlimit.c new testcase * testsuite/systemtap.syscall/ioctl.c new testcase --- tapset/linux/nd_syscalls.stp | 42 +++++++++++++++------- tapset/linux/syscalls.stp | 48 +++++++++++++++++-------- tapset/linux/syscalls.stpm | 7 ++++ testsuite/systemtap.syscall/getrlimit.c | 30 ++++++++++++++++ testsuite/systemtap.syscall/ioctl.c | 42 ++++++++++++++++++++++ 5 files changed, 142 insertions(+), 27 deletions(-) create mode 100644 testsuite/systemtap.syscall/getrlimit.c create mode 100644 testsuite/systemtap.syscall/ioctl.c diff --git a/tapset/linux/nd_syscalls.stp b/tapset/linux/nd_syscalls.stp index 3079b4623..d95e17a54 100644 --- a/tapset/linux/nd_syscalls.stp +++ b/tapset/linux/nd_syscalls.stp @@ -2161,23 +2161,32 @@ probe nd_syscall.getresuid.return = kprobe.function("sys_getresuid16").return ?, # long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim) # long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim) # long compat_sys_getrlimit (unsigned int resource, struct compat_rlimit __user *rlim) -probe nd_syscall.getrlimit = kprobe.function("sys_getrlimit") ?, - kprobe.function("sys_old_getrlimit") ?, - kprobe.function("compat_sys_getrlimit") ? +probe nd_syscall.getrlimit = __nd_syscall.getrlimit ?, + kprobe.function("compat_sys_getrlimit") ?, + kprobe.function("sys_old_getrlimit") ? { name = "getrlimit" asmlinkage() - resource = uint_arg(1) + resource = int_arg(1) rlim_uaddr = pointer_arg(2) argstr = sprintf("%s, %p", _rlimit_resource_str(resource), rlim_uaddr) } -probe nd_syscall.getrlimit.return = kprobe.function("sys_getrlimit").return ?, - kprobe.function("sys_old_getrlimit").return ?, - kprobe.function("compat_sys_getrlimit").return ? +probe __nd_syscall.getrlimit = kprobe.function("sys_getrlimit") +{ + @__syscall_gate_compat_simple +} +probe nd_syscall.getrlimit.return = __nd_syscall.getrlimit.return ?, + kernel.function("sys_old_getrlimit").return ?, + kernel.function("compat_sys_getrlimit").return ?, + __nd_syscall.old_getrlimit.return ? { name = "getrlimit" retstr = returnstr(1) } +probe __nd_syscall.getrlimit.return = kernel.function("sys_getrlimit").return +{ + @__syscall_gate_compat_simple +} # getrusage __________________________________________________ # long sys_getrusage(int who, struct rusage __user *ru) @@ -2526,22 +2535,31 @@ probe nd_syscall.io_cancel.return = kprobe.function("sys_io_cancel").return ? # long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) # long compat_sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) # -probe nd_syscall.ioctl = kprobe.function("compat_sys_ioctl") ?, - kprobe.function("sys_ioctl") ? +probe nd_syscall.ioctl = __nd_syscall.ioctl, + kprobe.function("compat_sys_ioctl") ? { - name = "ioctl" asmlinkage() + name = "ioctl" fd = int_arg(1) request = int_arg(2) argp = ulong_arg(3) argstr = sprintf("%d, %d, %p", fd, request, argp) } -probe nd_syscall.ioctl.return = kprobe.function("compat_sys_ioctl").return ?, - kprobe.function("sys_ioctl").return ? +probe __nd_syscall.ioctl = kprobe.function("sys_ioctl") +{ + @__syscall_gate(%{ __NR_ioctl %}) +} +probe nd_syscall.ioctl.return = + __nd_syscall.ioctl.return, + kprobe.function("compat_sys_ioctl").return ? { name = "ioctl" retstr = returnstr(1) } +probe __nd_syscall.ioctl.return = kprobe.function("sys_ioctl").return +{ + @__syscall_gate(%{ __NR_ioctl %}) +} # io_destroy _________________________________________________ # long sys_io_destroy(aio_context_t ctx) diff --git a/tapset/linux/syscalls.stp b/tapset/linux/syscalls.stp index 09faad615..aa9d920d4 100644 --- a/tapset/linux/syscalls.stp +++ b/tapset/linux/syscalls.stp @@ -2044,22 +2044,31 @@ probe syscall.getresuid.return = kernel.function("sys_getresuid16").return ?, # long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim) # long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim) # long compat_sys_getrlimit (unsigned int resource, struct compat_rlimit __user *rlim) -probe syscall.getrlimit = kernel.function("sys_getrlimit").call ?, - kernel.function("sys_old_getrlimit").call ?, - kernel.function("compat_sys_getrlimit").call ? +probe syscall.getrlimit = __syscall.getrlimit ?, + kernel.function("compat_sys_getrlimit").call ?, + kernel.function("sys_old_getrlimit").call ? { name = "getrlimit" - resource = $resource + resource = __int32($resource) rlim_uaddr = $rlim - argstr = sprintf("%s, %p", _rlimit_resource_str($resource), $rlim) + argstr = sprintf("%s, %p", _rlimit_resource_str(resource), $rlim) } -probe syscall.getrlimit.return = kernel.function("sys_getrlimit").return ?, - kernel.function("sys_old_getrlimit").return ?, - kernel.function("compat_sys_getrlimit").return ? +probe __syscall.getrlimit = kernel.function("sys_getrlimit").call +{ + @__syscall_gate_compat_simple +} +probe syscall.getrlimit.return = + kernel.function("sys_old_getrlimit").return ?, + kernel.function("compat_sys_getrlimit").return ?, + __syscall.getrlimit.return ? { name = "getrlimit" retstr = return_str(1, $return) } +probe __syscall.getrlimit.return = kernel.function("sys_getrlimit").return +{ + @__syscall_gate_compat_simple +} # getrusage __________________________________________________ # long sys_getrusage(int who, struct rusage __user *ru) @@ -2393,21 +2402,30 @@ probe syscall.io_cancel.return = kernel.function("sys_io_cancel").return # long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) # long compat_sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) # -probe syscall.ioctl = kernel.function("compat_sys_ioctl").call ?, - kernel.function("sys_ioctl").call ? +probe syscall.ioctl = __syscall.ioctl ?, + kernel.function("compat_sys_ioctl").call ? { name = "ioctl" - fd = $fd - request = $cmd + fd = __int32($fd) + request = __int32($cmd) argp = @choose_defined($arg, $arg32) - argstr = sprintf("%d, %d, %p", $fd, $cmd, argp) + argstr = sprintf("%d, %d, %p", fd, request, argp) +} +probe __syscall.ioctl = kernel.function("sys_ioctl").call +{ + @__syscall_gate(%{ __NR_ioctl %}) } -probe syscall.ioctl.return = kernel.function("compat_sys_ioctl").return ?, - kernel.function("sys_ioctl").return ? +probe syscall.ioctl.return = + __syscall.ioctl.return ?, + kernel.function("compat_sys_ioctl").return ? { name = "ioctl" retstr = return_str(1, $return) } +probe __syscall.ioctl.return = kernel.function("sys_ioctl").return +{ + @__syscall_gate(%{ __NR_ioctl %}) +} # io_destroy _________________________________________________ # long sys_io_destroy(aio_context_t ctx) diff --git a/tapset/linux/syscalls.stpm b/tapset/linux/syscalls.stpm index 0d796691c..ce9b3a90e 100644 --- a/tapset/linux/syscalls.stpm +++ b/tapset/linux/syscalls.stpm @@ -59,6 +59,13 @@ %) %) +@define __syscall_gate_compat_simple +%( + %( CONFIG_COMPAT == "y" %? + if (%{ _stp_is_compat_task() %}) next + %) +%) + @define __pointer(val) %( %( CONFIG_COMPAT == "y" %? diff --git a/testsuite/systemtap.syscall/getrlimit.c b/testsuite/systemtap.syscall/getrlimit.c new file mode 100644 index 000000000..cc4df849f --- /dev/null +++ b/testsuite/systemtap.syscall/getrlimit.c @@ -0,0 +1,30 @@ +/* COVERAGE: getrlimit */ +#include +#include + +struct rlimit rlim; + +int main() { + + // --- first try out normal operation --- + + getrlimit(RLIMIT_CPU, &rlim); + //staptest// getrlimit (RLIMIT_CPU, XXXX) = 0 + + // --- then check nasty calls --- + + getrlimit(-1, &rlim); + //staptest// getrlimit (RLIM_INFINITY, XXXX) = NNNN (EINVAL) + + getrlimit(-15, &rlim); + //staptest// getrlimit (UNKNOWN VALUE: -15, XXXX) = NNNN (EINVAL) + + getrlimit(RLIMIT_CPU, (struct rlimit *)-1); +#ifdef __s390__ + //staptest// getrlimit (RLIMIT_CPU, 0x[7]?[f]+) = NNNN (EFAULT) +#else + //staptest// getrlimit (RLIMIT_CPU, 0x[f]+) = NNNN (EFAULT) +#endif + + return 0; +} diff --git a/testsuite/systemtap.syscall/ioctl.c b/testsuite/systemtap.syscall/ioctl.c new file mode 100644 index 000000000..72c879672 --- /dev/null +++ b/testsuite/systemtap.syscall/ioctl.c @@ -0,0 +1,42 @@ +/* COVERAGE: ioctl */ + +#include +#include +#include +#include +#include + +unsigned int fd, val; +char fname[] = "/dev/net/tun"; + +int main() { + fd = open(fname, O_RDWR); + if (fd < 0) { + printf("ERROR (open %s)\n", fname); + } + + // ----- try successful call ----- + + ioctl(fd, TUNGETFEATURES, &val); + //staptest/ ioctl (NNNN, NNNN, XXXX) = NNNN + + + // ----- try ugly things ----- + + ioctl(-1, TUNGETFEATURES, &val); + //staptest// ioctl (-1, NNNN, XXXX) = NNNN + + ioctl(fd, -1, &val); + //staptest// ioctl (NNNN, -1, XXXX) = NNNN + + ioctl(fd, TUNGETFEATURES, -1); +#ifdef __s390__ + //staptest// ioctl (NNNN, NNNN, 0x[7]?[f]+) = NNNN +#else + //staptest// ioctl (NNNN, NNNN, 0x[f]+) = NNNN +#endif + + close(fd); + + return 0; +} -- 2.43.5