]> granicus.if.org Git - strace/commitdiff
Implement decoding of fsconfig syscall
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 27 Jun 2019 16:51:33 +0000 (16:51 +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~3,
v5.2-rc1~20^2~1, and v5.2-rc1~20^2.

* fsconfig.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* pathtrace.c (pathtrace_match_set): Add SEN_fsconfig.
* xlat/fsconfig_cmds.in: New file.
* linux/syscallent-common.h [BASE_NR + 431]: Wire up fsconfig.
* NEWS: Mention this change.
* tests/fsconfig.c: New file.
* tests/fsconfig-P.c: Likewise.
* tests/gen_tests.in (fsconfig, fsconfig-P): New entries.
* tests/pure_executables.list: Add fsconfig and fsconfig-P.
* tests/.gitignore: Likewise.

Makefile.am
NEWS
fsconfig.c [new file with mode: 0644]
linux/syscallent-common.h
pathtrace.c
tests/.gitignore
tests/fsconfig-P.c [new file with mode: 0644]
tests/fsconfig.c [new file with mode: 0644]
tests/gen_tests.in
tests/pure_executables.list
xlat/fsconfig_cmds.in [new file with mode: 0644]

index 9fe5055af3941fca68a40975ffe69a8f12d566d7..e22a1ced35255d2554e6a4a4820ef900591c7b8d 100644 (file)
@@ -132,6 +132,7 @@ strace_SOURCES =    \
        flock.c         \
        flock.h         \
        fs_x_ioctl.c    \
+       fsconfig.c      \
        fsopen.c        \
        futex.c         \
        gcc_compat.h    \
diff --git a/NEWS b/NEWS
index 75bed509d750a88b076bbe13e9e466acb6f0359a..ef9da37b9f81e812bf61fc9b4bbf56349ab4f880 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,8 @@ Noteworthy changes in release ?.? (????-??-??)
 ==============================================
 
 * Improvements
-  * Implemented decoding of open_tree, move_mount, and fsopen syscalls.
+  * Implemented decoding of open_tree, move_mount, fsopen, and fsconfig
+    syscalls.
   * Enhanced decoding of clone syscall.
   * Updated lists of AT_*, AUDIT_*, CLONE_*, ETH_*, KEY_*, KVM_*, TIPC_*,
     and V4L2_* constants.
diff --git a/fsconfig.c b/fsconfig.c
new file mode 100644 (file)
index 0000000..7be095b
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+#ifdef HAVE_LINUX_MOUNT_H
+# include <linux/mount.h>
+#endif
+#include "xlat/fsconfig_cmds.h"
+
+SYS_FUNC(fsconfig)
+{
+       const int fs_fd = tcp->u_arg[0];
+       const unsigned int cmd = tcp->u_arg[1];
+       const kernel_ulong_t key = tcp->u_arg[2];
+       const kernel_ulong_t value = tcp->u_arg[3];
+       const int aux = tcp->u_arg[4];
+
+       printfd(tcp, fs_fd);
+       tprints(", ");
+
+       printxval_index(fsconfig_cmds, cmd, "FSCONFIG_???");
+       tprints(", ");
+
+       switch (cmd) {
+               case FSCONFIG_SET_FLAG:
+               case FSCONFIG_SET_STRING:
+               case FSCONFIG_SET_BINARY:
+               case FSCONFIG_SET_PATH:
+               case FSCONFIG_SET_PATH_EMPTY:
+               case FSCONFIG_SET_FD:
+                       printstr_ex(tcp, key, 256, QUOTE_0_TERMINATED);
+                       break;
+               case FSCONFIG_CMD_CREATE:
+               case FSCONFIG_CMD_RECONFIGURE:
+               default:
+                       printaddr(key);
+                       break;
+       }
+       tprints(", ");
+
+       switch (cmd) {
+               case FSCONFIG_SET_STRING:
+                       printstr_ex(tcp, value, 256, QUOTE_0_TERMINATED);
+                       break;
+               case FSCONFIG_SET_PATH:
+               case FSCONFIG_SET_PATH_EMPTY:
+                       printpath(tcp, value);
+                       break;
+               case FSCONFIG_SET_BINARY:
+                       if (aux >= 0 && aux <= 1024 * 1024) {
+                               printstr_ex(tcp, value, aux, QUOTE_FORCE_HEX);
+                               break;
+                       }
+                       ATTRIBUTE_FALLTHROUGH;
+               case FSCONFIG_SET_FLAG:
+               case FSCONFIG_SET_FD:
+               case FSCONFIG_CMD_CREATE:
+               case FSCONFIG_CMD_RECONFIGURE:
+               default:
+                       printaddr(value);
+                       break;
+       }
+       tprints(", ");
+
+       switch (cmd) {
+               case FSCONFIG_SET_PATH:
+               case FSCONFIG_SET_PATH_EMPTY:
+                       print_dirfd(tcp, aux);
+                       break;
+               case FSCONFIG_SET_FD:
+                       printfd(tcp, aux);
+                       break;
+               case FSCONFIG_SET_FLAG:
+               case FSCONFIG_SET_STRING:
+               case FSCONFIG_SET_BINARY:
+               case FSCONFIG_CMD_CREATE:
+               case FSCONFIG_CMD_RECONFIGURE:
+               default:
+                       tprintf("%d", aux);
+                       break;
+       }
+
+       return RVAL_DECODED;
+}
index abad88057b3f355cc8bf67793c5be0c65b6ceb00..c2e844eae7decfa8d9e54939089fce71daec148e 100644 (file)
@@ -15,3 +15,4 @@
 [BASE_NR + 428] = { 3, TD|TF,          SEN(open_tree),                 "open_tree"             },
 [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"              },
index 6de690e9f45333c98e417d285485397e577ff5a5..3c09bc3282d0f18a9d1e50c60c938b304293cbc9 100644 (file)
@@ -318,6 +318,21 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set)
                return false;
        }
 
