451 Commits

Author SHA1 Message Date
326b98927a defs.h: stop including <asm/unistd.h>
Limit the number of files where <asm/unistd.h> is included
to only those few that need it.

* defs.h: Do not include <asm/unistd.h>.
* clone.c: Include <asm/unistd.h>.
* strace.c: Likewise.
* syscall.c: Likewise.
* util.c: Likewise.
2016-12-31 22:12:08 +00:00
Seraphime Kirkovski
a864a32a76 Implement signal injection
This extends the fault injection capability with :signal=SIG option
which injects a signal on entering each syscall from the specified set.

:signal and :error options are complementary, if they are both specified
the syscall will be fault injected as usual and the specified signal
will be delivered to the tracee.

* defs.h (struct fault_opts): Change the type of err field to int16_t,
add signo field.
(trace_syscall): Add a pointer argument.
* qualify.c: Include "nsig.h".
(parse_fault_token): Handle signal= option.
(qualify_fault): Update default fault_opts.
* strace.c (trace): Forward signal number from trace_syscall
to ptrace_restart(PTRACE_SYSCALL).
* syscall.c (inject_syscall_fault_entering): Add pointer argument,
save there the signal number specified by fault options.  Do not inject
a syscall fault unless instructed by fault options.
(update_syscall_fault_exiting): Update the error code injection check.
(trace_syscall_entering): Add pointer argument, forward it to
inject_syscall_fault_entering.
(trace_syscall): Add pointer argument, forward it to
trace_syscall_entering.

Signed-off-by: Seraphime Kirkovski <kirkseraph@gmail.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
2016-12-28 18:33:28 +00:00
5a25466437 Move NSIG ifdefery to a separate header file
* nsig.h: New file.
* Makefile.am (strace_SOURCES): Add it.
* signal.c: Include "nsig.h" instead of <signal.h>, remove
NSIG workarounds.
* sigreturn.c: Likewise.
* syscall.c: Likewise.
* tests/pselect6.c: Likewise.
2016-12-27 23:18:21 +00:00
f91679316b Introduce ANY_WORDSIZE_LESS_THAN_KERNEL_LONG macro
* defs.h (ANY_WORDSIZE_LESS_THAN_KERNEL_LONG): New macro.
(truncate_klong_to_current_wordsize,
truncate_kulong_to_current_wordsize): Use it.
* mem.c (SYS_FUNC(old_mmap)): Likewise.
* util.c (umoven, umovestr, dumpiov_upto): Likewise.
* syscall.c (trace_syscall_exiting): Likewise.
2016-12-27 01:08:58 +00:00
a1e94e9c7a Remove HAVE_STRUCT_TCB_EXT_ARG, ext_arg, and u_lrval
After transition from long to kernel_ulong_t these fields
are no longer needed.

* defs.h (HAVE_STRUCT_TCB_EXT_ARG): Remove.
(struct tcb) [HAVE_STRUCT_TCB_EXT_ARG]: Remove.
[HAVE_STRUCT_TCB_EXT_ARG]: Remove.
(RVAL_MASK): Update.
* io.c (print_lld_from_low_high_val): Check
[SIZEOF_KERNEL_LONG_T > SIZEOF_LONG]
instead of [HAVE_STRUCT_TCB_EXT_ARG].
Use u_arg instead of ext_arg.
* linux/mips/get_error.c (get_error) [LINUX_MIPSN32]: Remove.
* linux/mips/get_syscall_args.c (get_syscall_args) [LINUX_MIPSN32]:
Remove.
[LINUX_MIPSN64]: Extend to [LINUX_MIPSN32].
* linux/x86_64/get_error.c (get_error) [X32]: Remove.
* linux/x86_64/get_syscall_args.c (get_syscall_args) [X32]: Remove.
* lseek.c: Check [SIZEOF_KERNEL_LONG_T > SIZEOF_LONG]
instead of [HAVE_STRUCT_TCB_EXT_ARG].
[SIZEOF_KERNEL_LONG_T > SIZEOF_LONG] (SYS_FUNC(lseek)): Use u_arg
instead of ext_arg.  Use RVAL_UDECIMAL instead of RVAL_LUDECIMAL.
* mem.c (SYS_FUNC(mmap)): Pass offset syscall argument directly
to print_mmap.
* syscall.c (trace_syscall_exiting) [HAVE_STRUCT_TCB_EXT_ARG]: Remove.
* times.c (SYS_FUNC(times)): Use RVAL_UDECIMAL instead
of RVAL_LUDECIMAL.
* util.c (getllval): Check [SIZEOF_KERNEL_LONG_T > SIZEOF_LONG]
instead of [HAVE_STRUCT_TCB_EXT_ARG].  Use u_arg instead of ext_arg.
2016-12-26 10:43:35 +00:00
89636759d7 Automatically replace PRI_kr[dux] with PRI_kl[dux]
Remove temporary macros created for transition from long
to kernel_ulong_t.

