diff options
author | Eugene Syromyatnikov <evgsyr@gmail.com> | 2018-02-21 19:20:54 +0100 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2018-03-06 23:52:08 +0000 |
commit | fd02ce4ff82a6cda2a012dbdae5c6588158db44c (patch) | |
tree | 3a928328a78d02401d458f61db17aadfae793ae1 | |
parent | 0b03de74bc5b19692e4b77df64882c6602f41161 (diff) | |
download | strace-fd02ce4ff82a6cda2a012dbdae5c6588158db44c.tar.gz |
Implement PTRACE_SECCOMP_GET_METADATA ptrace request decoding
* defs.h (seccomp_filter_flags): New declaration.
* process.c (SYS_FUNC(ptrace)): Implement PTRACE_SECCOMP_GET_METADATA
request decoding.
* ptrace.h [!PTRACE_SECCOMP_GET_METADATA] (PTRACE_SECCOMP_GET_METADATA):
New macro constant.
* xlat/ptrace_cmds.in (PTRACE_SECCOMP_GET_METADATA): New constant.
* tests/ptrace.c (main): Add some checks for PTRACE_SECCOMP_GET_METADATA
request decoding.
* NEWS: Mention it.
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | defs.h | 1 | ||||
-rw-r--r-- | process.c | 42 | ||||
-rw-r--r-- | ptrace.h | 3 | ||||
-rw-r--r-- | tests/ptrace.c | 20 | ||||
-rw-r--r-- | xlat/ptrace_cmds.in | 1 |
6 files changed, 68 insertions, 0 deletions
@@ -11,6 +11,7 @@ Noteworthy changes in release ?.?? (????-??-??) * Improvements * IPv6 addresses shown in socket information in -yy mode are now printed in brackets. + * Enhanced decoding of ptrace syscall. * Enhanced NETLINK_ROUTE protocol decoding. * Updated lists of signal codes. * Updated lists of BPF_*, BTN_*, ETH_P_*, INET_DIAG_BC_*, KEY_*, POLL*, RWF_*, @@ -297,6 +297,7 @@ extern const struct xlat resource_flags[]; extern const struct xlat routing_scopes[]; extern const struct xlat routing_table_ids[]; extern const struct xlat routing_types[]; +extern const struct xlat seccomp_filter_flags[]; extern const struct xlat seccomp_ret_action[]; extern const struct xlat setns_types[]; extern const struct xlat sg_io_info[]; @@ -122,6 +122,7 @@ SYS_FUNC(ptrace) case PTRACE_GETSIGMASK: case PTRACE_SETSIGMASK: case PTRACE_SECCOMP_GET_FILTER: + case PTRACE_SECCOMP_GET_METADATA: tprintf(", %" PRI_klu, addr); break; case PTRACE_PEEKSIGINFO: { @@ -204,6 +205,21 @@ SYS_FUNC(ptrace) case PTRACE_SETREGSET: tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR); break; + case PTRACE_SECCOMP_GET_METADATA: + if (verbose(tcp)) { + uint64_t filter_off; + if (addr < sizeof(filter_off) || + umove(tcp, data, &filter_off)) { + printaddr(data); + return RVAL_DECODED; + } + + tprintf("{filter_off=%" PRIu64, filter_off); + return 0; + } + + printaddr(data); + break; #ifndef IA64 case PTRACE_PEEKDATA: case PTRACE_PEEKTEXT: @@ -253,6 +269,32 @@ SYS_FUNC(ptrace) case PTRACE_SECCOMP_GET_FILTER: print_seccomp_fprog(tcp, data, tcp->u_rval); break; + case PTRACE_SECCOMP_GET_METADATA: { + const size_t offset = sizeof(uint64_t); + uint64_t flags = 0; + size_t ret_size = MIN((kernel_ulong_t) tcp->u_rval, + offset + sizeof(flags)); + + if (syserror(tcp) || ret_size <= offset) { + tprints("}"); + return 0; + } + + if (umoven(tcp, data + offset, ret_size - offset, + &flags)) { + tprints(", ...}"); + return 0; + } + + tprints(", flags="); + printflags64(seccomp_filter_flags, flags, + "SECCOMP_FILTER_FLAG_???"); + + if ((kernel_ulong_t) tcp->u_rval > ret_size) + tprints(", ..."); + + tprints("}"); + } } } return 0; @@ -171,6 +171,9 @@ #ifndef PTRACE_SECCOMP_GET_FILTER # define PTRACE_SECCOMP_GET_FILTER 0x420c #endif +#ifndef PTRACE_SECCOMP_GET_METADATA +# define PTRACE_SECCOMP_GET_METADATA 0x420d +#endif #if !HAVE_DECL_PTRACE_PEEKUSER # define PTRACE_PEEKUSER PTRACE_PEEKUSR diff --git a/tests/ptrace.c b/tests/ptrace.c index c70d56895..5c09fa32c 100644 --- a/tests/ptrace.c +++ b/tests/ptrace.c @@ -33,7 +33,9 @@ #include <errno.h> #include "ptrace.h" +#include <inttypes.h> #include <signal.h> +#include <stdint.h> #include <stdio.h> #include <string.h> #include <sys/wait.h> @@ -177,6 +179,8 @@ main(void) const unsigned long pid = (unsigned long) 0xdefaced00000000ULL | (unsigned) getpid(); + uint64_t *filter_off = tail_alloc(sizeof(*filter_off)); + const unsigned int sigset_size = get_sigset_size(); void *const k_set = tail_alloc(sigset_size); @@ -246,6 +250,22 @@ main(void) printf("ptrace(PTRACE_SECCOMP_GET_FILTER, %u, 42, NULL) = %s\n", (unsigned) pid, errstr); + do_ptrace(PTRACE_SECCOMP_GET_METADATA, pid, bad_data, 0); + printf("ptrace(PTRACE_SECCOMP_GET_METADATA, %u, %lu, NULL) = %s\n", + (unsigned) pid, bad_data, errstr); + + do_ptrace(PTRACE_SECCOMP_GET_METADATA, pid, 7, + (unsigned long) filter_off); + printf("ptrace(PTRACE_SECCOMP_GET_METADATA, %u, 7, %p) = %s\n", + (unsigned) pid, filter_off, errstr); + + *filter_off = 0xfacefeeddeadc0deULL; + do_ptrace(PTRACE_SECCOMP_GET_METADATA, pid, bad_data, + (unsigned long) filter_off); + printf("ptrace(PTRACE_SECCOMP_GET_METADATA, %u, %lu, " + "{filter_off=%" PRIu64 "}) = %s\n", + (unsigned) pid, bad_data, *filter_off, errstr); + do_ptrace(PTRACE_GETEVENTMSG, pid, bad_request, bad_data); printf("ptrace(PTRACE_GETEVENTMSG, %u, %#lx, %#lx) = %s\n", (unsigned) pid, bad_request, bad_data, errstr); diff --git a/xlat/ptrace_cmds.in b/xlat/ptrace_cmds.in index 525494da3..da7030d41 100644 --- a/xlat/ptrace_cmds.in +++ b/xlat/ptrace_cmds.in @@ -33,6 +33,7 @@ PTRACE_PEEKSIGINFO PTRACE_GETSIGMASK PTRACE_SETSIGMASK PTRACE_SECCOMP_GET_FILTER +PTRACE_SECCOMP_GET_METADATA /* arch-specific */ PTRACE_GET_THREAD_AREA PTRACE_SET_THREAD_AREA |