diff options
author | Eugene Syromyatnikov <evgsyr@gmail.com> | 2022-08-08 11:54:43 +0200 |
---|---|---|
committer | Eugene Syromyatnikov <evgsyr@gmail.com> | 2022-08-11 14:34:17 +0200 |
commit | 07da2c35fd20e1d9af9acd3401f3be7699486b67 (patch) | |
tree | 39d7be071eca802100bb67b500c67fbcd6ea0c11 | |
parent | e926431fdaf4e75a73e8777ac6179dabe02b48d9 (diff) | |
download | strace-07da2c35fd20e1d9af9acd3401f3be7699486b67.tar.gz |
arch_prctl: decode ARCH_GET_XCOMP_SUPP, ARCH_{GET,REQ}_XCOMP{,_GUEST}_PERM
* src/xlat/archvals.in (ARCH_GET_XCOMP_SUPP, ARCH_GET_XCOMP_PERM,
ARCH_REQ_XCOMP_PERM): New constants, introduced by Linux commit
v5.16-rc1~195^2~21.
(ARCH_GET_XCOMP_GUEST_PERM, ARCH_REQ_XCOMP_GUEST_PERM): New constants,
introduced by Linux commit v5.17-rc1~15^2~70.
* src/xlat/x86_xfeature_bits.in: New file.
* src/xlat/x86_xfeatures.in: Likewise.
* src/prctl.c [X86_64 || X32 || I386]: Include
"xlat/x86_xfeature_bits.h", "xlat/x86_xfeatures.h".
* tests/.gitignore: Add arch_prctl, arch_prctl-Xabbrev, arch_prctl-Xraw,
arch_prctl-Xverbose, arch_prctl-success, arch_prctl-success-Xabbrev,
arch_prctl-success-Xraw, and arch_prctl-success-Xverbose.
* tests/Makefile.am (check_PROGRAMS): Add arch_prctl-success,
arch_prctl-success-Xabbrev, arch_prctl-success-Xraw,
and arch_prctl-success-Xverbose.
* tests/arch_prctl.c: New file.
* tests/arch_prctl-Xabbrev.c: Likewise.
* tests/arch_prctl-Xraw.c: Likewise.
* tests/arch_prctl-Xverbose.c: Likewise.
* tests/arch_prctl-success.c: Likewise.
* tests/arch_prctl-success-Xabbrev.c: Likewise.
* tests/arch_prctl-success-Xraw.c: Likewise.
* tests/arch_prctl-success-Xverbose.c: Likewise.
* tests/arch_prctl.sh: Likewise.
* tests/gen_tests.in (arch_prctl, arch_prctl-Xabbrev, arch_prctl-Xraw,
arch_prctl-Xverbose, arch_prctl-success, arch_prctl-success-Xabbrev,
arch_prctl-success-Xraw, arch_prctl-success-Xverbose): New tests.
* tests/prctl-success.sh (PRCTL_SYSCALL, PRCTL_MARKER_RE): New vaiables.
Handle "ARCH_PRCTL_INJECT_RETVALS" in addition to "PRCTL_INJECT_RETVALS",
set PRCTL_SYSCALL and PRCTL_MARKER_RE accordingly; use $PRCTL_SYSCALL
and $PRCTL_MARKER_RE in run_strace and sed calls.
* tests/pure_executables.list: Add arch_prctl, arch_prctl-Xabbrev,
arch_prctl-Xraw, and arch_prctl-Xverbose.
* NEWS: Mention it.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | src/prctl.c | 56 | ||||
-rw-r--r-- | src/xlat/archvals.in | 24 | ||||
-rw-r--r-- | src/xlat/x86_xfeature_bits.in | 21 | ||||
-rw-r--r-- | src/xlat/x86_xfeatures.in | 18 | ||||
-rw-r--r-- | tests/.gitignore | 8 | ||||
-rw-r--r-- | tests/Makefile.am | 5 | ||||
-rw-r--r-- | tests/arch_prctl-Xabbrev.c | 2 | ||||
-rw-r--r-- | tests/arch_prctl-Xraw.c | 2 | ||||
-rw-r--r-- | tests/arch_prctl-Xverbose.c | 2 | ||||
-rw-r--r-- | tests/arch_prctl-success-Xabbrev.c | 2 | ||||
-rw-r--r-- | tests/arch_prctl-success-Xraw.c | 2 | ||||
-rw-r--r-- | tests/arch_prctl-success-Xverbose.c | 2 | ||||
-rw-r--r-- | tests/arch_prctl-success.c | 2 | ||||
-rw-r--r-- | tests/arch_prctl.c | 323 | ||||
-rw-r--r-- | tests/arch_prctl.sh | 16 | ||||
-rw-r--r-- | tests/gen_tests.in | 8 | ||||
-rw-r--r-- | tests/prctl-success.sh | 23 | ||||
-rwxr-xr-x | tests/pure_executables.list | 4 |
19 files changed, 506 insertions, 16 deletions
@@ -15,7 +15,7 @@ Noteworthy changes in release ?.?? (????-??-??) INET_DIAG_PROTOCOL, INET_DIAG_REQ_PROTOCOL, INET_DIAG_SHUTDOWN, INET_DIAG_SK_BPF_STORAGES, INET_DIAG_SOCKOPT, and INET_DIAG_ULP_INFO NETLINK_SOCK_DIAG netlink attributes. - * Enhanced decoding of prctl syscall. + * Enhanced decoding of arch_prctl and prctl syscalls. * Enhanced siginfo_t decoding. * Updated decoding of struct rtnl_link_stats64. * Updated lists of DEVCONF_*, FAN_MARK_*, GPIO_V2_LINE_FLAG_*, IORING_*, diff --git a/src/prctl.c b/src/prctl.c index cf281d8ae..97f42fe15 100644 --- a/src/prctl.c +++ b/src/prctl.c @@ -637,6 +637,8 @@ SYS_FUNC(prctl) #if defined X86_64 || defined X32 || defined I386 # include "xlat/archvals.h" +# include "xlat/x86_xfeature_bits.h" +# include "xlat/x86_xfeatures.h" SYS_FUNC(arch_prctl) { @@ -657,6 +659,60 @@ SYS_FUNC(arch_prctl) case ARCH_GET_CPUID: /* has no arguments */ return RVAL_DECODED; + + case ARCH_GET_XCOMP_SUPP: + case ARCH_GET_XCOMP_PERM: + case ARCH_GET_XCOMP_GUEST_PERM: + if (entering(tcp)) { + tprint_arg_next(); + } else { + uint64_t val; + + if (umove_or_printaddr(tcp, addr, &val)) + return 0; + + /* XFEATURE_MASK_* macros are not publicly exposed */ + tprint_indirect_begin(); + printflags_ex(val, "XFEATURE_MASK_???", + xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW + ? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE, + x86_xfeatures, NULL); + tprint_indirect_end(); + } + + return 0; + + case ARCH_REQ_XCOMP_PERM: + case ARCH_REQ_XCOMP_GUEST_PERM: + if (entering(tcp)) { + /* XFEATURE_* enum is not publicly exposed */ + tprint_arg_next(); + printxvals_ex(addr, "XFEATURE_???", + xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW + ? XLAT_STYLE_RAW : XLAT_STYLE_VERBOSE, + x86_xfeature_bits, NULL); + } else { + if (tcp->u_rval <= 0) + return 0; + + tcp->auxstr = sprintflags_ex("", x86_xfeatures, + (kernel_ulong_t) tcp->u_rval, '\0', + XLAT_STYLE_DEFAULT | SPFF_AUXSTR_MODE); + + return RVAL_HEX | RVAL_STR; + } + + return 0; + + /* default handling: print arg2 in hexadecimal on entering */ + case ARCH_SET_GS: + case ARCH_SET_FS: + case ARCH_SET_CPUID: + case ARCH_MAP_VDSO_X32: + case ARCH_MAP_VDSO_32: + case ARCH_MAP_VDSO_64: + default: + break; } tprint_arg_next(); diff --git a/src/xlat/archvals.in b/src/xlat/archvals.in index 1dbbb8d00..b50ce32d6 100644 --- a/src/xlat/archvals.in +++ b/src/xlat/archvals.in @@ -1,9 +1,15 @@ -ARCH_SET_GS 0x1001 -ARCH_SET_FS 0x1002 -ARCH_GET_FS 0x1003 -ARCH_GET_GS 0x1004 -ARCH_GET_CPUID 0x1011 -ARCH_SET_CPUID 0x1012 -ARCH_MAP_VDSO_X32 0x2001 -ARCH_MAP_VDSO_32 0x2002 -ARCH_MAP_VDSO_64 0x2003 +#sorted +ARCH_SET_GS 0x1001 +ARCH_SET_FS 0x1002 +ARCH_GET_FS 0x1003 +ARCH_GET_GS 0x1004 +ARCH_GET_CPUID 0x1011 +ARCH_SET_CPUID 0x1012 +ARCH_GET_XCOMP_SUPP 0x1021 +ARCH_GET_XCOMP_PERM 0x1022 +ARCH_REQ_XCOMP_PERM 0x1023 +ARCH_GET_XCOMP_GUEST_PERM 0x1024 +ARCH_REQ_XCOMP_GUEST_PERM 0x1025 +ARCH_MAP_VDSO_X32 0x2001 +ARCH_MAP_VDSO_32 0x2002 +ARCH_MAP_VDSO_64 0x2003 diff --git a/src/xlat/x86_xfeature_bits.in b/src/xlat/x86_xfeature_bits.in new file mode 100644 index 000000000..208a4c33e --- /dev/null +++ b/src/xlat/x86_xfeature_bits.in @@ -0,0 +1,21 @@ +#value_indexed +/* From arch/x86/include/asm/fpu/types.h */ +XFEATURE_FP 0 +XFEATURE_SSE 1 +XFEATURE_YMM 2 +XFEATURE_BNDREGS 3 +XFEATURE_BNDCSR 4 +XFEATURE_OPMASK 5 +XFEATURE_ZMM_Hi256 6 +XFEATURE_Hi16_ZMM 7 +XFEATURE_PT_UNIMPLEMENTED_SO_FAR 8 +XFEATURE_PKRU 9 +XFEATURE_PASID 10 +/* XFEATURE_RSRVD_COMP_11 11 */ +/* XFEATURE_RSRVD_COMP_12 12 */ +/* XFEATURE_RSRVD_COMP_13 13 */ +/* XFEATURE_RSRVD_COMP_14 14 */ +XFEATURE_LBR 15 +/* XFEATURE_RSRVD_COMP_16 16 */ +XFEATURE_XTILE_CFG 17 +XFEATURE_XTILE_DATA 18 diff --git a/src/xlat/x86_xfeatures.in b/src/xlat/x86_xfeatures.in new file mode 100644 index 000000000..ef81ff3fb --- /dev/null +++ b/src/xlat/x86_xfeatures.in @@ -0,0 +1,18 @@ +/* From arch/x86/include/asm/fpu/types.h */ +XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE) +XFEATURE_MASK_FP (1 << XFEATURE_FP) +XFEATURE_MASK_SSE (1 << XFEATURE_SSE) +XFEATURE_MASK_YMM (1 << XFEATURE_YMM) +XFEATURE_MASK_BNDREGS (1 << XFEATURE_BNDREGS) +XFEATURE_MASK_BNDCSR (1 << XFEATURE_BNDCSR) +XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK | XFEATURE_MASK_ZMM_Hi256 | XFEATURE_MASK_Hi16_ZMM) +XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK) +XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256) +XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM) +XFEATURE_MASK_PT (1 << XFEATURE_PT_UNIMPLEMENTED_SO_FAR) +XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU) +XFEATURE_MASK_PASID (1 << XFEATURE_PASID) +XFEATURE_MASK_LBR (1 << XFEATURE_LBR) +XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILE_DATA | XFEATURE_MASK_XTILE_CFG) +XFEATURE_MASK_XTILE_CFG (1 << XFEATURE_XTILE_CFG) +XFEATURE_MASK_XTILE_DATA (1 << XFEATURE_XTILE_DATA) diff --git a/tests/.gitignore b/tests/.gitignore index 653002ac1..361f74655 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -23,6 +23,14 @@ aio aio_pgetevents alarm answer +arch_prctl +arch_prctl-Xabbrev +arch_prctl-Xraw +arch_prctl-Xverbose +arch_prctl-success +arch_prctl-success-Xabbrev +arch_prctl-success-Xraw +arch_prctl-success-Xverbose at_fdcwd-pathmax attach-f-p attach-f-p-cmd diff --git a/tests/Makefile.am b/tests/Makefile.am index df5cf6313..7d08c0523 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -99,6 +99,10 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ $(secontext_EXECUTABLES) \ _newselect-P \ answer \ + arch_prctl-success \ + arch_prctl-success-Xabbrev \ + arch_prctl-success-Xraw \ + arch_prctl-success-Xverbose \ attach-f-p \ attach-f-p-cmd \ attach-p-cmd-cmd \ @@ -633,6 +637,7 @@ EXTRA_DIST = \ GPL-2.0-or-later \ PTRACE_SEIZE.sh \ accept_compat.h \ + arch_prctl.sh \ attach-p-cmd.h \ caps-abbrev.awk \ caps.awk \ diff --git a/tests/arch_prctl-Xabbrev.c b/tests/arch_prctl-Xabbrev.c new file mode 100644 index 000000000..3f4c7626c --- /dev/null +++ b/tests/arch_prctl-Xabbrev.c @@ -0,0 +1,2 @@ +#define XLAT_ABBREV 1 +#include "arch_prctl.c" diff --git a/tests/arch_prctl-Xraw.c b/tests/arch_prctl-Xraw.c new file mode 100644 index 000000000..8068cb53c --- /dev/null +++ b/tests/arch_prctl-Xraw.c @@ -0,0 +1,2 @@ +#define XLAT_RAW 1 +#include "arch_prctl.c" diff --git a/tests/arch_prctl-Xverbose.c b/tests/arch_prctl-Xverbose.c new file mode 100644 index 000000000..bab799a66 --- /dev/null +++ b/tests/arch_prctl-Xverbose.c @@ -0,0 +1,2 @@ +#define XLAT_VERBOSE 1 +#include "arch_prctl.c" diff --git a/tests/arch_prctl-success-Xabbrev.c b/tests/arch_prctl-success-Xabbrev.c new file mode 100644 index 000000000..2572ff845 --- /dev/null +++ b/tests/arch_prctl-success-Xabbrev.c @@ -0,0 +1,2 @@ +#define XLAT_ABBREV 1 +#include "arch_prctl-success.c" diff --git a/tests/arch_prctl-success-Xraw.c b/tests/arch_prctl-success-Xraw.c new file mode 100644 index 000000000..f685c369b --- /dev/null +++ b/tests/arch_prctl-success-Xraw.c @@ -0,0 +1,2 @@ +#define XLAT_RAW 1 +#include "arch_prctl-success.c" diff --git a/tests/arch_prctl-success-Xverbose.c b/tests/arch_prctl-success-Xverbose.c new file mode 100644 index 000000000..e8e0afc81 --- /dev/null +++ b/tests/arch_prctl-success-Xverbose.c @@ -0,0 +1,2 @@ +#define XLAT_VERBOSE 1 +#include "arch_prctl-success.c" diff --git a/tests/arch_prctl-success.c b/tests/arch_prctl-success.c new file mode 100644 index 000000000..02b6e39b0 --- /dev/null +++ b/tests/arch_prctl-success.c @@ -0,0 +1,2 @@ +#define INJECT_RETVAL +#include "arch_prctl.c" diff --git a/tests/arch_prctl.c b/tests/arch_prctl.c new file mode 100644 index 000000000..08ba31ac1 --- /dev/null +++ b/tests/arch_prctl.c @@ -0,0 +1,323 @@ +/* + * Check decoding of arch_prctl syscall. + * + * Copyright (c) 2021-2022 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include "scno.h" + +#ifdef __NR_arch_prctl + +# include <stdio.h> +# include <stdlib.h> +# include <unistd.h> +# include <linux/prctl.h> + +# define XLAT_MACROS_ONLY +# include "xlat/archvals.h" +# undef XLAT_MACROS_ONLY + +# include "xlat.h" +# include "xlat/x86_xfeature_bits.h" +# include "xlat/x86_xfeatures.h" + +# ifdef INJECT_RETVAL +# define INJ_STR " (INJECTED)\n" +# else +# define INJ_STR "\n" +# endif + +# define ARRAY_END(a_) ((a_) + ARRAY_SIZE(a_)) + +static long +sys_arch_prctl(unsigned int cmd, kernel_ulong_t arg) +{ + return syscall(__NR_arch_prctl, cmd, arg, (unsigned long) -3U, + (unsigned long) -4U, + (unsigned long) -5U); +} + +static long +arch_prctl_marker(void) +{ + return sys_arch_prctl(-1U, (unsigned long) -2U); +} + +int +main(int argc, char *argv[]) +{ + const kernel_ulong_t dummy = (kernel_ulong_t) 0xbadfaceddeadbeefULL; + const char *errstr; + long rc; + + arch_prctl_marker(); + +# ifdef INJECT_RETVAL + unsigned long num_skip; + long inject_retval; + bool locked = false; + + if (argc < 3) + error_msg_and_fail("Usage: %s NUM_SKIP INJECT_RETVAL", argv[0]); + + num_skip = strtoul(argv[1], NULL, 0); + inject_retval = strtol(argv[2], NULL, 0); + + for (size_t i = 0; i < num_skip; i++) { + if (arch_prctl_marker() != inject_retval) + continue; + + locked = true; + break; + } + + if (!locked) + error_msg_and_fail("Have not locked on arch_prctl(-1, -2)" + " returning %ld", inject_retval); +# endif /* INJECT_RETVAL */ + + TAIL_ALLOC_OBJECT_CONST_PTR(uint64_t, u64_p); + + /* Unknown commands */ + static const uint32_t unk_cmds[] = { + 0, 0x1, + 0x1000, 0x1005, + 0x1010, 0x1013, + 0x1020, 0x1026, + 0x1030, 0x1031, + 0x1100, 0x1101, + 0x2000, 0x2004, + 0x2010, 0x2011, + 0x2100, 0x2101, + 0x3000, 0x3001, + 0xdeadc0de }; + + for (size_t i = 0; i < ARRAY_SIZE(unk_cmds); i++) { + rc = sys_arch_prctl(unk_cmds[i], 0); + printf("arch_prctl(" XLAT_UNKNOWN_FMT("%#x", "ARCH_???") + ", 0) = %s" INJ_STR, + unk_cmds[i], sprintrc(rc)); + + rc = sys_arch_prctl(unk_cmds[i], (kernel_ulong_t) dummy); + printf("arch_prctl(" XLAT_UNKNOWN_FMT("%#x", "ARCH_???") + ", %#llx) = %s" INJ_STR, + unk_cmds[i], (unsigned long long) dummy, sprintrc(rc)); + + rc = sys_arch_prctl(unk_cmds[i], (uintptr_t) u64_p); + printf("arch_prctl(" XLAT_UNKNOWN_FMT("%#x", "ARCH_???") + ", %p) = %s" INJ_STR, + unk_cmds[i], u64_p, sprintrc(rc)); + } + + /* Default decoding */ + static const struct strval32 def_cmds[] = { + { ARG_XLAT_KNOWN(0x1001, "ARCH_SET_GS") }, +# ifdef INJECT_RETVAL + { ARG_XLAT_KNOWN(0x1002, "ARCH_SET_FS") }, +# endif + { ARG_XLAT_KNOWN(0x1012, "ARCH_SET_CPUID") }, + { ARG_XLAT_KNOWN(0x2001, "ARCH_MAP_VDSO_X32") }, + { ARG_XLAT_KNOWN(0x2002, "ARCH_MAP_VDSO_32") }, + { ARG_XLAT_KNOWN(0x2003, "ARCH_MAP_VDSO_64") }, + }; + + for (const struct strval32 *p = def_cmds; p < ARRAY_END(def_cmds); p++) + { + rc = sys_arch_prctl(p->val, (kernel_ulong_t) dummy); + printf("arch_prctl(%s, %#llx) = %s" INJ_STR, + p->str, (unsigned long long) dummy, sprintrc(rc)); + + rc = sys_arch_prctl(p->val, (uintptr_t) u64_p); + printf("arch_prctl(%s, %p) = %s" INJ_STR, + p->str, u64_p, sprintrc(rc)); + + rc = sys_arch_prctl(p->val, 0); + printf("arch_prctl(%s, 0) = %s" INJ_STR, p->str, sprintrc(rc)); + } + + /* ARCH_GET_GS, ARCH_GET_FS */ + static const struct strval32 kptr_cmds[] = { +# ifdef INJECT_RETVAL + { ARG_XLAT_KNOWN(0x1003, "ARCH_GET_FS") }, +# endif + { ARG_XLAT_KNOWN(0x1004, "ARCH_GET_GS") }, + }; + TAIL_ALLOC_OBJECT_CONST_PTR(kernel_ulong_t, kulong_p); + const kernel_ulong_t ptrs[] = { + (kernel_ulong_t) 0xdeadfacecafebeefULL, + (uintptr_t) (kulong_p + 1), + (uintptr_t) kulong_p , + 0 + }; + + for (const struct strval32 *p = kptr_cmds; p < ARRAY_END(kptr_cmds); + p++) { + rc = sys_arch_prctl(p->val, 0); + printf("arch_prctl(%s, NULL) = %s" INJ_STR, + p->str, sprintrc(rc)); + + rc = sys_arch_prctl(p->val, (uintptr_t) (kulong_p + 1)); + printf("arch_prctl(%s, %p) = %s" INJ_STR, + p->str, kulong_p + 1, sprintrc(rc)); + + for (size_t j = 0; j < ARRAY_SIZE(ptrs); j++) { + *kulong_p = ptrs[j]; + uint32_t wr_cmd = p->val == ARCH_GET_GS ? ARCH_SET_GS + : ARCH_SET_FS; +# if !XLAT_RAW + const char *wr_str = p->val == ARCH_GET_GS + ? "ARCH_SET_GS" : "ARCH_SET_FS"; +# endif + rc = sys_arch_prctl(wr_cmd, *kulong_p); + printf("arch_prctl(" XLAT_FMT ", %#llx) = %s" INJ_STR, + XLAT_SEL(wr_cmd, wr_str), + (unsigned long long) *kulong_p, sprintrc(rc)); + + rc = sys_arch_prctl(p->val, (uintptr_t) kulong_p); + errstr = sprintrc(rc); + printf("arch_prctl(%s, ", p->str); + if (rc >= 0) { + if (*kulong_p) { + printf("[%#llx]", + (unsigned long long) *kulong_p); + } else { + printf("[NULL]"); + } + } else { + printf("%p", kulong_p); + } + printf(") = %s" INJ_STR, errstr); + } + } + + /* ARCH_GET_CPUID */ + rc = sys_arch_prctl(ARCH_GET_CPUID, 0xdeadc0de); + printf("arch_prctl(" XLAT_FMT ") = %s" INJ_STR, + XLAT_ARGS(ARCH_GET_CPUID), sprintrc(rc)); + + /* xfeature mask get */ + static const struct strval32 xfget_cmds[] = { + { ARG_XLAT_KNOWN(0x1021, "ARCH_GET_XCOMP_SUPP") }, + { ARG_XLAT_KNOWN(0x1022, "ARCH_GET_XCOMP_PERM") }, + { ARG_XLAT_KNOWN(0x1024, "ARCH_GET_XCOMP_GUEST_PERM") }, + }; + static const struct strval64 xfget_vals[] = { + { ARG_STR(0) }, + { ARG_XLAT_UNKNOWN(0x1, "XFEATURE_MASK_FP") }, + { ARG_XLAT_UNKNOWN(0x2, "XFEATURE_MASK_SSE") }, + { ARG_XLAT_UNKNOWN(0x3, "XFEATURE_MASK_FPSSE") }, + { ARG_XLAT_UNKNOWN(0x20, "XFEATURE_MASK_OPMASK") }, + { ARG_XLAT_UNKNOWN(0xc0, "XFEATURE_MASK_ZMM_Hi256" + "|XFEATURE_MASK_Hi16_ZMM") }, + { ARG_XLAT_UNKNOWN(0xe0, "XFEATURE_MASK_AVX512") }, + { ARG_XLAT_UNKNOWN(0x20000, "XFEATURE_MASK_XTILE_CFG") }, + { ARG_XLAT_UNKNOWN(0x40000, "XFEATURE_MASK_XTILE_DATA") }, + { ARG_XLAT_UNKNOWN(0x60000, "XFEATURE_MASK_XTILE") }, + { ARG_XLAT_UNKNOWN(0xbadfaced, + "XFEATURE_MASK_FP|XFEATURE_MASK_YMM" + "|XFEATURE_MASK_BNDREGS|XFEATURE_MASK_AVX512" + "|XFEATURE_MASK_PASID|XFEATURE_MASK_LBR" + "|XFEATURE_MASK_XTILE|0xbad92800") }, + { ARG_XLAT_UNKNOWN(0x687ff, + "XFEATURE_MASK_FPSSE|XFEATURE_MASK_YMM" + "|XFEATURE_MASK_BNDREGS|XFEATURE_MASK_BNDCSR" + "|XFEATURE_MASK_AVX512|XFEATURE_MASK_PT" + "|XFEATURE_MASK_PKRU|XFEATURE_MASK_PASID" + "|XFEATURE_MASK_LBR|XFEATURE_MASK_XTILE") }, + { ARG_XLAT_UNKNOWN(0xfffffffffff97800, "XFEATURE_MASK_???") }, + }; + + for (const struct strval32 *p = xfget_cmds; p < ARRAY_END(xfget_cmds); + p++) { + rc = sys_arch_prctl(p->val, 0); + printf("arch_prctl(%s, NULL) = %s" INJ_STR, + p->str, sprintrc(rc)); + + rc = sys_arch_prctl(p->val, (uintptr_t) (u64_p + 1)); + printf("arch_prctl(%s, %p) = %s" INJ_STR, + p->str, u64_p + 1, sprintrc(rc)); + + for (const struct strval64 *q = xfget_vals; + q < ARRAY_END(xfget_vals); q++) { + *u64_p = q->val; + rc = sys_arch_prctl(p->val, (uintptr_t) u64_p); + errstr = sprintrc(rc); + printf("arch_prctl(%s, ", p->str); + if (rc >= 0) { +# ifdef INJECT_RETVAL + printf("[%s]", q->str); +# else + if (*u64_p) { + printf("[%#llx" NRAW(" /* "), + (unsigned long long) *u64_p); +# if !XLAT_RAW + printflags(x86_xfeatures, *u64_p, NULL); +# endif + printf(NRAW(" */") "]"); + } else { + printf("[0]"); + } +# endif + } else { + printf("%p", u64_p); + } + printf(") = %s" INJ_STR, errstr); + } + } + + /* xfeature in arg, xfeature mask in ret */ + static const struct strval32 xfreq_cmds[] = { + { ARG_XLAT_KNOWN(0x1023, "ARCH_REQ_XCOMP_PERM") }, + { ARG_XLAT_KNOWN(0x1025, "ARCH_REQ_XCOMP_GUEST_PERM") }, + }; + static const struct strval32 xfreq_vals[] = { + { ARG_XLAT_UNKNOWN(0, "XFEATURE_FP") }, + { ARG_XLAT_UNKNOWN(0x8, "XFEATURE_PT_UNIMPLEMENTED_SO_FAR") }, + { ARG_XLAT_UNKNOWN(0xb, "XFEATURE_???") }, + { ARG_XLAT_UNKNOWN(0xc, "XFEATURE_???") }, + { ARG_XLAT_UNKNOWN(0xd, "XFEATURE_???") }, + { ARG_XLAT_UNKNOWN(0xe, "XFEATURE_???") }, + { ARG_XLAT_UNKNOWN(0xf, "XFEATURE_LBR") }, + { ARG_XLAT_UNKNOWN(0x10, "XFEATURE_???") }, + { ARG_XLAT_UNKNOWN(0x11, "XFEATURE_XTILE_CFG") }, + { ARG_XLAT_UNKNOWN(0x12, "XFEATURE_XTILE_DATA") }, + { ARG_XLAT_UNKNOWN(0x13, "XFEATURE_???") }, + { ARG_XLAT_UNKNOWN(0xdeadface, "XFEATURE_???") }, + }; + + for (const struct strval32 *p = xfreq_cmds; p < ARRAY_END(xfreq_cmds); + p++) { + for (const struct strval32 *q = xfreq_vals; + q < ARRAY_END(xfreq_vals); q++) { + rc = sys_arch_prctl(p->val, q->val); + errstr = sprintrc(rc); + printf("arch_prctl(%s, %s) = ", p->str, q->str); + if (rc > 0) { + printf("%#lx", rc); +# if !XLAT_RAW + if (rc & x86_xfeatures->flags_mask) { + printf(" ("); + printflags(x86_xfeatures, rc, NULL); + printf(")"); + } +# endif + printf(INJ_STR); + } else { + printf("%s" INJ_STR, errstr); + } + } + } + + puts("+++ exited with 0 +++"); + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_arch_prctl") + +#endif diff --git a/tests/arch_prctl.sh b/tests/arch_prctl.sh new file mode 100644 index 000000000..ddab7e25a --- /dev/null +++ b/tests/arch_prctl.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# +# Check arch_prctl syscall decoding. +# +# Copyright (c) 20212-2022 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/init.sh" + +check_prog sed +run_prog > /dev/null +run_strace -earch_prctl "$@" $args > "$EXP" +sed '0,/^arch_prctl(0xffffffff\( \/\* ARCH_??? \*\/\)\?, 0xfffffffe) *= -1 /d' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" diff --git a/tests/gen_tests.in b/tests/gen_tests.in index bb21a9d80..4bb63227f 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -20,6 +20,14 @@ adjtimex -a15 aio -a14 -e trace=io_setup,io_submit,io_getevents,io_cancel,io_destroy aio_pgetevents -e trace=io_pgetevents alarm -a10 +arch_prctl +arch_prctl.sh -a27 +arch_prctl-Xabbrev +arch_prctl.sh -a27 -Xabbrev +arch_prctl-Xraw +arch_prctl.sh -a17 -Xraw +arch_prctl-Xverbose +arch_prctl.sh -a32 -Xverbose +arch_prctl-success +prctl-success.sh ARCH_PRCTL_INJECT_RETVALS="0 1 2 3 0x20 0xc0 0xdead 0x20000 0x40000 0x60000 0x687ff 0x97800 0x789abcde" -a27 +arch_prctl-success-Xabbrev +prctl-success.sh ARCH_PRCTL_INJECT_RETVALS="0 1 2 3 0x20 0xc0 0xdead 0x20000 0x40000 0x60000 0x687ff 0x97800 0x789abcde" -a27 -Xabbrev +arch_prctl-success-Xraw +prctl-success.sh ARCH_PRCTL_INJECT_RETVALS="0 1 2 3 0x20 0xc0 0xdead 0x20000 0x40000 0x60000 0x687ff 0x97800 0x789abcde" -a17 -Xraw +arch_prctl-success-Xverbose +prctl-success.sh ARCH_PRCTL_INJECT_RETVALS="0 1 2 3 0x20 0xc0 0xdead 0x20000 0x40000 0x60000 0x687ff 0x97800 0x789abcde" -a32 -Xverbose at_fdcwd-pathmax -a36 --trace=openat -y -P sample bpf -a20 bpf-obj_get_info_by_fd -a20 -y -e trace=bpf diff --git a/tests/prctl-success.sh b/tests/prctl-success.sh index 2ab26023c..0d5301501 100644 --- a/tests/prctl-success.sh +++ b/tests/prctl-success.sh @@ -12,8 +12,10 @@ . "${srcdir=.}/scno_tampering.sh" -: ${PRCTL_INJECT_START=256} -: ${PRCTL_INJECT_RETVALS=42} +: "${PRCTL_INJECT_START=256}" +: "${PRCTL_INJECT_RETVALS=42}" +: "${PRCTL_SYSCALL=prctl}" +: "${PRCTL_MARKER_RE='prctl(0xffffffff\( \/\* PR_??? \*\/\)\?, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb)'}" check_prog sed @@ -21,7 +23,16 @@ check_prog sed # at the beginning of the argument list. while [ "$#" -gt 0 ]; do case "$1" in - PRCTL_INJECT_RETVALS=*) PRCTL_INJECT_RETVALS="${1#PRCTL_INJECT_RETVALS=}"; ;; + ARCH_PRCTL_INJECT_RETVALS=*) + PRCTL_INJECT_RETVALS="${1#ARCH_PRCTL_INJECT_RETVALS=}" + PRCTL_SYSCALL=arch_prctl + PRCTL_MARKER_RE='arch_prctl(0xffffffff\( \/\* ARCH_??? \*\/\)\?, 0xfffffffe)' + ;; + PRCTL_INJECT_RETVALS=*) + PRCTL_INJECT_RETVALS="${1#PRCTL_INJECT_RETVALS=}" + PRCTL_SYSCALL=prctl + PRCTL_MARKER_RE='prctl(0xffffffff\( \/\* PR_??? \*\/\)\?, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb)' + ;; *) break; ;; esac @@ -48,9 +59,9 @@ for i in $(echo "$PRCTL_INJECT_RETVALS"); do sed_match="-1 ${i#error=}" fi - run_strace -a80 "$@" -e trace=prctl \ - -e inject=prctl:"${inj_str}":when="${PRCTL_INJECT_START}+" \ + run_strace -a80 "$@" -e trace="${PRCTL_SYSCALL}" \ + -e inject="${PRCTL_SYSCALL}":"${inj_str}":when="${PRCTL_INJECT_START}+" \ "../$NAME" "${PRCTL_INJECT_START}" "${ret_val}" > "$EXP.$i" - sed '0,/^prctl(0xffffffff\( \/\* PR_??? \*\/\)\?, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb) *= '"${sed_match}"' /d' < "$LOG" > "$OUT.$i" + sed '0,/^'"${PRCTL_MARKER_RE}"' *= '"${sed_match}"' /d' < "$LOG" > "$OUT.$i" match_diff "$OUT.$i" "$EXP.$i" done diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 3577499cc..471a97e1e 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -15,6 +15,10 @@ adjtimex aio aio_pgetevents alarm +arch_prctl +arch_prctl-Xabbrev +arch_prctl-Xraw +arch_prctl-Xverbose at_fdcwd-pathmax bpf bpf-v |