Automatically replace PRI_kr[dux] with PRI_kl[dux] using
$ git grep -l 'PRI_kr[dux]' | xargs sed -ri 's/PRI_kr([dux])/PRI_kl\1/g'

* defs.h (PRI_krd, PRI_kru, PRI_krx): Remove.  All users updated.
2016-12-26 10:43:34 +00:00
7fa3d78319 Automatically replace kernel_(scno|ureg)_t with kernel_ulong_t
Remove temporary types created for transition from long
to kernel_ulong_t.

Automatically replace kernel_scno_t and kernel_ureg_t with
kernel_ulong_t using
$ git grep -El 'kernel_(scno|ureg)_t' |
  xargs sed -ri 's/kernel_(scno|ureg)_t/kernel_ulong_t/g'

* kernel_types.h (kernel_scno_t, kernel_ureg_t): Remove.
All users updated.
2016-12-26 10:43:34 +00:00
1d5bb61c49 Print kernel_ureg_t and kernel_scno_t using dedicated format strings
Prepare for the change of kernel_ureg_t and kernel_scno_t from
unsigned long to kernel_ulong_t.

* defs.h (PRI_krd, PRI_kru, PRI_krx): New temporary macros.
All users updated.
2016-12-26 10:43:04 +00:00
9cd050573c trace_syscall_exiting: prepare personality check for u_rval type change
* syscall.c (trace_syscall_exiting): Check for sizeof(tcp->u_rval)
instead of sizeof(long) when deciding how to print tcp->u_rval.
2016-12-26 10:08:53 +00:00
0eda4a0a4b upeek, upoke: change argument types from long to unsigned long
* defs.h (upeek, upoke): Change offset argument type from long
to unsigned long.  Change res argument type from long to kernel_ureg_t.
* upeek.c (upeek): Likewise.
* upoke.c (upoke.c): Likewise.
* syscall.c (print_pc) [ARCH_PC_PEEK_ADDR]: Change pc type from long
to kernel_ureg_t.
* linux/aarch64/arch_regs.c (arm_sp_ptr): Remove redundant cast.
* linux/metag/get_syscall_args.c (get_syscall_args): Likewise.
* linux/sh/get_syscall_result.c (get_syscall_result_regs): Likewise.
* linux/sh64/get_syscall_result.c (get_syscall_result_regs): Likewise.
* linux/powerpc/getregs_old.c (getregs_old): Remove redundant casts.
* linux/alpha/arch_getrval2.c (getrval2): Change r20 type from long
to unsigned long.
* linux/alpha/arch_regs.c (alpha_r0, alpha_a3): Change type from long
to unsigned long.
* linux/bfin/arch_regs.c (bfin_r0): Likewise.
* linux/crisv10/arch_regs.c (cris_r10): Likewise.
* linux/hppa/arch_regs.c (hppa_r28): Likewise.
* linux/ia64/arch_regs.c (IA64_PSR_IS): Likewise.
* linux/microblaze/arch_regs.c (microblaze_r3): Likewise.
* linux/sh/arch_regs.c (sh_r0): Likewise.
* linux/sh64/arch_regs.c (sh64_r9): Likewise.
* linux/xtensa/arch_regs.c (xtensa_a2): Likewise.
* linux/alpha/arch_sigreturn.c (arch_sigreturn): Change addr type
from long to unsigned long.
* linux/microblaze/arch_sigreturn.c (arch_sigreturn): Likewise.
* linux/alpha/get_scno.c (arch_get_scno): Update for the change
of signedness.
* linux/arc/get_syscall_args.c (get_syscall_args): Change arc_args type
from pointer to long to pointer to unsigned long.
* linux/arm/arch_regs.c (arm_sp_ptr): Change type from pointer to long
to pointer to unsigned long.
* linux/arm/arch_regs.h (arm_sp_ptr): Likewise.
* linux/i386/arch_regs.c (i386_esp_ptr): Likewise.
* linux/i386/arch_regs.h (i386_esp_ptr): Likewise.
* linux/m68k/arch_regs.c (m68k_usp_ptr): Likewise.
* linux/m68k/arch_regs.h (m68k_usp_ptr): Likewise.
* linux/ia64/get_syscall_args.c (get_syscall_args): Use umove
instead of umoven.
* linux/sh/arch_getrval2.c (getrval2): Change val type from long
to unsigned long.
2016-12-25 20:14:12 +00:00
121e148978 msghdr: change register based size types from unsigned long to kernel_ureg_t
* defs.h (dumpiov_in_msghdr): Change data_size argument type
from unsigned long to kernel_ureg_t.
* msghdr.h (print_struct_msghdr): Likewise.
* msghdr.c (print_struct_msghdr): Likewise.  Cast msghdr.msg_iovlen
and msghdr.msg_controllen to kernel_ureg_t instead of unsigned long.
(decode_msghdr, dumpiov_in_msghdr): Change data_size argument type
from unsigned long to kernel_ureg_t.
(SYS_FUNC(sendmsg)): Pass -1 instead of -1UL as data_size argument
to decode_msghdr.
* mmsghdr.c (print_struct_mmsghdr): Pass (kernel_ureg_t) -1 instead
of -1UL as data_size argument to print_struct_msghdr.
(dumpiov_in_mmsghdr): Cast msghdr.msg_iovlen to kernel_ureg_t instead
of unsigned long.
* syscall.c (dumpio): Pass -1 instead of -1UL as data_size argument
to dumpiov_in_msghdr
2016-12-25 11:32:45 +00:00
73be1d7e2e Remove dumpiov wrapper
* defs.h (dumpiov): Remove.
* syscall.c (dumpio): Use dumpiov_upto instead of dumpiov.
2016-12-21 22:25:30 +00:00
6a360e2f3e x32: implement automatic argument truncation for compat syscalls
x32 syscalls starting with number 512 are compat syscalls that operate
on compat types.  Set COMPAT_SYSCALL_TYPES flag to these syscall entries
and make get_syscall_args truncate arguments of syscalls that have this
flag set, to avoid unpleasant alternative of adding multiple
widen_to_ulong invocations to individual syscall parsers.

