From c32610732350c4d39911b28510f21d116d49d6d8 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 24 Jun 2019 16:57:01 +0000 Subject: [PATCH] Implement decoding of open_tree syscall ... 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. --- Makefile.am | 1 + NEWS | 1 + configure.ac | 1 + linux/syscallent-common.h | 1 + open_tree.c | 22 +++++++ pathtrace.c | 1 + tests/.gitignore | 2 + tests/gen_tests.in | 2 + tests/open_tree-P.c | 2 + tests/open_tree.c | 111 ++++++++++++++++++++++++++++++++++++ tests/pure_executables.list | 2 + xlat/open_tree_flags.in | 10 ++++ 12 files changed, 156 insertions(+) create mode 100644 open_tree.c create mode 100644 tests/open_tree-P.c create mode 100644 tests/open_tree.c create mode 100644 xlat/open_tree_flags.in diff --git a/Makefile.am b/Makefile.am index 07918ec9..4c56935a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 e941627d..8a21b789 100644 --- 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. diff --git a/configure.ac b/configure.ac index f3769ca7..399c0e0a 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/linux/syscallent-common.h b/linux/syscallent-common.h index 70116c22..6d404d2d 100644 --- a/linux/syscallent-common.h +++ b/linux/syscallent-common.h @@ -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 index 00000000..3d1173ad --- /dev/null +++ b/open_tree.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "defs.h" +#include +#ifdef HAVE_LINUX_MOUNT_H +# include +#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; +} diff --git a/pathtrace.c b/pathtrace.c index 142e1b65..53ac8031 100644 --- a/pathtrace.c +++ b/pathtrace.c @@ -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: diff --git a/tests/.gitignore b/tests/.gitignore index 94420216..e51895ce 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -366,6 +366,8 @@ oldselect-efault oldselect-efault-P oldstat open +open_tree +open_tree-P openat orphaned_process_group osf_utimes diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 487b9608..45fc5e5a 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -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 index 00000000..0097d763 --- /dev/null +++ b/tests/open_tree-P.c @@ -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 index 00000000..4bc86959 --- /dev/null +++ b/tests/open_tree.c @@ -0,0 +1,111 @@ +/* + * Check decoding of open_tree syscall. + * + * Copyright (c) 2019 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include +#include "scno.h" + +#ifdef __NR_open_tree + +# include +# include +# include +# include +# include + +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 diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 1e509dcf..e6e99abe 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -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 index 00000000..3080dc08 --- /dev/null +++ b/xlat/open_tree_flags.in @@ -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 -- 2.40.0