+       case SEN_fsconfig: {
+               /* x, x, x, maybe path, maybe fd */
+               const unsigned int cmd = tcp->u_arg[1];
+               switch (cmd) {
+                       case 3 /* FSCONFIG_SET_PATH */:
+                       case 4 /* FSCONFIG_SET_PATH_EMPTY */:
+                               return fdmatch(tcp, tcp->u_arg[4], set) ||
+                                       upathmatch(tcp, tcp->u_arg[3], set);
+                       case 5 /* FSCONFIG_SET_FD */:
+                               return fdmatch(tcp, tcp->u_arg[4], set);
+               }
+
+               return false;
+       }
+
        case SEN_accept4:
        case SEN_accept:
        case SEN_bpf:
index c0d5bd7b072110d84fe52c35f5adc3a973691815..2b8e500acb76cc8fb9891febe79bb7020b9ffe1e 100644 (file)
@@ -89,6 +89,8 @@ filter-unavailable
 finit_module
 flock
 fork-f
+fsconfig
+fsconfig-P
 fsopen
 fstat
 fstat-Xabbrev
diff --git a/tests/fsconfig-P.c b/tests/fsconfig-P.c
new file mode 100644 (file)
index 0000000..b763332
--- /dev/null
@@ -0,0 +1,2 @@
+#define PATH_TRACING
+#include "fsconfig.c"
diff --git a/tests/fsconfig.c b/tests/fsconfig.c
new file mode 100644 (file)
index 0000000..e5ece51
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Check decoding of fsconfig 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_fsconfig
+
+# include <fcntl.h>
+# include <limits.h>
+# include <stdio.h>
+# include <stdint.h>
+# include <unistd.h>
+
+# define XLAT_MACROS_ONLY
+# include "xlat/fsconfig_cmds.h"
+# undef XLAT_MACROS_ONLY
+
+static const char *errstr;
+
+static long
+k_fsconfig(const unsigned int fs_fd,
+          const unsigned int cmd,
+          const void *key,
+          const void *value,
+          const unsigned int aux)
+{
+       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 | cmd;
+       const kernel_ulong_t arg3 = (uintptr_t) key;
+       const kernel_ulong_t arg4 = (uintptr_t) value;
+       const kernel_ulong_t arg5 = fill | aux;
+       const long rc = syscall(__NR_fsconfig,
+                               arg1, arg2, arg3, arg4, arg5, bad);
+       errstr = sprintrc(rc);
+       return rc;
+}
+
+static const char path_full[] = "/dev/full";
+static const int max_string_size = 256;
+static const int max_blob_size = 300;
+static const int huge_blob_size = 1024 * 1024 + 1;
+static const char *fd_path;
+static const void *efault;
+static const char *empty;
+static char *fname;
+static char *key1;
+static char *key;
+static char *val1;
+static char *val;
+static char *blob1;
+static char *blob;
+static int fd;
+
+static void
+test_fsconfig_unknown(void)
+{
+       k_fsconfig(fd, 8, empty, val, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, 0x8 /* FSCONFIG_??? */, %p, %p, -100) = %s\n",
+              fd, fd_path, empty, val, errstr);
+# endif
+
+       k_fsconfig(-100, -1, empty, fd_path, fd);
+# ifndef PATH_TRACING
+       printf("fsconfig(-100, 0xffffffff /* FSCONFIG_??? */, %p, %p, %d)"
+              " = %s\n",
+              empty, fd_path, fd, errstr);
+# endif
+}
+
+static void
+test_fsconfig_cmd(const unsigned int cmd, const char *cmd_str)
+{
+       k_fsconfig(fd, cmd, empty, val, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, %p, %p, -100) = %s\n",
+              fd, fd_path, cmd_str, empty, val, errstr);
+# endif
+
+       k_fsconfig(-100, cmd, empty, fd_path, fd);
+# ifndef PATH_TRACING
+       printf("fsconfig(-100, %s, %p, %p, %d) = %s\n",
+              cmd_str, empty, fd_path, fd, errstr);
+# endif
+}
+
+static void
+test_fsconfig_set_flag(const unsigned int cmd, const char *cmd_str)
+{
+       k_fsconfig(fd, cmd, key, val, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", %p, -100) = %s\n",
+              fd, fd_path, cmd_str, key, val, errstr);
+# endif
+
+       k_fsconfig(fd, cmd, key1, val, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%.*s\"..., %p, -100) = %s\n",
+              fd, fd_path, cmd_str, max_string_size, key1, val, errstr);
+# endif
+
+       k_fsconfig(-100, cmd, key, fd_path, fd);
+# ifndef PATH_TRACING
+       printf("fsconfig(-100, %s, \"%s\", %p, %d) = %s\n",
+              cmd_str, key, fd_path, fd, errstr);
+# endif
+}
+
+static void
+test_fsconfig_set_string(const unsigned int cmd, const char *cmd_str)
+{
+       k_fsconfig(fd, cmd, key, val, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", \"%s\", -100) = %s\n",
+              fd, fd_path, cmd_str, key, val, errstr);
+# endif
+
+       k_fsconfig(fd, cmd, key1, val1, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%.*s\"..., \"%.*s\"..., -100) = %s\n",
+              fd, fd_path, cmd_str, max_string_size, key1, max_string_size, val1,
+              errstr);
+# endif
+
+       k_fsconfig(-100, cmd, key, fd_path, fd);
+# ifndef PATH_TRACING
+       printf("fsconfig(-100, %s, \"%s\", \"%s\", %d) = %s\n",
+              cmd_str, key, fd_path, fd, errstr);
+# endif
+}
+
+static void
+test_fsconfig_set_binary(const unsigned int cmd, const char *cmd_str)
+{
+       k_fsconfig(fd, cmd, key, blob, max_blob_size);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", ", fd, fd_path, cmd_str, key);
+       print_quoted_hex(blob, max_blob_size);
+       printf(", %d) = %s\n", max_blob_size, errstr);
+# endif
+
+       k_fsconfig(fd, cmd, key1, blob1, max_blob_size + 1);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%.*s\"..., ",
+              fd, fd_path, cmd_str, max_string_size, key1);
+       print_quoted_hex(blob1, max_blob_size);
+       printf("..., %d) = %s\n", max_blob_size + 1, errstr);
+# endif
+
+       k_fsconfig(fd, cmd, key, empty, 0);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", \"\", 0) = %s\n",
+              fd, fd_path, cmd_str, key, errstr);
+# endif
+
+       k_fsconfig(fd, cmd, key, fname, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", %p, -100) = %s\n",
+              fd, fd_path, cmd_str, key, fname, errstr);
+# endif
+
+       k_fsconfig(fd, cmd, key, fname, huge_blob_size);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", %p, %d) = %s\n",
+              fd, fd_path, cmd_str, key, fname, huge_blob_size, errstr);
+# endif
+
+       k_fsconfig(-100, cmd, key, fd_path, sizeof(path_full));
+# ifndef PATH_TRACING
+       printf("fsconfig(-100, %s, \"%s\", ", cmd_str, key);
+       print_quoted_hex(fd_path, sizeof(path_full));
+       printf(", %d) = %s\n", (int) sizeof(path_full), errstr);
+# endif
+
+       k_fsconfig(-100, cmd, key, fname, fd);
+# ifndef PATH_TRACING
+       printf("fsconfig(-100, %s, \"%s\", ", cmd_str, key);
+       print_quoted_hex(fname, fd);
+       printf(", %d) = %s\n", fd, errstr);
+# endif
+}
+
+static void
+test_fsconfig_set_path(const unsigned int cmd, const char *cmd_str)
+{
+       fill_memory_ex(fname, PATH_MAX, '0', 10);
+       k_fsconfig(fd, cmd, key, fname, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", \"%.*s\"..., AT_FDCWD) = %s\n",
+              fd, fd_path, cmd_str, key, (int) PATH_MAX - 1, fname, errstr);
+# endif
+
+       fname[PATH_MAX - 1] = '\0';
+       k_fsconfig(fd, cmd, key, fname, -1);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", \"%s\", -1) = %s\n",
+              fd, fd_path, cmd_str, key, fname, errstr);
+# endif
+
+       k_fsconfig(-100, cmd, key, empty, fd);
+       printf("fsconfig(-100, %s, \"%s\", \"\", %d<%s>) = %s\n",
+              cmd_str, key, fd, fd_path, errstr);
+
+       k_fsconfig(-1, cmd, 0, fd_path, -100);
+       printf("fsconfig(-1, %s, NULL, \"%s\", AT_FDCWD) = %s\n",
+              cmd_str, fd_path, errstr);
+
+       k_fsconfig(-1, cmd, efault, efault + 1, fd);
+       printf("fsconfig(-1, %s, %p, %p, %d<%s>) = %s\n",
+              cmd_str, efault, efault + 1, fd, fd_path, errstr);
+
+       k_fsconfig(-100, cmd, key, fname, -1);
+# ifndef PATH_TRACING
+       printf("fsconfig(-100, %s, \"%s\", \"%s\", -1) = %s\n",
+              cmd_str, key, fname, errstr);
+# endif
+}
+
+static void
+test_fsconfig_set_fd(const unsigned int cmd, const char *cmd_str)
+{
+       k_fsconfig(fd, cmd, key, val, -100);
+# ifndef PATH_TRACING
+       printf("fsconfig(%d<%s>, %s, \"%s\", %p, -100) = %s\n",
+              fd, fd_path, cmd_str, key, val, errstr);
+# endif
+
+       k_fsconfig(-100, cmd, key1, 0, fd);
+       printf("fsconfig(-100, %s, \"%.*s\"..., NULL, %d<%s>) = %s\n",
+              cmd_str, max_string_size, key1, fd, fd_path, errstr);
+
+       k_fsconfig(-1, cmd, efault, efault + 1, fd);
+       printf("fsconfig(-1, %s, %p, %p, %d<%s>) = %s\n",
+              cmd_str, efault, efault + 1, fd, fd_path, errstr);
+
+       k_fsconfig(-100, cmd, key, fd_path, -1);
+# ifndef PATH_TRACING
+       printf("fsconfig(-100, %s, \"%s\", %p, -1) = %s\n",
+              cmd_str, key, fd_path, errstr);
+# endif
+}
+
+int
+main(void)
+{
+       skip_if_unavailable("/proc/self/fd/");
+
+       fd_path = tail_memdup(path_full, sizeof(path_full));
+       efault = fd_path + sizeof(path_full);
+       empty = efault - 1;
+       fname = tail_alloc(PATH_MAX);
+       key1 = tail_alloc(max_string_size + 1);
+       key = key1 + 1;
+       val1 = tail_alloc(max_string_size + 1);
+       val = val1 + 1;
+       blob1 = tail_alloc(max_blob_size + 1);
+       blob = blob1 + 1;
+
+       fill_memory_ex(fname, PATH_MAX, '0', 10);
+       fill_memory_ex(key1, max_string_size, 'a', 'z' - 'a' + 1);
+       key1[max_string_size] = '\0';
+       fill_memory_ex(val1, max_string_size, 'A', 'Z' - 'A' + 1);
+       val1[max_string_size] = '\0';
+       fill_memory_ex(blob, max_blob_size, '0', 10);
+       blob[0] = 0;
+       blob1[0] = 0;
+        fd = open(fd_path, O_WRONLY);
+        if (fd < 0)
+                perror_msg_and_fail("open: %s", fd_path);
+
+       test_fsconfig_unknown();
+       test_fsconfig_set_flag(ARG_STR(FSCONFIG_SET_FLAG));
+       test_fsconfig_set_string(ARG_STR(FSCONFIG_SET_STRING));
+       test_fsconfig_set_binary(ARG_STR(FSCONFIG_SET_BINARY));
+       test_fsconfig_set_path(ARG_STR(FSCONFIG_SET_PATH));
+       test_fsconfig_set_path(ARG_STR(FSCONFIG_SET_PATH_EMPTY));
+       test_fsconfig_set_fd(ARG_STR(FSCONFIG_SET_FD));
+       test_fsconfig_cmd(ARG_STR(FSCONFIG_CMD_CREATE));
+       test_fsconfig_cmd(ARG_STR(FSCONFIG_CMD_RECONFIGURE));
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_fsconfig")
+
+#endif
index f2377556628b5a5fd2f393f84b8f4cefae72b042..7cbfc417a1cfcf0c8565241e415b45338d84e69a 100644 (file)
@@ -68,6 +68,8 @@ file_ioctl    +ioctl.test
 finit_module   -a25
 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
 fsopen -a35
 fstat  -a15 -v -P stat.sample
 fstat-Xabbrev -a15 -v -Xabbrev -P stat.sample -e trace=fstat
index 9f57ad5612de2022288a886bdc01ab82a593c6e1..9fa551a8b3f32ce00ac74cbd3c8e4d01cf835d40 100755 (executable)
@@ -71,6 +71,8 @@ file_handle
 file_ioctl
 finit_module
 flock
+fsconfig
+fsconfig-P
 fsopen
 fstat
 fstat-Xabbrev
diff --git a/xlat/fsconfig_cmds.in b/xlat/fsconfig_cmds.in
new file mode 100644 (file)
index 0000000..be33679
--- /dev/null
@@ -0,0 +1,9 @@
+#value_indexed
+FSCONFIG_SET_FLAG              0
+FSCONFIG_SET_STRING            1
+FSCONFIG_SET_BINARY            2
+FSCONFIG_SET_PATH              3
+FSCONFIG_SET_PATH_EMPTY                4
+FSCONFIG_SET_FD                        5
+FSCONFIG_CMD_CREATE            6
+FSCONFIG_CMD_RECONFIGURE       7