preadv, pwritev, preadv2, and pwritev2 are exceptions: while these
syscalls operate on compat types, the offset argument has a regular
64-bit type, so the automatic argument truncation cannot be applied.

* defs.h (COMPAT_SYSCALL_TYPES): New macro.
* syscall.c (CST): New macro, defined to COMPAT_SYSCALL_TYPES.
* linux/ia64/syscallent.h: Do not include "../i386/syscallent.h"
unless [CST > 0].
* linux/x32/syscallent.h [512..533, 536..545]: Add CST flag.
* linux/x86_64/get_syscall_args.c (get_syscall_args): Truncate arguments
of compat syscalls to 32-bit values.
* tests/ksysent.c (CST): New macro, defined to 0.
* tests/nsyscalls.c (CST): Likewise.
2016-12-20 05:10:21 +00:00
b3d82da686 Check for current_klongsize instead of current_personality where appropriate
current_klongsize checks are more universal, therefore they are usually
shorter and easier to comprehend.

* desc.c (umove_kulong_array_or_printaddr): Check for current_klongsize
instead of current_personality and current_wordsize.
* io.c (print_lld_from_low_high_val): Likewise.
* lseek.c (SYS_FUNC(lseek)): Likewise.
* resource.c (decode_rlimit): Likewise.
* syscall.c (is_negated_errno): Likewise.
* util.c (getllval, getarg_klu): Likewise.
2016-12-19 19:58:16 +00:00
Eugene Syromyatnikov
1fe5d9bed5 Introduce current_klongsize in addition to current_wordsize
Subsequent commits are going to use current_klongsize
as the tracee's size of kernel_ulong_t type.

* defs.h (PERSONALITY0_KLONGSIZE): New macro.
[X86_64] (PERSONALITY2_KLONGSIZE): Likewise.
[SUPPORTED_PERSONALITIES > 1] (PERSONALITY1_KLONGSIZE): Likewise.
[SUPPORTED_PERSONALITIES == 1] (current_klongsize): Likewise.
[SUPPORTED_PERSONALITIES == 2 && PERSONALITY0_KLONGSIZE ==
PERSONALITY1_KLONGSIZE] (current_klongsize): Likewise.
[SUPPORTED_PERSONALITIES != 1 && (SUPPORTED_PERSONALITIES != 2 ||
PERSONALITY0_KLONGSIZE != PERSONALITY1_KLONGSIZE)] (current_klongsize):
New variable prototype.
* syscall.c [!current_klongsize] (current_klongsize): New variable.
[!current_klongsize] (personality_klongsize): New array.
(set_personality) [!current_klongsize]: Update current_klongsize
with the appropriate value from personality_klongsize.
2016-12-19 14:39:48 +00:00
0547dc1ad5 Change scno type from long to unsigned long
Use an unsigned type for syscall numbers as they are not intended
for signed arithmetics.  Introduce kernel_scno_t as a typedef
to unsigned long, that could be changed later to kernel_ulong_t.

