Because there are never enough print_quoted_string flags.
* defs.h (QUOTE_EMIT_COMMENT): New quoting flag macro constant.
* util.c (string_quote): Emit " /* " in the beginning and " */" in the
end if QUOTE_EMIT_COMMENT is passed.
(print_quoted_string): Increase alloc_size by 7 if QUOTE_EMIT_COMMENT is
passed.
tests: make ioctl.test more flexible, use it for the rest of ioctl tests
As the remaining non-generated ioctl tests differ from ioctl.test only
in strace options, and since gen_tests.sh can pass arguments to sourced
tests, replace the remaining non-generated ioctl tests with invocations
of ioctl.test with appropriate parameters.
* tests/ioctl.test: Pass script arguments to the strace invocation.
* tests/gen_tests.in (ioctl_dm): New entry, invoke ioctl.test with -s9.
(ioctl_dm-v): New entry, invoke ioctl.test with -v -s9.
(ioctl_kvm_run): New entry, invoke ioctl.test with -a36 -y.
(ioctl_loop-nv): New entry, invoke ioctl.test with -a22 -e verbose=none.
(ioctl_nsfs): New entry, invoke ioctl.test with -esignal=none.
(ioctl_sock_gifconf): New entry, invoke ioctl.test with -a28 -s1.
(ioctl_evdev-v, ioctl_loop-v, ioctl_rtc-v): Invoke ioctl.test
with -v option instead of ioctl-v.sh.
* tests/ioctl_dm-v.test: Remove.
* tests/ioctl_dm.test: Likewise.
* tests/ioctl_kvm_run.test: Likewise.
* tests/ioctl_loop-nv.test: Likewise.
* tests/ioctl_nsfs.test: Likewise.
* tests/ioctl_sock_gifconf.test: Likewise.
* tests/ioctl-v.sh: Likewise.
* tests/Makefile.am (DECODER_TESTS, EXTRA_DIST): Remove them.
tests/gen_tests.sh: enable passing arguments to sourced tests
* tests/gen_tests.sh: Read first argument separately, put it in $arg0,
and the rest of the arguments in $args.
(case "$arg0" in) <+*)>: Set command line to $args and source $arg0.
Dmitry V. Levin [Thu, 25 Jan 2018 01:55:08 +0000 (01:55 +0000)]
Drop non-functional CRIS architecture support
From the very first commit when CRIS architecture support was introduced
and up to this comment that ends the agony of this non-functional code,
this support was incomplete and could never be compiled.
* futex.c (VALP, VALP_PR, VAL2P, VAL2P_PR): New macro definitions.
(main): Allow EINVAL on *REQUEUE* checks with VAL/VAL2 with higher bit
being set, check that the existing behaviour preserved with VALP/VAL2P
where higher bit is unset.
We (apparently) had a long-standing test failure inside strace-ff.test
with the symptom that it misses exit_group call. As it turned out, it
was PTRACE_EVENT_EXEC followed by execve syscall exiting stop. That
behaviour indeed screwed all the syscall state tracking for the tracee.
Let's try to patch it up by calling trace_syscall when we receive
PTRACE_EVENT_EXEC outside syscall.
* defs.h (TCB_RECOVERING): New tcb flag.
* strace.c (dispatch_event) <case TE_STOP_BEFORE_EXECVE>: Invoke
trace_syscall with TCB_RECOVERING flag being set for the current_tcp
if the tracee is not on exiting syscall.
* syscall.c (get_scno): Set QUAL_RAW if we are recovering.
(tamper_with_syscall_entering): Do not perform actual tampering during
recovery as it's already too late.
* NEWS: Mention it.
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
Dmitry V. Levin [Wed, 24 Jan 2018 01:56:15 +0000 (01:56 +0000)]
tests: robustify set_ptracer_any
* tests/set_ptracer_any.c (main) [HAVE_PRCTL]: Provide fallback
definitions for PR_SET_PTRACER and PR_SET_PTRACER_ANY constants,
set all unused prctl arguments to 0.
Dmitry V. Levin [Wed, 24 Jan 2018 01:56:15 +0000 (01:56 +0000)]
ia64: do not bail out in get_syscall_args if umove fails with EPERM
If the kernel contains commit 84d77d3f06e7e8dea057d10e8ec77ad71f721be3,
both PTRACE_PEEKDATA and process_vm_readv become unavailable when the
process dumpable flag is cleared, on ia64 this results to all syscall
arguments being unavailable.
Recognize this situation and do not treat it as get_syscall_args error
because the latter leaves the tracee in a ptrace stop.
This condition used to be triggered by prctl-dumpable test that caused
strace to hang indefinitely.
* linux/ia64/get_syscall_args.c (get_syscall_args): Do not bail out
if umove fails.
* tests/prctl-dumpable.c [__ia64__]: Skip the test.
print_event_exit should have printing_tcp setup analogous to printleader and
syscall_exit_trace before printing its part, otherwise it spuriously resets
curcol in line_ended for the stale printing_tcp if followfork == 2.
* strace.c (print_event_exit): Set printing_tcp to tcp before printing
exiting event line and calling line_ended.
Dmitry V. Levin [Tue, 23 Jan 2018 01:06:09 +0000 (01:06 +0000)]
tests: check path tracing of select/_newselect syscalls
* tests/xselect.c (main) [PATH_TRACING_FD]: Skip if /proc/self/fd/
is not available. Add test calls that use PATH_TRACING_FD.
(main): Conditionalize expected output for those calls
that do not use PATH_TRACING_FD with [!PATH_TRACING_FD].
* tests/_newselect-P.c: New file.
* tests/select-P.c: Likewise.
* tests/Makefile.am (check_PROGRAMS): Add _newselect-P and select-P.
* tests/.gitignore: Likewise.
* tests/gen_tests.in (_newselect-P, select-P): New entries.
Dmitry V. Levin [Tue, 23 Jan 2018 21:17:05 +0000 (21:17 +0000)]
tests: add file:line to perror_msg_and_fail/error_msg_and_fail output
* tests/tests.h [!perror_msg_and_fail] (perror_msg_and_fail): New macro
wrapper around the homonymous function.
[!error_msg_and_fail] (error_msg_and_fail): Likewise.
* tests/error_msg.c (perror_msg_and_fail, error_msg_and_fail): New
macros defined to themselves.
Dmitry V. Levin [Sun, 21 Jan 2018 23:23:31 +0000 (23:23 +0000)]
Transform fetch_old_mmap_args into fetch_indirect_syscall_args
As there are more than one old style syscall that take their arguments
via array, generalize fetch_old_mmap_args into a function that could
fetch variable number of arguments.
* mem.c (fetch_old_mmap_args): Transform into ...
* fetch_indirect_syscall_args.c: ... fetch_indirect_syscall_args
in this new file.
* Makefile.am (libstrace_a_SOURCES): Add it.
* defs.h [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): Remove.
(fetch_indirect_syscall_args): New prototype.
* pathtrace.c (pathtrace_match_set) [HAVE_ARCH_OLD_MMAP]: Use
fetch_indirect_syscall_args instead of fetch_old_mmap_args.
Dmitry V. Levin [Sun, 21 Jan 2018 20:19:53 +0000 (20:19 +0000)]
Move decoder of getpagesize syscall to libstrace
As only five architectures have getpagesize syscall, moving the decoder
to libstrace allows to get rid of getpagesize related ifdefs and check
build of getpagesize decoder on other architectures.
* mem.c (SYS_FUNC(getpagesize)): Move ...
* getpagesize.c: ... to this new file.
* Makefile.am (libstrace_a_SOURCES): Add it.
Some old systems that still make some sense to be supported have only
gawk 3, so let's support them for now.
In order to achieve that, multiple changes have been implemented:
- Multidimensional arrays are replaced with single-dimensional ones.
In most places it's a "][" -> ", " replacement, as awk allows some
kind of emulation of multidimensional arrays that way, but in several
occasions (specifically for storing name and special fields) we have
to iterate over them later, so we store that information in
additional arrays in order to get the keys.
- "switch" statements are replaced with sets of "if ... else if ...
else" statements. This change is trivial, except we've added
a temporary variable in what_is order to store expression value, for
readability purposes.
- No support for array iteration ordering. This one is most ugly of
them all. Luckily, not that ugly, we've just had to process index a
bit in order to make it lexicographically sortable and add two
temporary arrays containing sorted indices in order to sort over them
instead of those two arrays that we've added in order to work around
lack of multidimensional array support.
* mpers.awk (compare_indices): Remove unused function.
(array_get, update_upper_bound, /^DW_AT_data_member_location/,
/^DW_AT_byte_size/, /^DW_AT_encoding/): Replace multidimensional array
access with comma-concatenated index.
(norm_idx): New function.
(array_seq): Replace multidimensional array access with
comma-concatenated index. Use comma-concatenated pair of (array_idx,
"seq") in order to check presence of the item in an array.
(what_is): Add enc and i local variables. Store the value of
array[what_idx, "encoding"] in it. Replace "switch" statements with
sets of "if ... else if ... else" statements. Replace multidimensional
array access with comma-concatenated index. Use for (... ; ...; ...)
iteration over aparents_keys instead of iteration over array.
(/^<[[:xdigit:]]+>/): Store idx as norm_idx(matches[2]). Replace
multidimensional array access with comma-concatenated index. Store an
additional flag in array_names array.
(/^DW_AT_name/): Replace multidimensional array access with
comma-concatenated index. Add a flag to array_names for that idx.
(/^DW_AT_type/): Do not capture "0x" as a part of a group, normalise
the captured group. Replace multidimensional array access with
comma-concatenated index.
(/^Abbrev Number:[^(]+\(DW_TAG_/): Replace multidimensional array access
with comma-concatenated index. Store additional flags in
array_special and array_parents arrays.
(END): Remove PROCINFO["sorted_in"] setup. Sort array_parents. Replace
multidimensional array access with comma-concatenated index. Iterate
over array_special to go over all the items that have "special" field.
Iterate over array_names to go over all items that have "name" field.
* NEWS: Mention it.
dm: add support for event_nr in DM_LIST_DEVICES result
Commit v4.13-rc1~137^2~13 (and a follow-up fix v4.14-rc4~20^2~3
that changed alignment) introduced an additional hidden field
in the structure returned by DM_LIST_DEVICES ioctl command
that contains event_nr information.
Unfortunately, we can't test it for now, but looks like it kinda works:
* dm.c (dm_decode_dm_name_list): Obtain the amount of bytes copied
during printing device name, print event number if there's a suitable
gap present and the DM version is high enough.
* NEWS: Mention it.
Dmitry V. Levin [Sun, 21 Jan 2018 01:46:04 +0000 (01:46 +0000)]
Use #if idiom instead of #ifdef for HAVE_ARCH_* macros.
* linux/arch_defs_.h [!HAVE_ARCH_OLD_MMAP] (HAVE_ARCH_OLD_MMAP): New
macro.
[!HAVE_ARCH_OLD_MMAP_PGOFF] (HAVE_ARCH_OLD_MMAP_PGOFF): Likewise.
* defs.h: Use #if instead of #ifdef to check HAVE_ARCH_OLD_MMAP.
* mem.c: Use #if instead of #ifdef to check HAVE_ARCH_OLD_MMAP
and HAVE_ARCH_OLD_MMAP_PGOFF
* pathtrace.c: Likewise.
Dmitry V. Levin [Sun, 21 Jan 2018 01:46:04 +0000 (01:46 +0000)]
Rename arch-specific arch_defs.h files to arch_defs_.h
Introduce a new arch_defs.h header that includes the corresponding
arch-specific arch_defs_.h file followed by generic arch_defs_.h file.
* linux/arch_defs.h: Rename to linux/arch_defs_.h.
* linux/aarch64/arch_defs.h: Rename to linux/aarch64/arch_defs_.h.
* linux/arm/arch_defs.h: Rename to linux/arm/arch_defs_.h.
* linux/i386/arch_defs.h: Rename to linux/i386/arch_defs_.h.
* linux/m68k/arch_defs.h: Rename to linux/m68k/arch_defs_.h.
* linux/s390/arch_defs.h: Rename to linux/s390/arch_defs_.h.
* linux/s390x/arch_defs.h: Rename to linux/s390x/arch_defs_.h.
* linux/x32/arch_defs.h: Rename to linux/x32/arch_defs_.h.
* linux/x86_64/arch_defs.h: Rename to linux/x86_64/arch_defs_.h.
* arch_defs.h: New file.
* Makefile.am (strace_SOURCES): Add it.
(EXTRA_DIST): Rename linux/*/arch_defs.h to linux/*/arch_defs_.h.
As umovestr now returns something useful, let's propagate it further.
* defs.h (printstr_ex, printpathn, printpath): Change return type from
void to int.
(printstrn, printstr): Change return type from void to int, return
printstr_ex result.
* util.c (printpathn): Return -1 on NULL addr, nul_seen (exit code of
umovestr) on success.
(printpath): Return printpathn result.
(printstr_ex): Return -1 on NULL addr, umoven/umovestr result otherwise.
We return the size that includes \0 in order to preserve existing
behaviour (return 0 when \0 haven't been seen, return positive number
when it has been seen).
* ucopy.c (umovestr_peekdata, umovestr): Return string length
including \0 instead of 1 when \0 is found.
Dmitry V. Levin [Fri, 19 Jan 2018 17:07:04 +0000 (17:07 +0000)]
mpers.awk: avoid redefinition of mpers_ptr_t
Older versions of gcc like those found in RHEL6 fail with the following
diagnostics:
In file included from block.c:32:
./mpers-m32/struct_blk_user_trace_setup.h:2: error: redefinition of typedef ‘mpers_ptr_t’
mpers_type.h:44: note: previous declaration of ‘mpers_ptr_t’ was here
* configure.ac (AC_ARG_ENABLE([mpers])): Allow m32 and mx32 values
for --enable-mpers option.
* m4/mpers.m4 (st_MPERS): Check for personality support if personality
name is provided as an option. Fail if the requested personality
support is not available.
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
strace.1.in: clarify mpers flags in strace -V output
The previous description was a bit dated.
* strace.1.in (.SH "MULTIPLE PERSONALITY SUPPORT"): Remove "no-m32" and
"no-mx32", describe the situation when some of mpers flags are not
present in strace -V output.
Dmitry V. Levin [Wed, 17 Jan 2018 21:31:07 +0000 (21:31 +0000)]
tests: check path tracing of ppoll syscall
* tests/ppoll.c (main) [PATH_TRACING_FD]: Skip if /proc/self/fd/
is not available. Add a test call that use PATH_TRACING_FD.
(main): Conditionalize expected output for those calls
that do not use PATH_TRACING_FD with [!PATH_TRACING_FD].
* tests/ppoll-P.c: New file.
* tests/pure_executables.list: Add ppoll-P.
* tests/.gitignore: Likewise.
* tests/gen_tests.in (ppoll-P): New entry.
Dmitry V. Levin [Wed, 17 Jan 2018 21:31:07 +0000 (21:31 +0000)]
tests: check path tracing of poll syscall
* tests/poll.c (main) [PATH_TRACING_FD]: Skip if /proc/self/fd/
is not available. Add tests calls that use PATH_TRACING_FD.
(main): Conditionalize expected output for those calls
that do not use PATH_TRACING_FD with [!PATH_TRACING_FD].
* tests/poll-P.c: New file.
* tests/pure_executables.list: Add poll-P.
* tests/.gitignore: Likewise.
* tests/poll-P.test: New test.
* tests/Makefile.am (DECODER_TESTS): Add poll-P.test.
As s390x is the only 64-bit architecture that has old_mmap,
the test needs some adjustments there.
* tests/old_mmap.c: Update condition.
(main): Change int types to long, extend numerals to 64 bit, change
printing format qualifiers to corresponding long types.
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
* tests/old_mmap.c [!TEST_FD]: Define TEST_FD.
(main) <args1_c>: Replace 5th argument with TEST_FD.
(main): Wrap the output for the calls that do not use TEST_FD
with #ifndef PATH_TRACING.
* tests/old_mmap-P.c: New file.
* tests/pure_executables.list: Add old_mmap-P.
* tests/.gitignore: Likewise.
* tests/gen_tests.in: Add old_mmap-P test.
As these system calls have only one argument that points to the
location in memory containing actual arguments, current path tracing
implementation is incorrect. In order to fix this, let's use recently
introduced fetch_old_mmap_args in order to get actual arguments suitable
for path matching.
* pathtrace.c [HAVE_ARCH_OLD_MMAP] <case SEN_old_mmap,
case SEN_old_mmap_pgoff>: Retrieve actual old_mmap arguments with
fetch_old_mmap_args, pass the value from the retrieved args if it's
available.
Move common old_mmap/old_mmap_pgoff argument fetching code into a
separate function.
As it is, it also fixes the case of non-verbose printing of old_mmap
arguments (see the new test in the next commit). Also, it is a
preparation for the fix of path tracing for these syscalls.
* defs.h [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): New prototype.
* mem.c [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): New function.
[HAVE_ARCH_OLD_MMAP] (old_mmap, old_mmap_pgoff): Use it.
Fixes: 3db07f11 "Fix old_mmap output when mmap arguments are unfetchable" Suggested-by: Dmitry V. Levin <ldv@altlinux.org>
* linux/aarch64/arch_regs.c (ARCH_PERSONALITY_0_IOV_SIZE,
ARCH_PERSONALITY_1_IOV_SIZE): New macros.
* linux/aarch64/get_scno.c (arch_get_scno): Do not call
update_personality as it is handled by the generic get_regs code now.
syscall.c: add ability to set personality based on GETREGSET iov size
Some architectures (aarch64, s390x) use only PTRACE_GETREGSET interface
and use its size to detect current personality. Let's generalise this
approach and also avoid subtle errors when we get register but forget to
update personality, at least for those architectures.
Note that in order to employ this behaviour, architecture has to use
PTRACE_GETREGSET exclusively (no HAVE_GETREGS_OLD) and should declare
appropriate ARCH_PERSONALITY_*_IOV_SIZE macros.
* syscall.c (get_regs) [ptrace_getregset_or_getregs &&
!HAVE_GETREGS_OLD]: Call update_personality based on the value returned
in the iov_len field by PTRACE_GETREGSET. Warn once if the returned
iov_len is unknown.
syscall.c: add sanity check for the target personality number
We can never be cautious enough.
* defs.h (set_personality): Change argument type to unsigned int.
* syscall.c (set_personality): Change argument type to unsigned int,
check whether requested personality is sane, die otherwise.
syscall.c: move current_personality check to set_personality
As all the personality-dependent entries are initially in sync, we can
move the check whether we are setting the same personality as we
currently are inside set_personality out of update_personality.
* syscall.c (current_wordsize, current_klongsize): Initialise to 0'th
personality value in order to make the statement about "all the
personality-dependent entries are initially in sync" true.
(set_personality): Check whether requested personality differs from
current_personality.
(update_personality): Call set_personality unconditionally.
syscall.c: always update tcp->currpers in update_personality
Sometimes (for example, switching from a process with one personality
to a process that previously had different personality but returning
from execve to that same personality into) it is possible that
current_personality is not changed, but tcp->currpers is different.
So, let's not return from update_personality and always update
tcp->currpers if it differs from the target personality.
* syscall.c (update_personality): Do not exit early if personality ==
current_personality.
Add support for specifying compiler options for mpers builds
Because some architectures are very, very special.
* configure.ac (cc_flags_m32, cc_flags_mx32): New variables. AC_SUBST
them.
* m4/mpers.m4 (MPERS_CFLAGS): Use instead of CFLAG, pushdef as
$cc_flags_$1.
Use mpers_name instead of CFLAG in AC_CACHE_CHECK messages.
Pass MPERS_CFLAGS as the second argument to mpers_test.sh
* mpers.sh: Add CC_ARCH_FLAGS as the second argument (PARSER_FILE
is moved to the third one). Do not expect leading dash in ARCH_FLAG
anymore.
* mpers_test.sh (mpers_cc_flags): New variable, initialise to the second
command line argument.
Pass $mpers_name without leading dash to mpers.sh.
Pass $mpers_cc_flags as the second argument to mpers.sh ($sample is
the third argument now).
* Makefile.am (mpers-m%.stamp:): Pass $(mpers_CC_FLAGS) as the second
argument to mpers.sh ($$f is now the third argument).
($(mpers_m32_targets)): Define target variable mpers_CC_FLAGS with the
value of @cc_flags_m32@
($(mpers_mx32_targets)): Define target variable mpers_CC_FLAGS with the
value of @cc_flags_mx32@
* tests/Makefile.am (MERS_CC_FLAGS): New variable.
* bootstrap: Append @cc_flags_$1@ to MPERS_CC_FLAGS. Append
$(MPERS_CC_FLAGS) to ARCH_MFLAGS.
Dmitry V. Levin [Tue, 16 Jan 2018 04:34:25 +0000 (04:34 +0000)]
Enhance error diagnostics about invalid syscalls in fault injection syntax
Validate syscall set before the whole fault injection syntax.
* filter_qualify.c (parse_inject_expression): Add const qualifier to
return type. Return an empty string when no syscall set is specified.
(qualify_inject_common): Add const qualifier to "name". Move
qualify_syscall_tokens invocation right after parse_inject_expression.
* tests/qual_fault-syntax.test: Update expected output.
* tests/qual_inject-syntax.test: Likewise.
Dmitry V. Levin [Sun, 14 Jan 2018 00:43:12 +0000 (00:43 +0000)]
filter_qualify: move memory allocation from parse_inject_expression
* filter_qualify.c (parse_inject_expression): Replace "s" and "buf"
arguments with "str" argument, use it instead of "s" and "*buf".
(qualify_inject_common): Rename "buf" to "copy", initialize it to a copy
of "str", pass "copy" to parse_inject_expression instead of "str" and
"buf".
Dmitry V. Levin [Sat, 13 Jan 2018 13:46:45 +0000 (13:46 +0000)]
configure: use AC_MSG_ERROR and AC_MSG_FAILURE consistently
* configure.ac [$arch = mips]: Use AC_MSG_FAILURE instead of
AC_MSG_ERROR when _MIPS_SIM cannot be determined. Use AC_MSG_ERROR
instead of AC_MSG_FAILURE when syscallent stubs cannot be generated.
configure: add --disable-mpers and --enable-mpers=check options
On architectures supporting multiple personalities, multiple
personalities support in strace is required for proper decoding of
structures used by tracees with personalities that differ from the
personality of strace.
New configure options control whether multiple personalities support
in strace is mandatory, optional, or disabled.
The default is changed from what is now equivalent of
--enable-mpers=check (automatically detect whether required mpers
support could be enabled) to --enable-mpers (terminate the build
if required mpers support could not be enabled).
* configure.ac (AC_ARG_ENABLE([mpers])): New option.
* m4/mpers.m4 (st_MPERS): Use enable_mpers. Terminate the build
if mpers could not be enabled and enable_mpers==yes.
* strace.spec.in: Specify --enable-mpers=check to %configure.
* debian/rules (build/Makefile, build64/Makefile): Specify
--enable-mpers=check to configure.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org> Suggested-by: DJ Delorie <dj@redhat.com>
Issue a warning when strace lacks tracee personality support
* defs.h (HAVE_PERSONALITY_1_MPERS, HAVE_PERSONALITY_2_MPERS): New
macros.
* syscall.c (update_personality): Add need_mpers_warning array
initialized with mpers support data. Use it for printing the mpers
unavailability warning once per personality.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>