From: Dmitry V. Levin Date: Wed, 21 Nov 2018 01:44:16 +0000 (+0000) Subject: Introduce PTRACE_GET_SYSCALL_INFO support X-Git-Tag: v4.26~49 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e3b80cb65fd50c4e377a01e780b7a46ce4ebb2e7;p=strace Introduce PTRACE_GET_SYSCALL_INFO support When PTRACE_GET_SYSCALL_INFO API works, use it instead of traditional upeek/get_regs API. Tested on x86_64 and x86. * get_personality.c: New file. * get_personality.h: Likewise. * Makefile.am (strace_SOURCES): Add them. * linux/aarch64/arch_get_personality.c: New file. * linux/powerpc64/arch_get_personality.c: Likewise. * linux/riscv/arch_get_personality.c: Likewise. * linux/s390x/arch_get_personality.c: Likewise. * linux/sparc64/arch_get_personality.c: Likewise. * linux/tile/arch_get_personality.c: Likewise. * linux/x32/arch_get_personality.c: Likewise. * linux/x86_64/arch_get_personality.c: Likewise. * linux/check_scno.c: Likewise. * linux/x32/check_scno.c: Likewise. * Makefile.am (EXTRA_DIST): Add them. * linux/ia64/arch_getrval2.c (getrval2): Invoke get_regs() if ptrace_syscall_info is in use. * linux/mips/arch_getrval2.c: Likewise. * linux/sparc/arch_getrval2.c: Likewise. * defs.h (get_personality_from_syscall_info): New prototype. * syscall.c: Include "get_personality.h" and "ptrace_syscall_info.h". (get_regs_error): Define unconditionally. (ptrace_sci): New static variable. (clear_regs): Reset ptrace_sci.op. (ptrace_syscall_info_is_valid, ptrace_get_syscall_info, get_syscall_regs): New functions. (get_syscall_result_regs): Change to get_syscall_regs. (get_instruction_pointer, get_stack_pointer, get_scno, get_syscall_args, get_error, set_error, set_success): Add ptrace_syscall_info support. * tests/int_0x80.test: New test. * tests/Makefile.am (DECODER_TESTS): Add int_0x80.test. (XFAIL_TESTS_x86_64, XFAIL_TESTS_x32): Remove. * tests/gen_tests.in (int_0x80): Remove. --- diff --git a/Makefile.am b/Makefile.am index e13c9258..1bc77bb7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -134,6 +134,8 @@ strace_SOURCES = \ fs_x_ioctl.c \ futex.c \ gcc_compat.h \ + get_personality.c \ + get_personality.h \ get_robust_list.c \ getcpu.c \ getcwd.c \ @@ -417,6 +419,7 @@ EXTRA_DIST = \ linux/64/ioctls_inc.h \ linux/64/syscallent.h \ linux/aarch64/arch_defs_.h \ + linux/aarch64/arch_get_personality.c \ linux/aarch64/arch_regs.c \ linux/aarch64/arch_sigreturn.c \ linux/aarch64/get_error.c \ @@ -505,6 +508,7 @@ EXTRA_DIST = \ linux/bfin/set_scno.c \ linux/bfin/syscallent.h \ linux/bfin/userent.h \ + linux/check_scno.c \ linux/dummy.h \ linux/errnoent.h \ linux/getregs_old.h \ @@ -524,8 +528,8 @@ EXTRA_DIST = \ linux/hppa/set_scno.c \ linux/hppa/signalent.h \ linux/hppa/syscallent.h \ - linux/i386/arch_kvm.c \ linux/i386/arch_defs_.h \ + linux/i386/arch_kvm.c \ linux/i386/arch_regs.c \ linux/i386/arch_rt_sigframe.c \ linux/i386/arch_sigreturn.c \ @@ -663,6 +667,7 @@ EXTRA_DIST = \ linux/powerpc/syscallent.h \ linux/powerpc/userent.h \ linux/powerpc64/arch_defs_.h \ + linux/powerpc64/arch_get_personality.c \ linux/powerpc64/arch_regs.c \ linux/powerpc64/arch_rt_sigframe.c \ linux/powerpc64/arch_sigreturn.c \ @@ -686,6 +691,7 @@ EXTRA_DIST = \ linux/ptrace_pokeuser.c \ linux/raw_syscall.h \ linux/riscv/arch_defs_.h \ + linux/riscv/arch_get_personality.c \ linux/riscv/arch_regs.c \ linux/riscv/get_error.c \ linux/riscv/get_scno.c \ @@ -717,6 +723,7 @@ EXTRA_DIST = \ linux/s390/userent0.h \ linux/s390/userent1.h \ linux/s390x/arch_defs_.h \ + linux/s390x/arch_get_personality.c \ linux/s390x/arch_regs.c \ linux/s390x/arch_sigreturn.c \ linux/s390x/get_error.c \ @@ -786,6 +793,7 @@ EXTRA_DIST = \ linux/sparc/syscallent.h \ linux/sparc/userent.h \ linux/sparc64/arch_defs_.h \ + linux/sparc64/arch_get_personality.c \ linux/sparc64/arch_getrval2.c \ linux/sparc64/arch_regs.c \ linux/sparc64/arch_rt_sigframe.c \ @@ -809,6 +817,7 @@ EXTRA_DIST = \ linux/subcall.h \ linux/syscall.h \ linux/tile/arch_defs_.h \ + linux/tile/arch_get_personality.c \ linux/tile/arch_regs.c \ linux/tile/arch_sigreturn.c \ linux/tile/get_error.c \ @@ -829,11 +838,13 @@ EXTRA_DIST = \ linux/userent.h \ linux/userent0.h \ linux/x32/arch_defs_.h \ + linux/x32/arch_get_personality.c \ linux/x32/arch_kvm.c \ linux/x32/arch_regs.c \ linux/x32/arch_regs.h \ linux/x32/arch_rt_sigframe.c \ linux/x32/arch_sigreturn.c \ + linux/x32/check_scno.c \ linux/x32/get_error.c \ linux/x32/get_scno.c \ linux/x32/get_syscall_args.c \ @@ -851,6 +862,7 @@ EXTRA_DIST = \ linux/x32/syscallent1.h \ linux/x32/userent.h \ linux/x86_64/arch_defs_.h \ + linux/x86_64/arch_get_personality.c \ linux/x86_64/arch_kvm.c \ linux/x86_64/arch_regs.c \ linux/x86_64/arch_regs.h \ diff --git a/get_personality.c b/get_personality.c new file mode 100644 index 00000000..4fa09694 --- /dev/null +++ b/get_personality.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "defs.h" + +#if SUPPORTED_PERSONALITIES > 1 +# include "get_personality.h" +# include +# include "arch_get_personality.c" +#endif diff --git a/get_personality.h b/get_personality.h new file mode 100644 index 00000000..7571e43d --- /dev/null +++ b/get_personality.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef STRACE_GET_PERSONALITY_H +#define STRACE_GET_PERSONALITY_H + +#include "ptrace.h" + +extern int +get_personality_from_syscall_info(const struct ptrace_syscall_info *); + +#endif /* !STRACE_GET_PERSONALITY_H */ diff --git a/linux/aarch64/arch_get_personality.c b/linux/aarch64/arch_get_personality.c new file mode 100644 index 00000000..534d7f4f --- /dev/null +++ b/linux/aarch64/arch_get_personality.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef AUDIT_ARCH_ARM +# define AUDIT_ARCH_ARM 0x40000028 +#endif + +int +get_personality_from_syscall_info(const struct ptrace_syscall_info *sci) +{ + return sci->arch == AUDIT_ARCH_ARM; +} diff --git a/linux/check_scno.c b/linux/check_scno.c new file mode 100644 index 00000000..cdeff678 --- /dev/null +++ b/linux/check_scno.c @@ -0,0 +1,6 @@ +/* Return codes: 1 - ok, 0 - ignore, other - error. */ +static int +arch_check_scno(struct tcb *tcp) +{ + return 1; +} diff --git a/linux/ia64/arch_getrval2.c b/linux/ia64/arch_getrval2.c index 7a6875f0..f4ea78cc 100644 --- a/linux/ia64/arch_getrval2.c +++ b/linux/ia64/arch_getrval2.c @@ -1,5 +1,7 @@ long getrval2(struct tcb *tcp) { + if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0) + return -1; return ia64_regs.gr[9]; } diff --git a/linux/mips/arch_getrval2.c b/linux/mips/arch_getrval2.c index 332f2706..fd73a79c 100644 --- a/linux/mips/arch_getrval2.c +++ b/linux/mips/arch_getrval2.c @@ -1,5 +1,7 @@ long getrval2(struct tcb *tcp) { + if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0) + return -1; return mips_regs.uregs[3]; } diff --git a/linux/powerpc64/arch_get_personality.c b/linux/powerpc64/arch_get_personality.c new file mode 100644 index 00000000..9817d44a --- /dev/null +++ b/linux/powerpc64/arch_get_personality.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef AUDIT_ARCH_PPC +# define AUDIT_ARCH_PPC 0x14 +#endif + +int +get_personality_from_syscall_info(const struct ptrace_syscall_info *sci) +{ + return sci->arch == AUDIT_ARCH_PPC; +} diff --git a/linux/riscv/arch_get_personality.c b/linux/riscv/arch_get_personality.c new file mode 100644 index 00000000..78cf4329 --- /dev/null +++ b/linux/riscv/arch_get_personality.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef AUDIT_ARCH_RISCV32 +# define AUDIT_ARCH_RISCV32 0x400000f3 +#endif + +int +get_personality_from_syscall_info(const struct ptrace_syscall_info *sci) +{ + return sci->arch == AUDIT_ARCH_RISCV32; +} diff --git a/linux/s390x/arch_get_personality.c b/linux/s390x/arch_get_personality.c new file mode 100644 index 00000000..8b12132e --- /dev/null +++ b/linux/s390x/arch_get_personality.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef AUDIT_ARCH_S390 +# define AUDIT_ARCH_S390 0x16 +#endif + +int +get_personality_from_syscall_info(const struct ptrace_syscall_info *sci) +{ + return sci->arch == AUDIT_ARCH_S390; +} diff --git a/linux/sparc/arch_getrval2.c b/linux/sparc/arch_getrval2.c index 9079482c..f8783533 100644 --- a/linux/sparc/arch_getrval2.c +++ b/linux/sparc/arch_getrval2.c @@ -1,5 +1,7 @@ long getrval2(struct tcb *tcp) { + if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0) + return -1; return sparc_regs.u_regs[U_REG_O1]; } diff --git a/linux/sparc64/arch_get_personality.c b/linux/sparc64/arch_get_personality.c new file mode 100644 index 00000000..36d11915 --- /dev/null +++ b/linux/sparc64/arch_get_personality.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef AUDIT_ARCH_SPARC +# define AUDIT_ARCH_SPARC 0x2 +#endif + +int +get_personality_from_syscall_info(const struct ptrace_syscall_info *sci) +{ + return sci->arch == AUDIT_ARCH_SPARC; +} diff --git a/linux/tile/arch_get_personality.c b/linux/tile/arch_get_personality.c new file mode 100644 index 00000000..0a88242d --- /dev/null +++ b/linux/tile/arch_get_personality.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef AUDIT_ARCH_TILEGX32 +# define AUDIT_ARCH_TILEGX32 0x400000bf +#endif +#ifndef AUDIT_ARCH_TILEPRO +# define AUDIT_ARCH_TILEPRO 0x400000bc +#endif + +int +get_personality_from_syscall_info(const struct ptrace_syscall_info *sci) +{ + return sci->arch == AUDIT_ARCH_TILEGX32 || + sci->arch == AUDIT_ARCH_TILEPRO; +} diff --git a/linux/x32/arch_get_personality.c b/linux/x32/arch_get_personality.c new file mode 100644 index 00000000..a8ede47e --- /dev/null +++ b/linux/x32/arch_get_personality.c @@ -0,0 +1 @@ +#include "x86_64/arch_get_personality.c" diff --git a/linux/x32/check_scno.c b/linux/x32/check_scno.c new file mode 100644 index 00000000..42387012 --- /dev/null +++ b/linux/x32/check_scno.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2018 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +/* Return codes: 1 - ok, 0 - ignore, other - error. */ +static int +arch_check_scno(struct tcb *tcp) +{ + + const kernel_ulong_t scno = ptrace_sci.entry.nr; + + if (tcp->currpers == 0 && !(scno & __X32_SYSCALL_BIT)) { + error_msg("syscall_%" PRI_klu "(...) in unsupported " + "64-bit mode of process PID=%d", scno, tcp->pid); + return 0; + } + + return 1; +} diff --git a/linux/x86_64/arch_get_personality.c b/linux/x86_64/arch_get_personality.c new file mode 100644 index 00000000..fc313a81 --- /dev/null +++ b/linux/x86_64/arch_get_personality.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010-2018 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef AUDIT_ARCH_I386 +# define AUDIT_ARCH_I386 0x40000003 +#endif + +int +get_personality_from_syscall_info(const struct ptrace_syscall_info *sci) +{ + unsigned int pers = sci->arch == AUDIT_ARCH_I386; + +#ifndef X32 + switch(sci->op) { + case PTRACE_SYSCALL_INFO_ENTRY: + case PTRACE_SYSCALL_INFO_SECCOMP: + break; + default: + return -1; + } + + kernel_ulong_t scno = sci->entry.nr; + +#ifndef __X32_SYSCALL_BIT +# define __X32_SYSCALL_BIT 0x40000000 +#endif + + if (pers == 0 && (scno & __X32_SYSCALL_BIT)) { + /* + * Syscall number -1 requires special treatment: + * it might be a side effect of SECCOMP_RET_ERRNO + * filtering that sets orig_rax to -1 + * in some versions of linux kernel. + * If that is the case, then + * __X32_SYSCALL_BIT logic does not apply. + */ + if (scno != (kernel_ulong_t) -1) + pers = 2; + } +#endif /* !X32 */ + + return pers; +} diff --git a/syscall.c b/syscall.c index dfddde7b..a4e3ea54 100644 --- a/syscall.c +++ b/syscall.c @@ -13,9 +13,11 @@ */ #include "defs.h" +#include "get_personality.h" #include "mmap_notify.h" #include "native_defs.h" #include "ptrace.h" +#include "ptrace_syscall_info.h" #include "nsig.h" #include "number_set.h" #include "delay.h" @@ -461,6 +463,7 @@ static void get_error(struct tcb *, bool); static void set_error(struct tcb *, unsigned long); static void set_success(struct tcb *, kernel_long_t); static int arch_get_scno(struct tcb *); +static int arch_check_scno(struct tcb *); static int arch_set_scno(struct tcb *, kernel_ulong_t); static int arch_get_syscall_args(struct tcb *); static void arch_get_error(struct tcb *, bool); @@ -943,11 +946,21 @@ restore_cleared_syserror(struct tcb *tcp) tcp->u_error = saved_u_error; } +static struct ptrace_syscall_info ptrace_sci; + +static bool +ptrace_syscall_info_is_valid(void) +{ + return ptrace_get_syscall_info_supported && + ptrace_sci.op <= PTRACE_SYSCALL_INFO_SECCOMP; +} + #define XLAT_MACROS_ONLY # include "xlat/nt_descriptor_types.h" #undef XLAT_MACROS_ONLY #define ARCH_MIGHT_USE_SET_REGS 1 + #include "arch_regs.c" #if HAVE_ARCH_GETRVAL2 @@ -1035,16 +1048,13 @@ ptrace_setregs(pid_t pid) #endif /* ARCH_REGS_FOR_GETREGSET || ARCH_REGS_FOR_GETREGS */ -#ifdef ptrace_getregset_or_getregs -static long get_regs_error; -#endif +static long get_regs_error = -1; void clear_regs(struct tcb *tcp) { -#ifdef ptrace_getregset_or_getregs + ptrace_sci.op = 0xff; get_regs_error = -1; -#endif } static long @@ -1139,9 +1149,59 @@ free_sysent_buf(void *ptr) free(ptr); } +static bool +ptrace_get_syscall_info(struct tcb *tcp) +{ + /* + * ptrace_get_syscall_info_supported should have been checked + * by the caller. + */ + if (ptrace_sci.op == 0xff) { + const size_t size = sizeof(ptrace_sci); + if (ptrace(PTRACE_GET_SYSCALL_INFO, tcp->pid, + (void *) size, &ptrace_sci) < 0) { + get_regs_error = -2; + return false; + } +#if SUPPORTED_PERSONALITIES > 1 + int newpers = get_personality_from_syscall_info(&ptrace_sci); + if (newpers >= 0) + update_personality(tcp, newpers); +#endif + } + + if (entering(tcp)) { + if (ptrace_sci.op == PTRACE_SYSCALL_INFO_EXIT) { + error_msg("pid %d: entering" + ", ptrace_syscall_info.op == %u", + tcp->pid, ptrace_sci.op); + /* TODO: handle this. */ + } + } else { + if (ptrace_sci.op == PTRACE_SYSCALL_INFO_ENTRY) { + error_msg("pid %d: exiting" + ", ptrace_syscall_info.op == %u", + tcp->pid, ptrace_sci.op); + /* TODO: handle this. */ + } + } + + return true; +} + bool get_instruction_pointer(struct tcb *tcp, kernel_ulong_t *ip) { + if (get_regs_error < -1) + return false; + + if (ptrace_get_syscall_info_supported) { + if (!ptrace_get_syscall_info(tcp)) + return false; + *ip = (kernel_ulong_t) ptrace_sci.instruction_pointer; + return true; + } + #if defined ARCH_PC_REG if (get_regs(tcp) < 0) return false; @@ -1159,6 +1219,16 @@ get_instruction_pointer(struct tcb *tcp, kernel_ulong_t *ip) bool get_stack_pointer(struct tcb *tcp, kernel_ulong_t *sp) { + if (get_regs_error < -1) + return false; + + if (ptrace_get_syscall_info_supported) { + if (!ptrace_get_syscall_info(tcp)) + return false; + *sp = (kernel_ulong_t) ptrace_sci.stack_pointer; + return true; + } + #if defined ARCH_SP_REG if (get_regs(tcp) < 0) return false; @@ -1173,6 +1243,18 @@ get_stack_pointer(struct tcb *tcp, kernel_ulong_t *sp) #endif } +static int +get_syscall_regs(struct tcb *tcp) +{ + if (get_regs_error != -1) + return get_regs_error; + + if (ptrace_get_syscall_info_supported) + return ptrace_get_syscall_info(tcp) ? 0 : get_regs_error; + + return get_regs(tcp); +} + /* * Returns: * 0: "ignore this ptrace stop", syscall_entering_decode() should return a "bail @@ -1184,12 +1266,23 @@ get_stack_pointer(struct tcb *tcp, kernel_ulong_t *sp) int get_scno(struct tcb *tcp) { - if (get_regs(tcp) < 0) + if (get_syscall_regs(tcp) < 0) return -1; - int rc = arch_get_scno(tcp); - if (rc != 1) - return rc; + if (ptrace_syscall_info_is_valid()) { + /* + * So far it's just a workaround for x32, + * but let's pretend it could be used elsewhere. + */ + int rc = arch_check_scno(tcp); + if (rc != 1) + return rc; + tcp->scno = ptrace_sci.entry.nr; + } else { + int rc = arch_get_scno(tcp); + if (rc != 1) + return rc; + } tcp->scno = shuffle_scno(tcp->scno); @@ -1229,11 +1322,22 @@ get_scno(struct tcb *tcp) static int get_syscall_args(struct tcb *tcp) { + if (ptrace_syscall_info_is_valid()) { + for (unsigned int i = 0; i < ARRAY_SIZE(tcp->u_arg); ++i) + tcp->u_arg[i] = ptrace_sci.entry.args[i]; +#if SUPPORTED_PERSONALITIES > 1 + if (tcp->s_ent->sys_flags & COMPAT_SYSCALL_TYPES) { + for (unsigned int i = 0; i < ARRAY_SIZE(tcp->u_arg); ++i) + tcp->u_arg[i] = (uint32_t) tcp->u_arg[i]; + } +#endif + return 1; + } return arch_get_syscall_args(tcp); } #ifdef ptrace_getregset_or_getregs -# define get_syscall_result_regs get_regs +# define get_syscall_result_regs get_syscall_regs #else static int get_syscall_result_regs(struct tcb *); #endif @@ -1259,8 +1363,18 @@ get_syscall_result(struct tcb *tcp) static void get_error(struct tcb *tcp, const bool check_errno) { - tcp->u_error = 0; - arch_get_error(tcp, check_errno); + if (ptrace_syscall_info_is_valid()) { + if (ptrace_sci.exit.is_error) { + tcp->u_rval = -1; + tcp->u_error = -ptrace_sci.exit.rval; + } else { + tcp->u_error = 0; + tcp->u_rval = ptrace_sci.exit.rval; + } + } else { + tcp->u_error = 0; + arch_get_error(tcp, check_errno); + } } static void @@ -1271,12 +1385,22 @@ set_error(struct tcb *tcp, unsigned long new_error) if (new_error == old_error || new_error > MAX_ERRNO_VALUE) return; +#ifdef ptrace_setregset_or_setregs + /* if we are going to invoke set_regs, call get_regs first */ + if (get_regs(tcp) < 0) + return; +#endif + tcp->u_error = new_error; if (arch_set_error(tcp)) { tcp->u_error = old_error; /* arch_set_error does not update u_rval */ } else { - get_error(tcp, !(tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS)); + if (ptrace_syscall_info_is_valid()) + tcp->u_rval = -1; + else + get_error(tcp, !(tcp->s_ent->sys_flags & + SYSCALL_NEVER_FAILS)); } } @@ -1285,16 +1409,27 @@ set_success(struct tcb *tcp, kernel_long_t new_rval) { const kernel_long_t old_rval = tcp->u_rval; +#ifdef ptrace_setregset_or_setregs + /* if we are going to invoke set_regs, call get_regs first */ + if (get_regs(tcp) < 0) + return; +#endif + tcp->u_rval = new_rval; if (arch_set_success(tcp)) { tcp->u_rval = old_rval; - /* arch_set_error does not update u_error */ + /* arch_set_success does not update u_error */ } else { - get_error(tcp, !(tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS)); + if (ptrace_syscall_info_is_valid()) + tcp->u_error = 0; + else + get_error(tcp, !(tcp->s_ent->sys_flags & + SYSCALL_NEVER_FAILS)); } } #include "get_scno.c" +#include "check_scno.c" #include "set_scno.c" #include "get_syscall_args.c" #ifndef ptrace_getregset_or_getregs diff --git a/tests/Makefile.am b/tests/Makefile.am index b784f21a..1f0e5a9c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -228,6 +228,7 @@ DECODER_TESTS = \ fadvise64.test \ futex.test \ getuid.test \ + int_0x80.test \ ioctl.test \ ioctl_evdev-success.test \ ioctl_evdev-success-v.test \ @@ -347,8 +348,6 @@ TESTS = $(GEN_TESTS) $(DECODER_TESTS) $(MISC_TESTS) $(STACKTRACE_TESTS) XFAIL_TESTS_ = XFAIL_TESTS_m32 = $(STACKTRACE_TESTS) XFAIL_TESTS_mx32 = $(STACKTRACE_TESTS) -XFAIL_TESTS_x86_64 = int_0x80.gen.test -XFAIL_TESTS_x32 = int_0x80.gen.test XFAIL_TESTS = $(XFAIL_TESTS_$(MPERS_NAME)) $(XFAIL_TESTS_$(ARCH)) TEST_LOG_COMPILER = env diff --git a/tests/gen_tests.in b/tests/gen_tests.in index b77a36af..31a06274 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -118,7 +118,6 @@ inet-cmsg -e trace=recvmsg init_module -a27 inotify -a23 -e trace=inotify_add_watch,inotify_rm_watch inotify_init1 -a27 -int_0x80 -a11 -e trace=getgid32 ioctl_block +ioctl.test ioctl_dm +ioctl.test -s9 ioctl_dm-v +ioctl.test -v -s9 diff --git a/tests/int_0x80.test b/tests/int_0x80.test new file mode 100755 index 00000000..1188d983 --- /dev/null +++ b/tests/int_0x80.test @@ -0,0 +1,11 @@ +#!/bin/sh +# +# Check decoding of int 0x80 on x86_64, x32, and x86. + +. "${srcdir=.}/init.sh" + +$STRACE -d -enone / > /dev/null 2> "$LOG" +grep -x "[^:]*strace: PTRACE_GET_SYSCALL_INFO works" "$LOG" > /dev/null || + skip_ 'PTRACE_GET_SYSCALL_INFO does not work' + +run_strace_match_diff -a11 -e trace=getgid32