* kernel_types.h (kernel_scno_t): New type, typedef to unsigned long.
* defs.h (struct tcb): Change type of scno field from long
to kernel_scno_t.
(syscall_name): Change argument type from long to kernel_scno_t.
(scno_in_range, scno_is_valid): Change argument type from unsigned long
to kernel_scno_t.
* linux/aarch64/set_scno.c (arch_set_scno): Change scno argument type
from long to kernel_scno_t.
* linux/alpha/set_scno.c (arch_set_scno): Likewise.
* linux/arc/set_scno.c (arch_set_scno): Likewise.
* linux/arm/set_scno.c (arch_set_scno): Likewise.
* linux/avr32/set_scno.c (arch_set_scno): Likewise.
* linux/bfin/set_scno.c (arch_set_scno): Likewise.
* linux/crisv10/set_scno.c (arch_set_scno): Likewise.
* linux/hppa/set_scno.c (arch_set_scno): Likewise.
* linux/i386/set_scno.c (arch_set_scno): Likewise.
* linux/ia64/set_scno.c (arch_set_scno): Likewise.
* linux/m68k/set_scno.c (arch_set_scno): Likewise.
* linux/metag/set_scno.c (arch_set_scno): Likewise.
* linux/microblaze/set_scno.c (arch_set_scno): Likewise.
* linux/mips/set_scno.c (arch_set_scno): Likewise.
* linux/nios2/set_scno.c (arch_set_scno): Likewise.
* linux/or1k/set_scno.c (arch_set_scno): Likewise.
* linux/powerpc/set_scno.c (arch_set_scno): Likewise.
* linux/riscv/set_scno.c (arch_set_scno): Likewise.
* linux/s390/set_scno.c (arch_set_scno): Likewise.
* linux/sh/set_scno.c (arch_set_scno): Likewise.
* linux/sh64/set_scno.c (arch_set_scno): Likewise.
* linux/sparc/set_scno.c (arch_set_scno): Likewise.
* linux/tile/set_scno.c (arch_set_scno): Likewise.
* linux/x86_64/set_scno.c (arch_set_scno): Likewise.
* linux/xtensa/set_scno.c (arch_set_scno): Likewise.
* linux/aarch64/get_scno.c (arch_get_scno): Change scno variable type
from long to kernel_scno_t.
* linux/alpha/get_scno.c (arch_get_scno): Likewise.
* linux/arm/get_scno.c (arch_get_scno): Likewise.
* linux/sh/get_scno.c (arch_get_scno): Likewise.
* linux/x86_64/get_scno.c (arch_get_scno): Likewise.
* syscall.c (arch_set_scno): Likewise.
(shuffle_scno): Change return type from long to kernel_scno_t.
(syscall_name): Change argument type from long to kernel_scno_t.
2016-12-18 22:57:57 +00:00
ae39bba347 Lowercase SCNO_IN_RANGE and SCNO_IS_VALID
* defs.h (SCNO_IN_RANGE): Rename to scno_in_range.  All callers updated.
(SCNO_IS_VALID): Rename to scno_is_valid.  All callers updated.
2016-12-18 22:57:57 +00:00
f0ba3723f5 Replace "(unsigned long) -1L" with -1UL
* defs.h (dumpiov): Replace "(unsigned long) -1L" with -1UL.
* io.c (print_iovec, tprint_iov): Likewise.
* msghdr.c (SYS_FUNC(sendmsg)): Likewise.
* syscall.c (dumpio): Likewise.
* poll.c (decode_poll_exiting): Replace "(unsigned int) -1" with -1U.
2016-12-18 14:09:51 +00:00
f55ef46feb Include "kernel_types.h" in defs.h and tests/tests.h
As kernel_ulong_t type is going to be used in the definition
of struct tcb and in many function prototypes, make it readily
available for every source file by including "kernel_types.h"
in defs.h and tests/tests.h files.

