]> granicus.if.org Git - strace/blobdiff - pathtrace.c
Introduce generic STRINGIFY and STRINGIFY_VAL macros
[strace] / pathtrace.c
index 4ca031cb449d45087442f574c8837d43fa1b120a..9cb0ba77626617336197e8a8fa2dcdd4236c08e1 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2011, Comtrol Corp.
+ * Copyright (c) 2011 Comtrol Corp.
+ * Copyright (c) 2011-2017 The strace developers.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include "defs.h"
 #include <sys/param.h>
-#if defined HAVE_POLL_H
-# include <poll.h>
-#elif defined HAVE_SYS_POLL_H
-# include <sys/poll.h>
-#endif
+#include <poll.h>
 
 #include "syscall.h"
 
-const char **paths_selected = NULL;
-static unsigned num_selected = 0;
+const char **paths_selected;
+static unsigned int num_selected;
 
 /*
  * Return true if specified path matches one that we're tracing.
@@ -58,11 +55,11 @@ pathmatch(const char *path)
  * Return true if specified path (in user-space) matches.
  */
 static int
-upathmatch(struct tcb *tcp, unsigned long upath)
+upathmatch(struct tcb *const tcp, const kernel_ulong_t upath)
 {
        char path[PATH_MAX + 1];
 
-       return umovestr(tcp, upath, sizeof path, path) > 0 &&
+       return umovestr(tcp, upath, sizeof(path), path) > 0 &&
                pathmatch(path);
 }
 
@@ -167,6 +164,7 @@ pathtrace_match(struct tcb *tcp)
        switch (s->sen) {
        case SEN_dup2:
        case SEN_dup3:
+       case SEN_kexec_file_load:
        case SEN_sendfile:
        case SEN_sendfile64:
        case SEN_tee:
@@ -177,14 +175,16 @@ pathtrace_match(struct tcb *tcp)
        case SEN_faccessat:
        case SEN_fchmodat:
        case SEN_fchownat:
+       case SEN_fstatat64:
        case SEN_futimesat:
        case SEN_inotify_add_watch:
        case SEN_mkdirat:
        case SEN_mknodat:
+       case SEN_name_to_handle_at:
        case SEN_newfstatat:
        case SEN_openat:
-       case SEN_pipe2:
        case SEN_readlinkat:
+       case SEN_statx:
        case SEN_unlinkat:
        case SEN_utimensat:
                /* fd, path */
@@ -218,6 +218,7 @@ pathtrace_match(struct tcb *tcp)
        case SEN_mmap:
        case SEN_mmap_4koff:
        case SEN_mmap_pgoff:
+       case SEN_ARCH_mmap:
                /* x, x, x, x, fd */
                return fdmatch(tcp, tcp->u_arg[4]);
 
@@ -227,8 +228,9 @@ pathtrace_match(struct tcb *tcp)
                        upathmatch(tcp, tcp->u_arg[0]) ||
                        upathmatch(tcp, tcp->u_arg[2]);
 
+       case SEN_copy_file_range:
        case SEN_splice:
-               /* fd, x, fd, x, x */
+               /* fd, x, fd, x, x, x */
                return fdmatch(tcp, tcp->u_arg[0]) ||
                        fdmatch(tcp, tcp->u_arg[2]);
 
@@ -248,19 +250,31 @@ pathtrace_match(struct tcb *tcp)
        {
                int     i, j;
                int     nfds;
-               long   *args, oldargs[5];
-               unsigned fdsize;
+               kernel_ulong_t *args;
+               kernel_ulong_t select_args[5];
+               unsigned int oldselect_args[5];
+               unsigned int fdsize;
                fd_set *fds;
 
-               args = tcp->u_arg;
                if (SEN_oldselect == s->sen) {
-                       if (umoven(tcp, tcp->u_arg[0], sizeof oldargs,
-                                  oldargs) < 0)
-                       {
-                               error_msg("umoven() failed");
-                               return 0;
+                       if (sizeof(*select_args) == sizeof(*oldselect_args)) {
+                               if (umove(tcp, tcp->u_arg[0], &select_args)) {
+                                       return 0;
+                               }
+                       } else {
+                               unsigned int n;
+
+                               if (umove(tcp, tcp->u_arg[0], &oldselect_args)) {
+                                       return 0;
+                               }
+
+                               for (n = 0; n < 5; ++n) {
+                                       select_args[n] = oldselect_args[n];
+                               }
                        }
-                       args = oldargs;
+                       args = select_args;
+               } else {
+                       args = tcp->u_arg;
                }
 
                /* Kernel truncates arg[0] to int, we do the same. */
@@ -278,7 +292,6 @@ pathtrace_match(struct tcb *tcp)
                        if (args[i] == 0)
                                continue;
                        if (umoven(tcp, args[i], fdsize, fds) < 0) {
-                               error_msg("umoven() failed");
                                continue;
                        }
                        for (j = 0;; j++) {
@@ -300,7 +313,7 @@ pathtrace_match(struct tcb *tcp)
        {
                struct pollfd fds;
                unsigned nfds;
-               unsigned long start, cur, end;
+               kernel_ulong_t start, cur, end;
 
                start = tcp->u_arg[0];
                nfds = tcp->u_arg[1];
@@ -311,26 +324,31 @@ pathtrace_match(struct tcb *tcp)
                        return 0;
 
                for (cur = start; cur < end; cur += sizeof(fds))
-                       if ((umoven(tcp, cur, sizeof fds, &fds) == 0)
+                       if ((umove(tcp, cur, &fds) == 0)
                            && fdmatch(tcp, fds.fd))
                                return 1;
 
                return 0;
        }
 
+       case SEN_bpf:
        case SEN_epoll_create:
+       case SEN_epoll_create1:
        case SEN_eventfd2:
        case SEN_eventfd:
        case SEN_fanotify_init:
        case SEN_inotify_init1:
+       case SEN_memfd_create:
        case SEN_perf_event_open:
        case SEN_pipe:
+       case SEN_pipe2:
        case SEN_printargs:
        case SEN_socket:
        case SEN_socketpair:
        case SEN_timerfd_create:
        case SEN_timerfd_gettime:
        case SEN_timerfd_settime:
+       case SEN_userfaultfd:
                /*
                 * These have TRACE_FILE or TRACE_DESCRIPTOR or TRACE_NETWORK set,
                 * but they don't have any file descriptor or path args to test.