]> granicus.if.org Git - strace/commitdiff
Implement decoding of open_tree syscall
authorDmitry V. Levin <ldv@altlinux.org>
Mon, 24 Jun 2019 16:57:01 +0000 (16:57 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 29 Jun 2019 17:38:25 +0000 (17:38 +0000)
... introduced by Linux kernel commits v5.2-rc1~141^2~9,
v5.2-rc1~20^2~1, and v5.2-rc1~20^2.

* configure.ac (AC_CHECK_HEADERS): Add linux/mount.h.
* open_tree.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* pathtrace.c (pathtrace_match_set): Add SEN_open_tree.
* xlat/open_tree_flags.in: New file.
* linux/syscallent-common.h [BASE_NR + 428]: Wire up open_tree.
* NEWS: Mention this change.
* tests/open_tree.c: New file.
* tests/open_tree-P.c: Likewise.
* tests/gen_tests.in (open_tree, open_tree-P): New entries.
* tests/pure_executables.list: Add open_tree and open_tree-P.
* tests/.gitignore: Likewise.

12 files changed:
Makefile.am
NEWS
configure.ac
linux/syscallent-common.h
open_tree.c [new file with mode: 0644]
pathtrace.c
tests/.gitignore
tests/gen_tests.in
tests/open_tree-P.c [new file with mode: 0644]
tests/open_tree.c [new file with mode: 0644]
tests/pure_executables.list
xlat/open_tree_flags.in [new file with mode: 0644]

index 07918ec92480bfec94e99fe0bc3b0d0f5faacb87..4c56935a56fd5f10fac8ac128a8e575f5cfde597 100644 (file)
@@ -221,6 +221,7 @@ strace_SOURCES =    \
        number_set.h    \
        oldstat.c       \
        open.c          \
+       open_tree.c     \
        or1k_atomic.c   \
        pathtrace.c     \
        perf.c          \
diff --git a/NEWS b/NEWS
index e941627def76b07f517c394d768a6c72817476b9..8a21b789425f92fe76cea30c30028bf1914064d8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ Noteworthy changes in release ?.? (????-??-??)
 ==============================================
 
 * Improvements
+  * Implemented decoding of open_tree syscall.
   * Enhanced decoding of clone syscall.
   * Updated lists of AT_*, AUDIT_*, CLONE_*, ETH_*, KEY_*, KVM_*, TIPC_*,
     and V4L2_* constants.
index f3769ca7ebdc4c65788a22535d7b0e53a0158ca3..399c0e0ac54dbd9d4254a308a1a1f456756df530 100644 (file)
@@ -394,6 +394,7 @@ AC_CHECK_HEADERS(m4_normalize([
        linux/kvm.h
        linux/memfd.h
        linux/mmtimer.h
+       linux/mount.h
        linux/msg.h
        linux/neighbour.h
        linux/netfilter/ipset/ip_set.h
index 70116c2275c04d4b8ab658243e9611fa2ddc9a22..6d404d2dcf38ad9bae5e7d1de5352c9a95a5af47 100644 (file)
@@ -12,3 +12,4 @@
 [BASE_NR + 425] = { 2, TD,             SEN(io_uring_setup),            "io_uring_setup"        },
 [BASE_NR + 426] = { 6, TD|TS,          SEN(io_uring_enter),            "io_uring_enter"        },
 [BASE_NR + 427] = { 4, TD|TM,          SEN(io_uring_register),         "io_uring_register"     },
+[BASE_NR + 428] = { 3, TD|TF,          SEN(open_tree),                 "open_tree"             },
diff --git a/open_tree.c b/open_tree.c
new file mode 100644 (file)
index 0000000..3d1173a
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+#include <fcntl.h>
+#ifdef HAVE_LINUX_MOUNT_H
+# include <linux/mount.h>
+#endif
+#include "xlat/open_tree_flags.h"
+
+SYS_FUNC(open_tree)
+{
+       print_dirfd(tcp, tcp->u_arg[0]);
+       printpath(tcp, tcp->u_arg[1]);
+       tprints(", ");
+       printflags(open_tree_flags, tcp->u_arg[2], "OPEN_TREE_???");
+       return RVAL_DECODED | RVAL_FD;
+}
index 142e1b65933e77734cae7dedbef79b1836ce69f8..53ac8031342014c06307cd31a50943ea2a2177ec 100644 (file)
@@ -199,6 +199,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set)
        case SEN_mknodat:
        case SEN_name_to_handle_at:
        case SEN_newfstatat:
+       case SEN_open_tree:
        case SEN_openat:
        case SEN_readlinkat:
        case SEN_statx:
index 9442021666d15a7638867981f9b12d654be4eec7..e51895cec7e53daab80674b7007687264ec7bbbe 100644 (file)
@@ -366,6 +366,8 @@ oldselect-efault
 oldselect-efault-P
 oldstat
 open
+open_tree
+open_tree-P
 openat
 orphaned_process_group
 osf_utimes
index 487b9608a20f13c0758c4f99bf8d974b54c42990..45fc5e5aa512fdaacbc6a302abf5d7c8bcb93742 100644 (file)
@@ -312,6 +312,8 @@ oldselect-efault    -a13 -e trace=select
 oldselect-efault-P     -a13 -e trace=select -P /dev/full 9>>/dev/full
 oldstat        -a32 -v -P stat.sample -P /dev/full
 open   -a30 -P $NAME.sample
+open_tree -a30 -y
+open_tree-P -a30 -y -P /dev/full -e trace=open_tree
 openat -a36 -P $NAME.sample
 orphaned_process_group . "${srcdir=.}/PTRACE_SEIZE.sh"; run_strace_match_diff -f -e trace=none -e signal='!chld'
 osf_utimes     -a21
diff --git a/tests/open_tree-P.c b/tests/open_tree-P.c
new file mode 100644 (file)
index 0000000..0097d76
--- /dev/null
@@ -0,0 +1,2 @@
+#define PATH_TRACING
+#include "open_tree.c"
diff --git a/tests/open_tree.c b/tests/open_tree.c
new file mode 100644 (file)
index 0000000..4bc8695
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Check decoding of open_tree syscall.
+ *
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <asm/unistd.h>
+#include "scno.h"
+
+#ifdef __NR_open_tree
+
+# include <fcntl.h>
+# include <limits.h>
+# include <stdio.h>
+# include <stdint.h>
+# include <unistd.h>
+
+static const char *errstr;
+
+static long
+k_open_tree(const unsigned int dfd,
+           const void *fname,
+           const unsigned int flags)
+{
+       const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+       const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
+       const kernel_ulong_t arg1 = fill | dfd;
+       const kernel_ulong_t arg2 = (uintptr_t) fname;
+       const kernel_ulong_t arg3 = fill | flags;
+       const long rc = syscall(__NR_open_tree, arg1, arg2, arg3, bad, bad, bad);
+       errstr = sprintrc(rc);
+       return rc;
+}
+
+int
+main(void)
+{
+       skip_if_unavailable("/proc/self/fd/");
+
+       static const char path_full[] = "/dev/full";
+       const char *const path = tail_memdup(path_full, sizeof(path_full));
+       char *const fname = tail_alloc(PATH_MAX);
+       const void *const efault = fname + PATH_MAX;
+       const char *const empty = efault - 1;
+       fill_memory_ex(fname, PATH_MAX, '0', 10);
+
+        int dfd = open(path, O_WRONLY);
+        if (dfd < 0)
+                perror_msg_and_fail("open: %s", path);
+
+       k_open_tree(-1, 0, 1);
+# ifndef PATH_TRACING
+       printf("open_tree(-1, NULL, %s) = %s\n", "OPEN_TREE_CLONE", errstr);
+# endif
+
+       k_open_tree(-100, fname, 0);
+# ifndef PATH_TRACING
+       printf("open_tree(%s, \"%.*s\"..., 0) = %s\n",
+              "AT_FDCWD", (int) PATH_MAX - 1, fname, errstr);
+# endif
+
+       fname[PATH_MAX - 1] = '\0';
+       k_open_tree(dfd, fname, 0x8000);
+       printf("open_tree(%d<%s>, \"%s\", %s) = %s\n",
+              dfd, path, fname, "AT_RECURSIVE", errstr);
+
+# ifdef O_CLOEXEC
+       k_open_tree(-1, efault, O_CLOEXEC | 1);
+#  ifndef PATH_TRACING
+       printf("open_tree(-1, %p, %s) = %s\n",
+              efault, "OPEN_TREE_CLONE|OPEN_TREE_CLOEXEC", errstr);
+#  endif
+
+       k_open_tree(-1, empty, -1);
+#  ifndef PATH_TRACING
+       printf("open_tree(-1, \"\", %s|%#x) = %s\n",
+              "OPEN_TREE_CLONE|OPEN_TREE_CLOEXEC"
+              "|AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW"
+              "|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|AT_RECURSIVE",
+              -1U & ~0x9f01 & ~O_CLOEXEC,
+              errstr);
+#  endif
+# endif /* O_CLOEXEC */
+
+       if (k_open_tree(-1, path, 0) < 0)
+               printf("open_tree(-1, \"%s\", 0) = %s\n",
+                      path, errstr);
+       else
+               printf("open_tree(-1, \"%s\", 0) = %s<%s>\n",
+                      path, errstr, path);
+
+       if (k_open_tree(dfd, empty, 0x1000) < 0)
+               printf("open_tree(%d<%s>, \"\", %s) = %s\n",
+                      dfd, path, "AT_EMPTY_PATH", errstr);
+       else
+               printf("open_tree(%d<%s>, \"\", %s) = %s<%s>\n",
+                      dfd, path, "AT_EMPTY_PATH", errstr, path);
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_open_tree")
+
+#endif
index 1e509dcfcf023c963809db9ced0b0cac4299fd72..e6e99abedbcd418c3381fe140e38122d85e64fa8 100755 (executable)
@@ -314,6 +314,8 @@ oldselect
 oldselect-efault
 oldstat
 open
+open_tree
+open_tree-P
 openat
 osf_utimes
 pause
diff --git a/xlat/open_tree_flags.in b/xlat/open_tree_flags.in
new file mode 100644 (file)
index 0000000..3080dc0
--- /dev/null
@@ -0,0 +1,10 @@
+OPEN_TREE_CLONE                1
+#if defined OPEN_TREE_CLOEXEC || defined O_CLOEXEC
+OPEN_TREE_CLOEXEC      O_CLOEXEC
+#endif
+AT_SYMLINK_NOFOLLOW    0x100
+AT_REMOVEDIR           0x200
+AT_SYMLINK_FOLLOW      0x400
+AT_NO_AUTOMOUNT                0x800
+AT_EMPTY_PATH          0x1000
+AT_RECURSIVE           0x8000