* defs.h: Include "kernel_types.h".
* tests/tests.h: Likewise.
* desc.c: Do not include "kernel_types.h".
* dirent.c: Likewise.
* keyctl.c: Likewise.
* syscall.c: Likewise.
* linux/asm_stat.h: Likewise.
* tests/answer.c: Likewise.
* tests/epoll_pwait.c: Likewise.
* tests/fanotify_init.c: Likewise.
* tests/fanotify_mark.c: Likewise.
* tests/file_handle.c: Likewise.
* tests/ftruncate.c: Likewise.
* tests/getdents.c: Likewise.
* tests/init_delete_module.h: Likewise.
* tests/inotify.c: Likewise.
* tests/inotify_init1.c: Likewise.
* tests/ioprio.c: Likewise.
* tests/ipc_msgbuf.c: Likewise.
* tests/kcmp.c: Likewise.
* tests/kexec_file_load.c: Likewise.
* tests/kexec_load.c: Likewise.
* tests/keyctl.c: Likewise.
* tests/lookup_dcookie.c: Likewise.
* tests/lseek.c: Likewise.
* tests/mq_sendrecv.c: Likewise.
* tests/nsyscalls.c: Likewise.
* tests/pkey_alloc.c: Likewise.
* tests/pkey_free.c: Likewise.
* tests/pkey_mprotect.c: Likewise.
* tests/prctl-pdeathsig.c: Likewise.
* tests/prctl-tsc.c: Likewise.
* tests/preadv2-pwritev2.c: Likewise.
* tests/process_vm_readv_writev.c: Likewise.
* tests/read-write.c: Likewise.
* tests/setfsugid.c: Likewise.
* tests/setns.c: Likewise.
* tests/truncate.c: Likewise.
* tests/unshare.c: Likewise.
* tests/xgetrlimit.c: Likewise.
2016-12-16 12:01:44 +00:00
45ed340016 Rewrite remaining qual_* parsers using bit sets
* defs.h (struct fault_opts): Replace forward declaration
with a definition.
(qualbits_t, qualify_read, qualify_write, qualify_signals): Remove.
(qual_flags): New function prototype.
(nsyscall_vec, sysent_vec, fault_vec): New variable prototypes.
* qualify.c (abbrev_set, fault_set, raw_set, trace_set, verbose_set):
New variables.
(qualify_read, qualify_write, qualify_signals): Add static qualifier.
(find_errno_by_name, lookup_class, parse_fault_expression,
parse_fault_token, qual_flags, qualify, qualify_abbrev, qualify_fault,
qualify_raw, qualify_syscall, qualify_syscall_class,
qualify_syscall_name, qualify_syscall_number, qualify_syscall_tokens,
qualify_trace, qualify_verbose, strip_prefix): New functions.
* syscall.c (nsyscall_vec, nsysent_vec): Remove static qualifier.
(MAX_NSYSCALLS1, MAX_NSYSCALLS2, MAX_NSYSCALLS, qual_vec, qual_flags,
qual_fault, qual_syscall, qual_options, fault_opts, qualify_one,
qualify_scno, lookup_class, qualify_syscall_class, qualify_syscall_name,
qual_syscall_ex, qual_syscall, strip_prefix, find_errno_by_name,
parse_fault_token, parse_fault_expression, qual_fault, qualify): Remove.
(decode_socket_subcall, decode_ipc_subcall, decode_mips_subcall,
get_scno): Update use of qual_flags.
(inject_syscall_fault_entering): Update per-personality allocation
of tcp->fault_vec.
* tests/fault_injection-exit_group.test: Check parsing of inversed
fault sets.
* tests/fault_injection.test: Check parsing of -efault=none.
* tests/options-syntax.test: Check parsing of invalid syscall numbers.
2016-12-05 20:49:59 +00:00
701792d70c Change qual_vec/qual_fault into static fixed size arrays
* defs.h (qual_vec, num_quals): Remove.
(qual_flags): Move ...
* syscall.c: ... here.
(num_quals, num_faults, MIN_QUALS, reallocate_vec, reallocate_qual,
reallocate_fault): Remove.
(qual_vec, qual_fault): Change into static fixed size arrays.
(qualify_one): Remove reallocate_qual and reallocate_fault calls.
(qualify): Likewise.  Replace num_quals and num_faults with
MAX_NSYSCALLS.
2016-12-05 20:49:59 +00:00
11abfb422a Rewrite qual_signal using bit sets
* defs.h (signal_set): New variable prototypes.
(qualify_signals): New function prototypes.
(QUAL_SIGNAL): Change to a value greater than 0xff.
(QUAL_FAULT): Change to a lower value.
* qualify.c (signal_set): New variable.
(sigstr_to_uint, qualify_signals): New functions.
* syscall.c (qual_signal): Remove.
(qual_options): Replace qual_signal with NULL.
(qualify): Use qualify_signals.
* strace.c (print_signalled, print_stopped): Use is_number_in_set
with signal_set argument.
2016-12-05 20:49:59 +00:00
05ac490cc7 Rewrite qual_desc using bit sets
As a side effect, this also fixes support of negated sets
of descriptors.

* defs.h (struct number_set): New forward declaration.
(read_set, write_set): New variable prototypes.
(is_number_in_set, qualify_read, qualify_write): New function
prototypes.
(QUAL_READ, QUAL_WRITE): Change to values greater than 0xff.
* qualify.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* syscall.c (qual_desc): Remove.
(qual_options): Replace qual_desc with NULL.
(qualify): Use qualify_read and qualify_write.
(dumpio): Use is_number_in_set.
* tests/options-syntax.test: Check invalid sets of descriptors.
* tests/readv.test: Check dumping of negated sets of descriptors.
2016-12-05 10:41:05 +00:00
3c8b673408 syscall_name: clear __X32_SYSCALL_BIT from syscall number on x32
* linux/x86_64/get_scno.c (X32_PERSONALITY_NUMBER): New macro.
* syscall.c (syscall_name) [X32_PERSONALITY_NUMBER && __X32_SYSCALL_BIT]:
Clear __X32_SYSCALL_BIT from scno on x32 personality.
2016-12-01 01:05:13 +00:00
Eugene Syromyatnikov
9936b91d9f Print syscall names only for defined syscalls
The string literal "__NR_syscall_4294967295" is semantically incorrect
as there is no such constant defined.

