]> granicus.if.org Git - strace/commitdiff
Implement PTRACE_SECCOMP_GET_METADATA ptrace request decoding
authorEugene Syromyatnikov <evgsyr@gmail.com>
Wed, 21 Feb 2018 18:20:54 +0000 (19:20 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 6 Mar 2018 23:52:08 +0000 (23:52 +0000)
* 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>
NEWS
defs.h
process.c
ptrace.h
tests/ptrace.c
xlat/ptrace_cmds.in

diff --git a/NEWS b/NEWS
index 8c777a302d828a111e13f80e98ebac5892e19900..a3c5283b38f8860b6593631b580123e7794a1e20 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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_*,
diff --git a/defs.h b/defs.h
index b4170af48a007d94455d70055e84c7426fde7f72..17f3b4887d40a7d96d79dae66488d5950be27663 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -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[];
index f5733417c66afea1a3f515d69ac745d1bf7dcabe..4780311369b25e29359dbbf31cec3265ad795853 100644 (file)
--- a/process.c
+++ b/process.c
@@ -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;
index ce4fd9af3eac39c1bc6b43ba3e17ef00ffc447c6..fb2e60917c11ff1ec2f21608ee95ba483a703145 100644 (file)
--- a/ptrace.h
+++ b/ptrace.h
 #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
index c70d56895aaa9fa9c67d30702d1adf75b259dc08..5c09fa32c69e487d62a160c3d6b3135ca8b0376b 100644 (file)
@@ -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);
index 525494da38753b5661385b78009d914ff95e7322..da7030d41a4a1f20dfb48f38616248ec6f3e8be7 100644 (file)
@@ -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