From bd2e4cfc74519981926c668580ce4dfc080b81f2 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 28 Jun 2019 09:30:54 +0000 Subject: [PATCH] Implement decoding of fsmount syscall ... introduced by Linux kernel commits v5.2-rc1~141^2~2, v5.2-rc1~20^2~1, and v5.2-rc1~20^2. * fsmount.c: New file. * Makefile.am (strace_SOURCES): Add it. * pathtrace.c (pathtrace_match_set): Add SEN_fsmount. * xlat/fsmount_cmds.in: New file. * xlat/mount_attr_atime.in: Likewise. * xlat/mount_attr_flags.in: Likewise. * linux/syscallent-common.h [BASE_NR + 432]: Wire up fsmount. * NEWS: Mention this change. * tests/fsmount.c: New file. * tests/gen_tests.in (fsmount): New entry. * tests/pure_executables.list: Add fsmount. * tests/.gitignore: Likewise. --- Makefile.am | 1 + NEWS | 2 +- fsmount.c | 26 ++++++++++ linux/syscallent-common.h | 1 + pathtrace.c | 1 + tests/.gitignore | 1 + tests/fsmount.c | 98 +++++++++++++++++++++++++++++++++++++ tests/gen_tests.in | 1 + tests/pure_executables.list | 1 + xlat/fsmount_flags.in | 1 + xlat/mount_attr_flags.in | 7 +++ 11 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 fsmount.c create mode 100644 tests/fsmount.c create mode 100644 xlat/fsmount_flags.in create mode 100644 xlat/mount_attr_flags.in diff --git a/Makefile.am b/Makefile.am index e22a1ced..4f0eb642 100644 --- a/Makefile.am +++ b/Makefile.am @@ -133,6 +133,7 @@ strace_SOURCES = \ flock.h \ fs_x_ioctl.c \ fsconfig.c \ + fsmount.c \ fsopen.c \ futex.c \ gcc_compat.h \ diff --git a/NEWS b/NEWS index ef9da37b..60d08848 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ Noteworthy changes in release ?.? (????-??-??) ============================================== * Improvements - * Implemented decoding of open_tree, move_mount, fsopen, and fsconfig + * Implemented decoding of open_tree, move_mount, fsopen, fsconfig, and fsmount syscalls. * Enhanced decoding of clone syscall. * Updated lists of AT_*, AUDIT_*, CLONE_*, ETH_*, KEY_*, KVM_*, TIPC_*, diff --git a/fsmount.c b/fsmount.c new file mode 100644 index 00000000..c64e2567 --- /dev/null +++ b/fsmount.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "defs.h" +#ifdef HAVE_LINUX_MOUNT_H +# include +#endif +#include "xlat/fsmount_flags.h" +#include "xlat/mount_attr_flags.h" + +SYS_FUNC(fsmount) +{ + printfd(tcp, tcp->u_arg[0]); + tprints(", "); + + printflags(fsmount_flags, tcp->u_arg[1], "FSMOUNT_???"); + tprints(", "); + + printflags(mount_attr_flags, tcp->u_arg[2], "MOUNT_ATTR_???"); + + return RVAL_DECODED | RVAL_FD; +} diff --git a/linux/syscallent-common.h b/linux/syscallent-common.h index c2e844ea..af96dc7a 100644 --- a/linux/syscallent-common.h +++ b/linux/syscallent-common.h @@ -16,3 +16,4 @@ [BASE_NR + 429] = { 5, TD|TF, SEN(move_mount), "move_mount" }, [BASE_NR + 430] = { 2, TD, SEN(fsopen), "fsopen" }, [BASE_NR + 431] = { 5, TD|TF, SEN(fsconfig), "fsconfig" }, +[BASE_NR + 432] = { 3, TD, SEN(fsmount), "fsmount" }, diff --git a/pathtrace.c b/pathtrace.c index 3c09bc32..a96b9ff6 100644 --- a/pathtrace.c +++ b/pathtrace.c @@ -341,6 +341,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set) case SEN_eventfd2: case SEN_eventfd: case SEN_fanotify_init: + case SEN_fsmount: case SEN_fsopen: case SEN_inotify_init: case SEN_inotify_init1: diff --git a/tests/.gitignore b/tests/.gitignore index 2b8e500a..14f50802 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -91,6 +91,7 @@ flock fork-f fsconfig fsconfig-P +fsmount fsopen fstat fstat-Xabbrev diff --git a/tests/fsmount.c b/tests/fsmount.c new file mode 100644 index 00000000..5996173c --- /dev/null +++ b/tests/fsmount.c @@ -0,0 +1,98 @@ +/* + * Check decoding of fsmount 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_fsmount + +# include +# include +# include +# include + +static const char *errstr; + +static long +k_fsmount(const unsigned int fs_fd, + const unsigned int flags, + const unsigned int attr_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 | fs_fd; + const kernel_ulong_t arg2 = fill | flags; + const kernel_ulong_t arg3 = fill | attr_flags; + const long rc = syscall(__NR_fsmount, + arg1, arg2, arg3, bad, bad, bad); + errstr = sprintrc(rc); + return rc; +} + +int +main(void) +{ + skip_if_unavailable("/proc/self/fd/"); + + static const char path[] = "/dev/full"; + int fd = open(path, O_WRONLY); + if (fd < 0) + perror_msg_and_fail("open: %s", path); + + struct { + unsigned int val; + const char *str; + } flags[] = { + { ARG_STR(0) }, + { 1, "FSMOUNT_CLOEXEC" }, + { 2, "0x2 /* FSMOUNT_??? */" }, + { 0xfffffffe, "0xfffffffe /* FSMOUNT_??? */" }, + { -1, "FSMOUNT_CLOEXEC|0xfffffffe" } + }, + attrs[] = { + { ARG_STR(0) }, + { 1, "MOUNT_ATTR_RDONLY" }, + { 0x10, "MOUNT_ATTR_NOATIME" }, + { 0xbf, "MOUNT_ATTR_RDONLY|MOUNT_ATTR_NOSUID|MOUNT_ATTR_NODEV" + "|MOUNT_ATTR_NOEXEC|MOUNT_ATTR_NOATIME" + "|MOUNT_ATTR_STRICTATIME|MOUNT_ATTR_NODIRATIME" }, + { 0x40, "0x40 /* MOUNT_ATTR_??? */" }, + { 0xffffff40, "0xffffff40 /* MOUNT_ATTR_??? */" }, + { -1, "MOUNT_ATTR_RDONLY|MOUNT_ATTR_NOSUID|MOUNT_ATTR_NODEV" + "|MOUNT_ATTR_NOEXEC|MOUNT_ATTR_NOATIME" + "|MOUNT_ATTR_STRICTATIME|MOUNT_ATTR_NODIRATIME" + "|0xffffff40" } + }; + + for (unsigned int i = 0; i < ARRAY_SIZE(flags); ++i) { + for (unsigned int j = 0; j < ARRAY_SIZE(attrs); ++j) { + k_fsmount(-1, flags[i].val, attrs[j].val); + printf("fsmount(-1, %s, %s) = %s\n", + flags[i].str, attrs[j].str, errstr); + + k_fsmount(-100, flags[i].val, attrs[j].val); + printf("fsmount(-100, %s, %s) = %s\n", + flags[i].str, attrs[j].str, errstr); + + k_fsmount(fd, flags[i].val, attrs[j].val); + printf("fsmount(%d<%s>, %s, %s) = %s\n", + fd, path, flags[i].str, attrs[j].str, errstr); + } + } + + puts("+++ exited with 0 +++"); + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_fsmount") + +#endif diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 7cbfc417..4e80b203 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -70,6 +70,7 @@ flock -a19 fork-f -a26 -qq -f -e signal=none -e trace=chdir fsconfig -s300 -y fsconfig-P -s300 -y -P /dev/full -e trace=fsconfig +fsmount -a18 -y fsopen -a35 fstat -a15 -v -P stat.sample fstat-Xabbrev -a15 -v -Xabbrev -P stat.sample -e trace=fstat diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 9fa551a8..e58f2941 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -73,6 +73,7 @@ finit_module flock fsconfig fsconfig-P +fsmount fsopen fstat fstat-Xabbrev diff --git a/xlat/fsmount_flags.in b/xlat/fsmount_flags.in new file mode 100644 index 00000000..8a3b95e4 --- /dev/null +++ b/xlat/fsmount_flags.in @@ -0,0 +1 @@ +FSMOUNT_CLOEXEC 1 diff --git a/xlat/mount_attr_flags.in b/xlat/mount_attr_flags.in new file mode 100644 index 00000000..f6356c19 --- /dev/null +++ b/xlat/mount_attr_flags.in @@ -0,0 +1,7 @@ +MOUNT_ATTR_RDONLY 0x01 +MOUNT_ATTR_NOSUID 0x02 +MOUNT_ATTR_NODEV 0x04 +MOUNT_ATTR_NOEXEC 0x08 +MOUNT_ATTR_NOATIME 0x10 +MOUNT_ATTR_STRICTATIME 0x20 +MOUNT_ATTR_NODIRATIME 0x80 -- 2.40.0