* syscall.c (syscall_name): Return NULL if there is no syscall
corresponding to the given number.
* defs.h (syscall_name): Document this behaviour.
* printsiginfo.c (print_si_info): Print syscall name with "__NR_" prefix
only if there is a syscall corresponding to si_syscall number; print
a plain syscall number otherwise.
* tests/ptrace.c (main): Update expected output.
2016-12-01 00:08:39 +00:00
ec8f783356 syscall: Simplify strip_prefix
* syscall.c (strip_prefix): Use strncmp instead of strlen+memcmp.
2016-11-30 16:52:28 +00:00
1c599b4f3d dumpio: remove useless check
* syscall.c (dumpio): Remove SEN_printargs check.  Use tcp->s_ent->sen
directly.
2016-11-30 00:04:03 +00:00
07586a5b64 Fix dumping of io syscalls when descriptor argument has unused bits set
* syscall.c (dumpio): Explicitly cast the first argument of syscall
to "int", the same way as the kernel does.
* tests/read-write.c: Include <asm/unistd.h> and "kernel_types.h".
(k_read, k_write): New functions.
(test_dump, main): Use them.
2016-11-29 22:56:49 +00:00
4399fa976a Fix meaning of negated sets in fault expressions
Change the parser of fault expression to follow the POLA:
-e fault=!SET
means that all syscalls except those from SET are subject to fault
injection;
-e fault=!SET1:error=ERRNO1, -e fault=!SET2:error=ERRNO2
means that all syscalls except those from SET2 are subject to fault
injection with error code ERRNO2, and all syscalls from SET2 that are
not in SET1 are subject to fault injection with error code ERRNO1.

* syscall.c (qualify_scno, qualify_syscall_class, qualify_syscall_name):
Handle negated QUAL_FAULT case differently.
* tests/fault_syntax.test: Add checks of negated sets.
2016-11-29 02:11:48 +00:00
2f948b9231 Set PTRACE_O_TRACEEXIT option and handle PTRACE_EVENT_EXIT events
Do not assume that some syscalls do not generate syscall-exit-stops.
When syscalls fail for any reason they may generate syscall-exit-stops.

The solution is to wait for an actual exit reported by PTRACE_EVENT_EXIT
and print the end of unfinished exiting syscall properly.

* exit.c: Remove.
* Makefile.am (strace_SOURCES): Remove exit.c.
* linux/dummy.h (sys_exit): Alias to printargs_d.
* strace.c (ptrace_setoptions): Add PTRACE_O_TRACEEXIT bit.
(print_event_exit): New function.
(trace): Use it in case of PTRACE_EVENT_EXIT.
* syscall.c (trace_syscall_entering): Remove special handling
of SEN_exit.
2016-11-27 14:22:58 +00:00
0c836eb060 Restrain from fault injection while the trace executes strace code
There is little use in injections of faults into syscalls made by strace.

* syscall.c (trace_syscall_entering): Clear QUAL_FAULT bit from
tcp->qual_flg when tcp->flags has TCB_HIDE_LOG bit set.
2016-11-26 20:54:01 +00:00
634a6a55e8 Move two global flags to tracee scope
A simultaneous use of -p option and tracing of a command available
since commit v4.11-183-gfa8c286 introduces a race condition because
the flags whether the first exec has happened are global.

Fix the race by moving hide_log_until_execve and hide_log_until_execve
global variables to TCB_HIDE_LOG and TCB_SKIP_DETACH_ON_FIRST_EXEC bits
in struct tcb.flags, correspondingly.

* defs.h (TCB_HIDE_LOG, TCB_SKIP_DETACH_ON_FIRST_EXEC, hide_log):
New macros.
(hide_log_until_execve): Remove prototype.
* strace.c (skip_one_b_execve, hide_log_until_execve): Remove.
(startup_child): Set TCB_HIDE_LOG and TCB_SKIP_DETACH_ON_FIRST_EXEC bits
in the allocated tcb structure.
(init): Remove initialization of hide_log_until_execve and
skip_one_b_execve.
(print_stopped): Use hide_log() instead of hide_log_until_execve.
(trace): Check and clear TCB_SKIP_DETACH_ON_FIRST_EXEC flag instead
of skip_one_b_execve.
* syscall.c (trace_syscall_entering): Clear TCB_HIDE_LOG flag instead of
hide_log_until_execve.
(trace_syscall_entering, trace_syscall_exiting): Check hide_log()
instead of hide_log_until_execve.
2016-11-26 19:47:38 +00:00
7910ac9638 Treat execveat as an execve family syscall
* syscall.c (trace_syscall_entering): Clear hide_log_until_execve flag
also when SEN_execveat is encountered.
2016-11-26 16:08:10 +00:00
d5b9c75d61 Change parser of fault expressions to conform the documentation
Make expressions like fault=SYSCALL1,SYSCALL2:error=EPERM work
as documented, i.e. fail both SYSCALL1 and SYSCALL2 with EPERM.

