From 3813565921c1028fe058edce06a31bf37711ce50 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Wed, 3 Dec 2014 10:15:36 +0100 Subject: [PATCH] PR16716 partial fix: Fix types in syscall.mknod[at] * runtime/linux/compat_unistd.h: Added more compat defines * tapset/linux/aux_syscalls.stp: Fixed types and neesting * tapset/linux/syscalls.stp: Fixed types and neesting * testsuite/systemtap.syscall/mknod.c: new testcase --- runtime/linux/compat_unistd.h | 5 +++ tapset/linux/aux_syscalls.stp | 50 +++++++++++----------- tapset/linux/nd_syscalls.stp | 14 ++++--- tapset/linux/syscalls.stp | 24 ++++++----- testsuite/systemtap.syscall/mknod.c | 64 +++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 41 deletions(-) create mode 100644 testsuite/systemtap.syscall/mknod.c diff --git a/runtime/linux/compat_unistd.h b/runtime/linux/compat_unistd.h index 06256c6c5..da8e98808 100644 --- a/runtime/linux/compat_unistd.h +++ b/runtime/linux/compat_unistd.h @@ -117,6 +117,9 @@ #ifndef __NR_ia32_mkdirat #define __NR_ia32_mkdirat 296 #endif +#ifndef __NR_ia32_mknodat +#define __NR_ia32_mknodat 297 +#endif #ifndef __NR_ia32_mmap2 #define __NR_ia32_mmap2 192 #endif @@ -168,6 +171,7 @@ #define __NR_compat_inotify_init1 __NR_ia32_inotify_init1 #define __NR_compat_linkat __NR_ia32_linkat #define __NR_compat_mkdirat __NR_ia32_mkdirat +#define __NR_compat_mknodat __NR_ia32_mknodat #define __NR_compat_open __NR_ia32_open #define __NR_compat_pipe2 __NR_ia32_pipe2 #define __NR_compat_pselect7 __NR_ia32_pselect7 @@ -203,6 +207,7 @@ #define __NR_compat_inotify_init1 __NR_inotify_init1 #define __NR_compat_linkat __NR_linkat #define __NR_compat_mkdirat __NR_mkdirat +#define __NR_compat_mknodat __NR_mknodat #define __NR_compat_open __NR_open #define __NR_compat_pipe2 __NR_pipe2 #define __NR_compat_pselect7 __NR_pselect7 diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index 3a2450291..4dd4973c3 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -1243,40 +1243,42 @@ function _access_mode_str:string(mode:long) /* `man 2 open` for more information */ function _sys_open_mode_str(f) { - if((f & 448) == 448) bs="S_IRWXU|".bs + if((f & %{ S_IRWXU %}) == %{ S_IRWXU %}) bs="S_IRWXU|".bs else { - if(f & 256) bs="S_IRUSR|".bs - if(f & 128) bs="S_IWUSR|".bs - if(f & 64) bs="S_IXUSR|".bs + if(f & %{ S_IRUSR %}) bs="S_IRUSR|" . bs + if(f & %{ S_IWUSR %}) bs="S_IWUSR|" . bs + if(f & %{ S_IXUSR %}) bs="S_IXUSR|" . bs } - if((f & 56) == 56) bs="S_IRWXG|".bs + if((f & %{ S_IRWXG %}) == %{ S_IRWXG %}) bs="S_IRWXG|" . bs else { - if(f & 32) bs="S_IRGRP|".bs - if(f & 16) bs="S_IWGRP|".bs - if(f & 8) bs="S_IXGRP|".bs + if(f & %{ S_IRGRP %}) bs="S_IRGRP|" . bs + if(f & %{ S_IWGRP %}) bs="S_IWGRP|" . bs + if(f & %{ S_IXGRP %}) bs="S_IXGRP|" . bs } - if((f & 7) == 7) bs="S_IRWXO|".bs + if((f & %{ S_IRWXO %}) == %{ S_IRWXO %}) bs="S_IRWXO|" . bs else { - if(f & 4) bs="S_IROTH|".bs - if(f & 2) bs="S_IWOTH|".bs - if(f & 1) bs="S_IXOTH|".bs + if(f & %{ S_IROTH %}) bs="S_IROTH|" . bs + if(f & %{ S_IWOTH %}) bs="S_IWOTH|" . bs + if(f & %{ S_IXOTH %}) bs="S_IXOTH|" . bs } - return substr(bs,0,strlen(bs)-1) + return (strlen(bs) > 0) ? substr(bs, 0, strlen(bs) - 1) : sprintf("%#o", f) } /* `man 2 mknod` for more information */ function _mknod_mode_str(mode) { - if((mode & 0xF000)==0x8000) - return "S_IFREG|"._sys_open_mode_str(mode) - if((mode & 0xF000)==0x2000) - return "S_IFCHR|"._sys_open_mode_str(mode) - if((mode & 0xF000)==0x6000) - return "S_IFBLK|"._sys_open_mode_str(mode) - if((mode & 0xF000)==0x1000) - return "S_IFIFO|"._sys_open_mode_str(mode) - if((mode & 0xF000)==0xC000) - return "S_IFSOCK|"._sys_open_mode_str(mode) - return "" + type = mode & %{ S_IFMT %} + mode &= %{ ~S_IFMT %} + if (type == %{ S_IFREG %}) + return "S_IFREG|" . _sys_open_mode_str(mode) + if (type == %{ S_IFCHR %}) + return "S_IFCHR|" . _sys_open_mode_str(mode) + if (type == %{ S_IFBLK %}) + return "S_IFBLK|" . _sys_open_mode_str(mode) + if (type == %{ S_IFIFO %}) + return "S_IFIFO|" . _sys_open_mode_str(mode) + if (type == %{ S_IFSOCK %}) + return "S_IFSOCK|" . _sys_open_mode_str(mode) + return sprintf("%#o", type | mode) } %{ diff --git a/tapset/linux/nd_syscalls.stp b/tapset/linux/nd_syscalls.stp index e5ee572b1..418aed8db 100644 --- a/tapset/linux/nd_syscalls.stp +++ b/tapset/linux/nd_syscalls.stp @@ -3293,16 +3293,16 @@ probe nd_syscall.mkdirat.return = kprobe.function("sys_mkdirat").return ? retstr = returnstr(1) } -# mknod +# mknod ______________________________________________________ # long sys_mknod(const char __user * filename, int mode, unsigned dev) probe nd_syscall.mknod = kprobe.function("sys_mknod") ? { name = "mknod" asmlinkage() pathname = user_string_quoted(pointer_arg(1)) - mode = int_arg(2) + mode = uint_arg(2) dev = uint_arg(3) - argstr = sprintf("%s, %s, %p", user_string_quoted(pointer_arg(1)), _mknod_mode_str(mode), dev) + argstr = sprintf("%s, %s, %u", pathname, _mknod_mode_str(mode), dev) } probe nd_syscall.mknod.return = kprobe.function("sys_mknod").return ? @@ -3317,19 +3317,21 @@ probe nd_syscall.mknod.return = kprobe.function("sys_mknod").return ? # int mode, unsigned dev) probe nd_syscall.mknodat = kprobe.function("sys_mknodat") ? { + @__syscall_compat_gate(%{ __NR_mknodat %}, %{ __NR_compat_mknodat %}) name = "mknodat" asmlinkage() dirfd = int_arg(1) dirfd_str = _dfd_str(dirfd) pathname = user_string_quoted(pointer_arg(2)) - mode = int_arg(3) + mode = uint_arg(3) mode_str = _mknod_mode_str(mode) dev = uint_arg(4) - argstr = sprintf("%s, %s, %s, %p", - dirfd_str, user_string_quoted(pointer_arg(2)), mode_str, dev) + argstr = sprintf("%s, %s, %s, %u", + dirfd_str, pathname, mode_str, dev) } probe nd_syscall.mknodat.return = kprobe.function("sys_mknodat").return ? { + @__syscall_compat_gate(%{ __NR_mknodat %}, %{ __NR_compat_mknodat %}) name = "mknodat" retstr = returnstr(1) } diff --git a/tapset/linux/syscalls.stp b/tapset/linux/syscalls.stp index ebbe53548..061346440 100644 --- a/tapset/linux/syscalls.stp +++ b/tapset/linux/syscalls.stp @@ -3139,15 +3139,15 @@ probe syscall.mkdirat.return = kernel.function("sys_mkdirat").return ? retstr = return_str(1, $return) } -# mknod +# mknod ______________________________________________________ # long sys_mknod(const char __user * filename, int mode, unsigned dev) probe syscall.mknod = kernel.function("sys_mknod").call { name = "mknod" pathname = user_string_quoted($filename) - mode = $mode - dev = $dev - argstr = sprintf("%s, %s, %p", user_string_quoted($filename), _mknod_mode_str($mode), dev) + mode = __uint32($mode) + dev = __uint32($dev) + argstr = sprintf("%s, %s, %u", pathname, _mknod_mode_str(mode), dev) } probe syscall.mknod.return = kernel.function("sys_mknod").return @@ -3162,18 +3162,20 @@ probe syscall.mknod.return = kernel.function("sys_mknod").return # int mode, unsigned dev) probe syscall.mknodat = kernel.function("sys_mknodat").call ? { + @__syscall_compat_gate(%{ __NR_mknodat %}, %{ __NR_compat_mknodat %}) name = "mknodat" - dirfd = $dfd - dirfd_str = _dfd_str($dfd) + dirfd = __int32($dfd) + dirfd_str = _dfd_str(dirfd) pathname = user_string_quoted($filename) - mode = $mode - mode_str = _mknod_mode_str($mode) - dev = $dev - argstr = sprintf("%s, %s, %s, %p", - dirfd_str, user_string_quoted($filename), mode_str, $dev) + mode = __uint32($mode) + mode_str = _mknod_mode_str(mode) + dev = __uint32($dev) + argstr = sprintf("%s, %s, %s, %u", + dirfd_str, pathname, mode_str, dev) } probe syscall.mknodat.return = kernel.function("sys_mknodat").return ? { + @__syscall_compat_gate(%{ __NR_mknodat %}, %{ __NR_compat_mknodat %}) name = "mknodat" retstr = return_str(1, $return) } diff --git a/testsuite/systemtap.syscall/mknod.c b/testsuite/systemtap.syscall/mknod.c new file mode 100644 index 000000000..3cf9b6dc9 --- /dev/null +++ b/testsuite/systemtap.syscall/mknod.c @@ -0,0 +1,64 @@ +/* COVERAGE: mknod mknodat */ + +#include +#include +#include +#include +#include + +int main() { + + // ------- test normal operation + + mknod("testfile1", S_IFREG | 0644, 0); + //staptest// mknod ("testfile1", S_IFREG|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = 0 + + syscall(__NR_mknodat, AT_FDCWD, "testfile2", S_IFREG | 0644, 0); + //staptest// mknodat (AT_FDCWD, "testfile2", S_IFREG|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = 0 + + // ------- test nasty things + + mknod((const char *)-1, S_IFREG | 0644, 0); +#ifdef __s390__ + //staptest// mknod ([7]?[f]+, S_IFREG|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN +#else + //staptest// mknod ([f]+, S_IFREG|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN +#endif + + mknod("testfile1", -1, 0); + //staptest// mknod ("testfile1", 037777777777, 0) = NNNN + + syscall(__NR_mknod, "testfile1", 1, -1); + //staptest// mknod ("testfile1", 01, 4294967295) = NNNN + + syscall(__NR_mknodat, (int)-1, "testfile2", S_IFREG | 0644, 0); + //staptest// mknodat (-1, "testfile2", S_IFREG|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN + + syscall(__NR_mknodat, (int)-1, "testfile2", S_IFCHR | 0644, 0); + //staptest// mknodat (-1, "testfile2", S_IFCHR|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN + + syscall(__NR_mknodat, (int)-1, "testfile2", S_IFBLK | 0644, 0); + //staptest// mknodat (-1, "testfile2", S_IFBLK|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN + + syscall(__NR_mknodat, (int)-1, "testfile2", S_IFIFO | 0644, 0); + //staptest// mknodat (-1, "testfile2", S_IFIFO|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN + + syscall(__NR_mknodat, (int)-1, "testfile2", S_IFSOCK | 0644, 0); + //staptest// mknodat (-1, "testfile2", S_IFSOCK|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN + + syscall(__NR_mknodat, AT_FDCWD, (const char *)-1, S_IFREG | 0644, 0); +#ifdef __s390__ + //staptest// mknodat (AT_FDCWD, [7]?[f]+, S_IFREG|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN +#else + //staptest// mknodat (AT_FDCWD, [f]+, S_IFREG|S_IROTH|S_IRGRP|S_IWUSR|S_IRUSR, 0) = NNNN +#endif + + syscall(__NR_mknodat, AT_FDCWD, "testfile2", -1, 0); + //staptest// mknodat (AT_FDCWD, "testfile2", 037777777777, 0) = NNNN + + syscall(__NR_mknodat, AT_FDCWD, "testfile2", 1, -1); + //staptest// mknodat (AT_FDCWD, "testfile2", 01, 4294967295) = NNNN + + return 0; + +} -- 2.43.5