From: David Smith Date: Fri, 22 Nov 2013 22:41:54 +0000 (-0600) Subject: PR16207 partial fix: Fix the access [nd_]syscall.exp tests on rawhide. X-Git-Tag: release-2.5~389^2~41 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=b72512c6a1b92209d41213cb83966db60851c7b0;p=systemtap.git PR16207 partial fix: Fix the access [nd_]syscall.exp tests on rawhide. * tapset/linux/syscalls.stpm: Add @__syscall_compat_gate() macro. * tapset/linux/syscalls.stp: Add @__syscall_compat_gate() macro call to syscall.faccessat and syscall.faccess.return. * tapset/linux/nd_syscalls.stp: Add @__syscall_compat_gate() macro call to nd_syscall.faccessat and nd_syscall.faccess.return. * testsuite/systemtap.syscall/access.c: Updated testcase to handle access() no longer being a wrapper around faccessat(). * runtime/linux/compat_unistd.h: New file. * tapset/linux/aux_syscalls.stp: Include compat_unistd.h. --- diff --git a/runtime/linux/compat_unistd.h b/runtime/linux/compat_unistd.h new file mode 100644 index 000000000..a7ce1ed40 --- /dev/null +++ b/runtime/linux/compat_unistd.h @@ -0,0 +1,35 @@ +/* -*- linux-c -*- + * Syscall compatibility defines. + * Copyright (C) 2013 Red Hat Inc. + * + * This file is part of systemtap, and is free software. You can + * redistribute it and/or modify it under the terms of the GNU General + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + +#ifndef _COMPAT_UNISTD_H_ +#define _COMPAT_UNISTD_H_ + +#if defined(__x86_64__) + +// On older kernels (like RHEL5), we have to define our own 32-bit +// syscall numbers. +#ifndef __NR_ia32_faccessat +#define __NR_ia32_faccessat 307 +#endif + +#define __NR_compat_faccessat __NR_ia32_faccessat + +#endif /* __x86_64__ */ + +#if defined(__powerpc64__) || defined (__s390x__) + +// On the ppc64 and s390x, the 32-bit syscalls use the same number +// as the 64-bit syscalls. + +#define __NR_compat_faccessat __NR_faccessat + +#endif /* __powerpc64__ || __s390x__ */ + +#endif /* _COMPAT_UNISTD_H_ */ diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index 79250121a..2141a0695 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -2,6 +2,7 @@ %{ // Be sure we have the __NR_* defines. #include +#include "linux/compat_unistd.h" %} function _stp_syscall_nr:long () diff --git a/tapset/linux/nd_syscalls.stp b/tapset/linux/nd_syscalls.stp index d89240fb3..4d39ec7ab 100644 --- a/tapset/linux/nd_syscalls.stp +++ b/tapset/linux/nd_syscalls.stp @@ -1129,6 +1129,8 @@ probe nd_syscall.exit_group = kprobe.function("sys_exit_group").call ? # long sys_faccessat(int dfd, const char __user *filename, int mode) probe nd_syscall.faccessat = kprobe.function("sys_faccessat") ? { + @__syscall_compat_gate(%{ __NR_faccessat %}, + %{ __NR_compat_faccessat %}) name = "faccessat" // dirfd = $dfd // dirfd_str = _dfd_str($dfd) @@ -1146,6 +1148,8 @@ probe nd_syscall.faccessat = kprobe.function("sys_faccessat") ? } probe nd_syscall.faccessat.return = kprobe.function("sys_faccessat").return ? { + @__syscall_compat_gate(%{ __NR_faccessat %}, + %{ __NR_compat_faccessat %}) name = "faccessat" retstr = returnstr(1) } diff --git a/tapset/linux/syscalls.stp b/tapset/linux/syscalls.stp index f53cf88a8..7f1358bb5 100644 --- a/tapset/linux/syscalls.stp +++ b/tapset/linux/syscalls.stp @@ -857,6 +857,8 @@ probe syscall.exit_group = kernel.function("sys_exit_group").call # long sys_faccessat(int dfd, const char __user *filename, int mode) probe syscall.faccessat = kernel.function("sys_faccessat").call ? { + @__syscall_compat_gate(%{ __NR_faccessat %}, + %{ __NR_compat_faccessat %}) name = "faccessat" dirfd = $dfd dirfd_str = _dfd_str($dfd) @@ -867,6 +869,8 @@ probe syscall.faccessat = kernel.function("sys_faccessat").call ? } probe syscall.faccessat.return = kernel.function("sys_faccessat").return ? { + @__syscall_compat_gate(%{ __NR_faccessat %}, + %{ __NR_compat_faccessat %}) name = "faccessat" retstr = return_str(1, $return) } diff --git a/tapset/linux/syscalls.stpm b/tapset/linux/syscalls.stpm index 652a4e364..bbd90f22c 100644 --- a/tapset/linux/syscalls.stpm +++ b/tapset/linux/syscalls.stpm @@ -19,3 +19,18 @@ if (_stp_syscall_nr() != @syscall_nr) next %) + +@define __syscall_compat_gate(syscall_nr, compat_syscall_nr) +%( + %( CONFIG_COMPAT == "y" %? + __nr = _stp_syscall_nr() + if (%{ _stp_is_compat_task() %}) { + if (__nr != @compat_syscall_nr) + next + } + else if (__nr != @syscall_nr) + next + %: + if (_stp_syscall_nr() != @syscall_nr) next + %) +%) diff --git a/testsuite/systemtap.syscall/access.c b/testsuite/systemtap.syscall/access.c index 450660156..1d73f5e24 100644 --- a/testsuite/systemtap.syscall/access.c +++ b/testsuite/systemtap.syscall/access.c @@ -1,10 +1,21 @@ -/* COVERAGE: access */ +/* COVERAGE: access faccessat */ +#define _GNU_SOURCE #include #include #include #include #include +// To test for glibc support for faccessat(): +// +// Since glibc 2.10: +// _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L +// Before glibc 2.10: +// _ATFILE_SOURCE + +#define GLIBC_SUPPORT \ + (_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L \ + || defined(_ATFILE_SOURCE)) int main() { @@ -13,28 +24,52 @@ int main() fd1 = creat("foobar1",S_IREAD|S_IWRITE); access("foobar1", F_OK); - //staptest// access ("foobar1", F_OK) - //staptest// faccessat (AT_FDCWD, "foobar1", F_OK) = 0 + //staptest// access ("foobar1", F_OK) = 0 + +#if GLIBC_SUPPORT + faccessat(AT_FDCWD, "foobar1", F_OK, 0); + //staptest// faccessat (AT_FDCWD, "foobar1", F_OK) = 0 +#endif access("foobar1", R_OK); - //staptest// access ("foobar1", R_OK) - //staptest// faccessat (AT_FDCWD, "foobar1", R_OK) = 0 + //staptest// access ("foobar1", R_OK) = 0 + +#if GLIBC_SUPPORT + faccessat(AT_FDCWD, "foobar1", R_OK, 0); + //staptest// faccessat (AT_FDCWD, "foobar1", R_OK) = 0 +#endif access("foobar1", W_OK); - //staptest// access ("foobar1", W_OK) - //staptest// faccessat (AT_FDCWD, "foobar1", W_OK) = 0 + //staptest// access ("foobar1", W_OK) = 0 + +#if GLIBC_SUPPORT + faccessat(AT_FDCWD, "foobar1", W_OK, 0); + //staptest// faccessat (AT_FDCWD, "foobar1", W_OK) = 0 +#endif access("foobar1", X_OK); - //staptest// access ("foobar1", X_OK) - //staptest// faccessat (AT_FDCWD, "foobar1", X_OK) = -NNNN (EACCES) + //staptest// access ("foobar1", X_OK) = -NNNN (EACCES) + +#if GLIBC_SUPPORT + faccessat(AT_FDCWD, "foobar1", X_OK, 0); + //staptest// faccessat (AT_FDCWD, "foobar1", X_OK) = -NNNN (EACCES) +#endif access("foobar1", R_OK|W_OK); - //staptest// access ("foobar1", W_OK |R_OK) - //staptest// faccessat (AT_FDCWD, "foobar1", W_OK |R_OK) = 0 + //staptest// access ("foobar1", W_OK |R_OK) = 0 + +#if GLIBC_SUPPORT + faccessat(AT_FDCWD, "foobar1", R_OK|W_OK, 0); + //staptest// faccessat (AT_FDCWD, "foobar1", W_OK |R_OK) = 0 +#endif access("foobar1", R_OK|W_OK|X_OK); - //staptest// access ("foobar1", X_OK |W_OK |R_OK) - //staptest// faccessat (AT_FDCWD, "foobar1", X_OK |W_OK |R_OK) = -NNNN (EACCES) + //staptest// access ("foobar1", X_OK |W_OK |R_OK) = -NNNN (EACCES) + +#if GLIBC_SUPPORT + faccessat(AT_FDCWD, "foobar1", R_OK|W_OK|X_OK, 0); + //staptest// faccessat (AT_FDCWD, "foobar1", X_OK |W_OK |R_OK) = -NNNN (EACCES) +#endif return 0; }