* syscall.c (parse_fault_expression): Remove const qualifier from
"name" and "token: variables, as well as from the return value.
(qual_fault): Remove const qualifier from "name" variables.
Split "name" into comma delimited tokens and pass each token
to individual qual_syscall_ex call.
(qualify): For QUAL_FAULT options, pass the whole option value
to their qualify methods without prior splitting into comma
delimited tokens.
* tests/fault_injection.test: Check it.
* tests/fault_syntax.test: Check empty syscall sets.
2016-11-25 23:47:32 +00:00
cba0d84def Simplify parse_fault_expression
* syscall.c (parse_fault_expression): Rewrite iterator over strtok_r
in a more concise way.
2016-11-24 21:35:05 +00:00
57506ae00f Fix signame usage in qual_signal
Do not assume that the string returned by signame starts with "SIG"
prefix, this is not always the case.

* syscall.c (qual_signal): Skip signame return value
when it does not have "SIG" prefix.
2016-11-18 00:11:39 +00:00
1658e9d4c6 Make -e fault= expressions cumulative
Change the way how subsequent -e fault= expressions are interpreted
to implement a cumulative behavior.  For example,
-e fault=file:when=3+ -e fault=chdir
now specifies that all chdir syscalls and 3+ file related syscalls
except chdir are subject for fault injection.

* syscall.c (qualify): Do not reset qual_vec for QUAL_FAULT.
* tests/fault_injection.test: Check it.
2016-11-17 15:44:21 +00:00
9cb6e03d4f Implement syscall fault injection
Introduce new -e fault=EXPR syntax that can be used to specify a subset
of syscalls that are subject of syscall fault injection, an error code
that has to be injected, and a frequency of injection.

The expression specifying syscall fault injection has the following
format: SET[:error=ERRNO][:when=FIRST[+[STEP]]]
where only SET is a required part and all the rest is optional.

The method used to implement syscall fault injection is the following:
on entering syscall the syscall number is substituted by an invalid
syscall number -1, and on exiting syscall the error code returned by
the kernel is substituted with the error code specified in the fault
expression.

This implementaion is based on the prototype developed
by Nahim El Atmani as a part of his GSoC 2016 strace project.

* defs.h (struct fault_opts): New forward declaration.
(struct tcb): Add fault_vec field.
(TCB_FAULT_INJ, QUAL_FAULT): New macros.
* strace.1: Document -e fault expression syntax.
* strace.c (usage): Mention -e fault expression.
(droptcb): Deallocate fault_vec member.
* syscall.c (qual_fault, arch_set_scno, arch_set_error): New prototypes.
(qual_options): Add "fault" option.
(struct fault_opts): New structure.
(num_faults): New variable.
(fault_vec): New array.
(syscall_fault_injected, tcb_fault_opts, reallocate_fault,
find_errno_by_name, qual_syscall_ex, strip_prefix, parse_fault_token,
parse_fault_expression, qual_fault, inject_syscall_fault_entering,
update_syscall_fault_exiting): New functions.
(qual_syscall): Use qual_syscall_ex.
(qualify_one): Add argument: a pointer to struct fault_opts, all callers
changed.  Copy struct fault_opts from the pointer to fault_vec.
Use reallocate_fault.
(qualify_scno, qualify_syscall_class, qualify_syscall_name): Add
argument: a pointer to struct fault_opts.
(qualify): Use reallocate_fault.  Do not check "all" class for
QUAL_FAULT qualifier.
(lookup_class): Check for "all" class.
(trace_syscall_entering): Use inject_syscall_fault_entering.
(trace_syscall_exiting): Use update_syscall_fault_exiting.  Clear
TCB_FAULT_INJ flag along with TCB_INSYSCALL.  Print " (INJECTED)" suffix
when the syscall has been injected successfully.
[ARCH_REGS_FOR_GETREGSET && !HAVE_GETREGS_OLD]
(ptrace_setregset): New function.
(ptrace_setregset_or_setregs): Define to ptrace_setregset.
[ARCH_REGS_FOR_GETREGS && !HAVE_GETREGS_OLD]
(ptrace_setregs): New function.
(ptrace_setregset_or_setregs): Define to ptrace_setregs.
[ptrace_setregset_or_setregs] (set_regs): New function.
Include "set_scno.c" and "set_error.c"
* NEWS: Mention this enhancement.
2016-11-16 17:26:58 +00:00
081b2a821b Introduce string_to_uint_ex and string_to_uint_upto functions
* defs.h (string_to_uint_ex): New prototype.
(string_to_uint_upto): New function, a thin wrapper around
string_to_uint_ex.
* util.c (string_to_uint_ex): New function.
(string_to_uint): Change into a thin wrapper around string_to_uint_upto.
* strace.c (init): Use string_to_uint_upto.
* syscall.c (qualify_scno, qual_signal, qual_desc): Use
string_to_uint_upto instead of string_to_uint.
2016-11-16 01:41:51 +00:00
0323fa3217 Split qual_syscall into separate functions
Split qual_syscall into qualify_scno, qualify_syscall_class,
and qualify_syscall_name.
This might be needed later to implement syscall fault injection.

* syscall.c (qualify_scno, qualify_syscall_class, qualify_syscall_name):
New functions.
(qual_syscall): Use them.
2016-11-16 01:41:51 +00:00
695545a8b3 syscall.c: refactor getregs_old fallback in get_regs
This change moves remaining arch specific getregs_old code into
appropriate arch subdirectories and removes unnecessary code
duplication.

* linux/getregs_old.h: New file.
* linux/powerpc/getregs_old.h: Likewise.
* linux/powerpc64/getregs_old.h: Likewise.
* linux/x86_64/getregs_old.h: Likewise.
* Makefile.am (EXTRA_DIST): Add them.
* syscall.c: Include "getregs_old.h".
[X86_64 || POWERPC]: Remove.
[ARCH_REGS_FOR_GETREGSET] (ptrace_getregset_or_getregs): Define
to ptrace_getregset.
[ARCH_REGS_FOR_GETREGS] (ptrace_getregset_or_getregs): Define
to ptrace_getregs.
(get_regs): Check for ptrace_getregset_or_getregs instead
of ARCH_REGS_FOR_GETREGSET and ARCH_REGS_FOR_GETREGS.  Use
ptrace_getregset_or_getregs instead of ptrace_getregset and
ptrace_getregs.  Check for HAVE_GETREGS_OLD instead of X86_64
and POWERPC.  Use use_getregs_old instead of getregset_support
and old_kernel.
2016-11-13 11:16:15 +00:00
c93f39ca5b syscall.c: factor out ptrace_getregs from get_regs
Move the code that calls ptrace(PTRACE_GETREGS) to a separate function.

* syscall.c (ptrace_getregs): New function.
(get_regs): Use it.
2016-11-12 21:29:58 +00:00
1d886734c7 syscall.c: rename get_regset to ptrace_getregset
* syscall.c (get_regset): Rename to ptrace_getregset.
(get_regs): Rename get_regset to ptrace_getregset.
2016-11-12 21:29:58 +00:00
5e33997559 syscall.c: introduce reallocate_vec function
This might be needed later to implement syscall fault injection.

* syscall.c (reallocate_vec): New function.
(reallocate_qual): Use it.
2016-11-12 21:29:58 +00:00
5d2293dea6 Fix prototypes of qual_desc, qual_signal, and qual_syscall functions
* syscall.c (qual_desc, qual_signal, qual_syscall): Fix prototypes.
(struct qual_options): Fix type of "qualify" member.
2016-11-12 21:29:58 +00:00
Eugene Syromyatnikov
0277a64986 Implement dumping of mq_timedsend and mq_timedreceive syscalls
* syscall.c (dumpio): Add SEN_mq_timedreceive and SEN_mq_timedsend.
2016-10-29 02:54:02 +03:00
820adffcd9 x86_64: fix is_negated_errno for x32 personality
* syscall.c (is_negated_errno) [X86_64]: Do not truncate kernel_ulong_t
to uint32_t for x32 personality.
2016-10-03 15:51:49 +00:00
4503da0816 Use err_name, print unrecognized errno values as numbers
* syscall.c (trace_syscall_exiting): Use err_name() instead
of open-coding it.  Print unrecognized errno values using %lu format
instead of ERRNO_%lu as the latter prodices an invalid constant.
2016-10-03 12:03:03 +00:00
Eugene Syromyatnikov
6fdb10455a Add function for getting errno string
* defs.h (err_name): New prototype.
* syscall.c (err_name): New function.
2016-10-03 11:54:49 +00:00
ba63d8a166 struct tcb: change the type of u_error field from int to unsigned long
This is the type actually used for the error code on architectures
that use a dedicated register.

* defs.h (struct tcb): Change the type of u_error to unsigned long.
* syscall.c (trace_syscall_exiting): Change the type of u_error variable
to unsigned long, print it using %lu format, drop no longer needed
explicit cast to unsigned long.
(saved_u_error): Change type to unsigned long.
2016-10-03 11:48:55 +00:00