diff options
author | Renaud Métrich <rmetrich@redhat.com> | 2021-09-19 15:20:37 +0200 |
---|---|---|
committer | Dmitry V. Levin <ldv@strace.io> | 2021-11-28 20:00:00 +0000 |
commit | 48de116c270d011fc98feb3a01bbfe72eb2d3c88 (patch) | |
tree | 7f08a291afa0f0d992b88ad30420842e8395ced9 | |
parent | 9d043d7491e246b1cc8bf2c537e1e0234ecfefbd (diff) | |
download | strace-48de116c270d011fc98feb3a01bbfe72eb2d3c88.tar.gz |
Print cwd path for AT_FDCWD when -y (--decode-fd=path) option is used
When syscalls use AT_FDCWD (e.g. openat()), the corresponding current
working directory is not always obvious, one might need to search back
for chdir() syscalls in the process or some of its parents.
With this change, the current working directory corresponding to
AT_FDCWD is printed when -y (--decode-fd=path) option is used, e.g.:
openat(AT_FDCWD</home/rmetrich/GIT/strace>, "/lib64/libselinux.so.1" ...)
* src/open.c: Include "number_set.h".
(print_dirfd) <fd == AT_FDCWD>: Print the current working directory of
tracee when DECODE_FD_PATH is set.
* tests/dev-yy.c [!PRINT_AT_FDCWD_PATH] (PRINT_AT_FDCWD_PATH):
New macro.
(main): Update expected output.
* tests/dev--decode-fds-all.c (PRINT_DEVNUM): New macro.
Include "dev-yy.c" instead of "dev--decode-fds-dev.c".
* tests/dev--decode-fds-dev.c (PRINT_AT_FDCWD_PATH): New macro.
* tests/dev--decode-fds-path.c (PRINT_AT_FDCWD_PATH): Likewise.
* tests/faccessat.c (AT_FDCWD_FMT, AT_FDCWD_ARG): New macros.
(tests_with_existing_file, main): Update expected output.
* tests/faccessat2.c (YFLAG): New macro.
(main): Update expected output.
* tests/fsconfig.c (test_fsconfig_set_path): Update expected output.
* tests/fspick.c (main): Likewise.
* tests/mount_setattr.c (main): Likewise.
* tests/move_mount.c (main): Likewise.
* tests/open_tree.c (main): Likewise.
* tests/openat2.c (YFLAG, AT_FDCWD_FMT, AT_FDCWD_ARG): New macros.
(main): Update expected output.
Co-authored-by: Dmitry V. Levin <ldv@strace.io>
Resolves: https://github.com/strace/strace/issues/194
-rw-r--r-- | src/open.c | 29 | ||||
-rw-r--r-- | tests/dev--decode-fds-all.c | 3 | ||||
-rw-r--r-- | tests/dev--decode-fds-dev.c | 1 | ||||
-rw-r--r-- | tests/dev--decode-fds-path.c | 1 | ||||
-rw-r--r-- | tests/dev-yy.c | 16 | ||||
-rw-r--r-- | tests/faccessat.c | 27 | ||||
-rw-r--r-- | tests/faccessat2.c | 11 | ||||
-rw-r--r-- | tests/fsconfig.c | 11 | ||||
-rw-r--r-- | tests/fspick.c | 7 | ||||
-rw-r--r-- | tests/mount_setattr.c | 7 | ||||
-rw-r--r-- | tests/move_mount.c | 46 | ||||
-rw-r--r-- | tests/open_tree.c | 7 | ||||
-rw-r--r-- | tests/openat2.c | 27 |
13 files changed, 147 insertions, 46 deletions
diff --git a/src/open.c b/src/open.c index 1dd79e9dc..d7654d7e8 100644 --- a/src/open.c +++ b/src/open.c @@ -16,6 +16,7 @@ #include "defs.h" #include "xstring.h" #include "kernel_fcntl.h" +#include "number_set.h" #include <linux/openat2.h> #include <linux/fcntl.h> @@ -29,10 +30,34 @@ void print_dirfd(struct tcb *tcp, int fd) { - if (fd == AT_FDCWD) + if (fd == AT_FDCWD) { print_xlat_d(AT_FDCWD); - else + + if (!is_number_in_set(DECODE_FD_PATH, decode_fd_set)) + goto done; + + int proc_pid = get_proc_pid(tcp->pid); + if (!proc_pid) + goto done; + + static const char cwd_path[] = "/proc/%u/cwd"; + char linkpath[sizeof(cwd_path) + sizeof(int) * 3]; + xsprintf(linkpath, cwd_path, proc_pid); + + char buf[PATH_MAX]; + ssize_t n = readlink(linkpath, buf, sizeof(buf)); + if ((size_t) n >= sizeof(buf)) + goto done; + + tprints("<"); + print_quoted_string_ex(buf, n, + QUOTE_OMIT_LEADING_TRAILING_QUOTES, + "<>"); + tprints(">"); +done: ; + } else { printfd(tcp, fd); + } #ifdef ENABLE_SECONTEXT tcp->last_dirfd = fd; #endif diff --git a/tests/dev--decode-fds-all.c b/tests/dev--decode-fds-all.c index f159f1ed2..eb8eb5e8b 100644 --- a/tests/dev--decode-fds-all.c +++ b/tests/dev--decode-fds-all.c @@ -1 +1,2 @@ -#include "dev--decode-fds-dev.c" +#define PRINT_DEVNUM 1 +#include "dev-yy.c" diff --git a/tests/dev--decode-fds-dev.c b/tests/dev--decode-fds-dev.c index eb8eb5e8b..22f7af67c 100644 --- a/tests/dev--decode-fds-dev.c +++ b/tests/dev--decode-fds-dev.c @@ -1,2 +1,3 @@ #define PRINT_DEVNUM 1 +#define PRINT_AT_FDCWD_PATH 0 #include "dev-yy.c" diff --git a/tests/dev--decode-fds-path.c b/tests/dev--decode-fds-path.c index 2a5fa1297..e75ab41f6 100644 --- a/tests/dev--decode-fds-path.c +++ b/tests/dev--decode-fds-path.c @@ -1,2 +1,3 @@ #define PRINT_DEVNUM 0 +#define PRINT_AT_FDCWD_PATH 1 #include "dev-yy.c" diff --git a/tests/dev-yy.c b/tests/dev-yy.c index 4cf90587f..9dcdb04d6 100644 --- a/tests/dev-yy.c +++ b/tests/dev-yy.c @@ -30,6 +30,10 @@ # endif #endif +#ifndef PRINT_AT_FDCWD_PATH +# define PRINT_AT_FDCWD_PATH PRINT_DEVNUM +#endif + #if PRINT_DEVNUM # define DEV_FMT "<%s<%s %u:%u>>" #elif PRINT_PATH @@ -44,6 +48,9 @@ int main(void) { skip_if_unavailable("/proc/self/fd/"); +# if PRINT_AT_FDCWD_PATH + char *cwd = get_fd_path(get_dir_fd(".")); +# endif static const struct { const char *path; @@ -66,7 +73,14 @@ main(void) long fd = syscall(__NR_openat, AT_FDCWD, checks[i].path, O_RDONLY|O_PATH); - printf("openat(AT_FDCWD, \"%s\", O_RDONLY|O_PATH) = %s", + printf("openat(AT_FDCWD" +# if PRINT_AT_FDCWD_PATH + "<%s>" +# endif + ", \"%s\", O_RDONLY|O_PATH) = %s", +# if PRINT_AT_FDCWD_PATH + cwd, +# endif checks[i].path, sprintrc(fd)); # if PRINT_PATH if (fd >= 0) diff --git a/tests/faccessat.c b/tests/faccessat.c index 9ce7a07ce..5850a4d00 100644 --- a/tests/faccessat.c +++ b/tests/faccessat.c @@ -28,6 +28,14 @@ # define SKIP_IF_PROC_IS_UNAVAILABLE # endif +# ifdef YFLAG +# define AT_FDCWD_FMT "<%s>" +# define AT_FDCWD_ARG(arg) arg, +# else +# define AT_FDCWD_FMT +# define AT_FDCWD_ARG(arg) +# endif + static const char *errstr; static long @@ -57,6 +65,9 @@ tests_with_existing_file(void) */ create_and_enter_subdir("faccessat_subdir"); + int cwd_fd = get_dir_fd("."); + char *cwd = get_fd_path(cwd_fd); + char *my_secontext = SECONTEXT_PID_MY(); k_faccessat(-1, NULL, F_OK); @@ -76,8 +87,9 @@ tests_with_existing_file(void) */ k_faccessat(-100, sample, F_OK); - printf("%s%s(AT_FDCWD, \"%s\"%s, F_OK) = %s\n", + printf("%s%s(AT_FDCWD" AT_FDCWD_FMT ", \"%s\"%s, F_OK) = %s\n", my_secontext, "faccessat", + AT_FDCWD_ARG(cwd) sample, sample_secontext, errstr); @@ -85,8 +97,9 @@ tests_with_existing_file(void) perror_msg_and_fail("unlink"); k_faccessat(-100, sample, F_OK); - printf("%s%s(AT_FDCWD, \"%s\", F_OK) = %s\n", + printf("%s%s(AT_FDCWD" AT_FDCWD_FMT ", \"%s\", F_OK) = %s\n", my_secontext, "faccessat", + AT_FDCWD_ARG(cwd) sample, errstr); @@ -94,8 +107,6 @@ tests_with_existing_file(void) * Tests with dirfd. */ - int cwd_fd = get_dir_fd("."); - char *cwd = get_fd_path(cwd_fd); char *cwd_secontext = SECONTEXT_FILE("."); char *sample_realpath = xasprintf("%s/%s", cwd, sample); @@ -196,6 +207,12 @@ main(void) if (fd < 0) perror_msg_and_fail("open: %s", path); char *fd_str = xasprintf("%d%s", fd, FD_PATH); + const char *at_fdcwd_str = +# ifdef YFLAG + xasprintf("AT_FDCWD<%s>", get_fd_path(get_dir_fd("."))); +# else + "AT_FDCWD"; +# endif char *path_quoted = xasprintf("\"%s\"", path); struct { @@ -203,7 +220,7 @@ main(void) const char *str; } dirfds[] = { { ARG_STR(-1) }, - { -100, "AT_FDCWD" }, + { -100, at_fdcwd_str }, { fd, fd_str }, }, modes[] = { { ARG_STR(F_OK) }, diff --git a/tests/faccessat2.c b/tests/faccessat2.c index d35b9d8e8..2a994e2e0 100644 --- a/tests/faccessat2.c +++ b/tests/faccessat2.c @@ -21,6 +21,8 @@ #ifndef FD_PATH # define FD_PATH "" +#else +# define YFLAG #endif #ifndef SKIP_IF_PROC_IS_UNAVAILABLE # define SKIP_IF_PROC_IS_UNAVAILABLE @@ -77,6 +79,13 @@ main(void) if (fd < 0) perror_msg_and_fail("open: %s", path); char *fd_str = xasprintf("%d%s", fd, FD_PATH); + const char *at_fdcwd_str = +#ifdef YFLAG + xasprintf("AT_FDCWD<%s>", get_fd_path(get_dir_fd("."))); +#else + "AT_FDCWD"; +#endif + char *path_quoted = xasprintf("\"%s\"", path); struct { @@ -84,7 +93,7 @@ main(void) const char *str; } dirfds[] = { { ARG_STR(-1) }, - { -100, "AT_FDCWD" }, + { -100, at_fdcwd_str }, { fd, fd_str }, }, modes[] = { { ARG_STR(F_OK) }, diff --git a/tests/fsconfig.c b/tests/fsconfig.c index 2cd14452d..feee7ccfa 100644 --- a/tests/fsconfig.c +++ b/tests/fsconfig.c @@ -187,11 +187,14 @@ test_fsconfig_set_binary(const unsigned int cmd, const char *cmd_str) static void test_fsconfig_set_path(const unsigned int cmd, const char *cmd_str) { + char *cwd = get_fd_path(get_dir_fd(".")); + 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); + printf("fsconfig(%d<%s>, %s, \"%s\", \"%.*s\"..., AT_FDCWD<%s>) = %s\n", + fd, fd_path, cmd_str, key, (int) PATH_MAX - 1, fname, cwd, + errstr); #endif fname[PATH_MAX - 1] = '\0'; @@ -206,8 +209,8 @@ test_fsconfig_set_path(const unsigned int cmd, const char *cmd_str) 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); + printf("fsconfig(-1, %s, NULL, \"%s\", AT_FDCWD<%s>) = %s\n", + cmd_str, fd_path, cwd, errstr); k_fsconfig(-1, cmd, efault, efault + 1, fd); printf("fsconfig(-1, %s, %p, %p, %d<%s>) = %s\n", diff --git a/tests/fspick.c b/tests/fspick.c index 9dd6c9c8f..7d7f48de1 100644 --- a/tests/fspick.c +++ b/tests/fspick.c @@ -38,6 +38,9 @@ main(void) { skip_if_unavailable("/proc/self/fd/"); +#ifndef PATH_TRACING + char *cwd = get_fd_path(get_dir_fd(".")); +#endif 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); @@ -56,8 +59,8 @@ main(void) k_fspick(-100, fname, 0); #ifndef PATH_TRACING - printf("fspick(%s, \"%.*s\"..., 0) = %s\n", - "AT_FDCWD", (int) PATH_MAX - 1, fname, errstr); + printf("fspick(AT_FDCWD<%s>, \"%.*s\"..., 0) = %s\n", + cwd, (int) PATH_MAX - 1, fname, errstr); #endif fname[PATH_MAX - 1] = '\0'; diff --git a/tests/mount_setattr.c b/tests/mount_setattr.c index 5532d7527..55fe10305 100644 --- a/tests/mount_setattr.c +++ b/tests/mount_setattr.c @@ -45,6 +45,9 @@ main(void) { skip_if_unavailable("/proc/self/fd/"); +#ifndef PATH_TRACING + char *cwd = get_fd_path(get_dir_fd(".")); +#endif 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); @@ -65,8 +68,8 @@ main(void) k_mount_setattr(-100, fname, 0, attr, MOUNT_ATTR_SIZE_VER0 - 1); #ifndef PATH_TRACING - printf("mount_setattr(%s, \"%.*s\"..., 0, %p, %u) = %s\n", - "AT_FDCWD", (int) PATH_MAX - 1, fname, + printf("mount_setattr(AT_FDCWD<%s>, \"%.*s\"..., 0, %p, %u) = %s\n", + cwd, (int) PATH_MAX - 1, fname, attr, MOUNT_ATTR_SIZE_VER0 - 1, rcstr); #endif diff --git a/tests/move_mount.c b/tests/move_mount.c index 76dda17f6..903afda18 100644 --- a/tests/move_mount.c +++ b/tests/move_mount.c @@ -41,6 +41,7 @@ main(void) { skip_if_unavailable("/proc/self/fd/"); + char *cwd = get_fd_path(get_dir_fd(".")); static const char path_full[] = "/dev/full"; const char *const path = tail_memdup(path_full, sizeof(path_full)); const void *const efault = path + sizeof(path_full); @@ -54,52 +55,55 @@ main(void) k_move_mount(-1, 0, -100, efault, 0); #ifndef PATH_TRACING - printf("move_mount(-1, NULL, AT_FDCWD, %p, 0) = %s\n", efault, errstr); + printf("move_mount(-1, NULL, AT_FDCWD<%s>, %p, 0) = %s\n", + cwd, efault, errstr); #endif k_move_mount(-100, efault, -1, 0, 0); #ifndef PATH_TRACING - printf("move_mount(AT_FDCWD, %p, -1, NULL, 0) = %s\n", efault, errstr); + printf("move_mount(AT_FDCWD<%s>, %p, -1, NULL, 0) = %s\n", + cwd, efault, errstr); #endif k_move_mount(dfd, fname, -100, empty, 1); - printf("move_mount(%d<%s>, \"%.*s\"..., AT_FDCWD, \"\", %s) = %s\n", - dfd, path, (int) PATH_MAX - 1, fname, "MOVE_MOUNT_F_SYMLINKS", - errstr); + printf("move_mount(%d<%s>, \"%.*s\"..., AT_FDCWD<%s>, \"\", %s) = %s\n", + dfd, path, (int) PATH_MAX - 1, fname, cwd, + "MOVE_MOUNT_F_SYMLINKS", errstr); k_move_mount(-100, empty, dfd, fname, 0x10); - printf("move_mount(AT_FDCWD, \"\", %d<%s>, \"%.*s\"..., %s) = %s\n", - dfd, path, (int) PATH_MAX - 1, fname, "MOVE_MOUNT_T_SYMLINKS", - errstr); + printf("move_mount(AT_FDCWD<%s>, \"\", %d<%s>, \"%.*s\"..., %s) = %s\n", + cwd, dfd, path, (int) PATH_MAX - 1, fname, + "MOVE_MOUNT_T_SYMLINKS", errstr); k_move_mount(-100, empty, dfd, fname, 0x100); - printf("move_mount(AT_FDCWD, \"\", %d<%s>, \"%.*s\"..., %s) = %s\n", - dfd, path, (int) PATH_MAX - 1, fname, "MOVE_MOUNT_SET_GROUP", - errstr); + printf("move_mount(AT_FDCWD<%s>, \"\", %d<%s>, \"%.*s\"..., %s) = %s\n", + cwd, dfd, path, (int) PATH_MAX - 1, fname, + "MOVE_MOUNT_SET_GROUP", errstr); #define f_flags_str "MOVE_MOUNT_F_SYMLINKS|MOVE_MOUNT_F_AUTOMOUNTS|MOVE_MOUNT_F_EMPTY_PATH" fname[PATH_MAX - 1] = '\0'; k_move_mount(dfd, fname, -100, empty, 7); - printf("move_mount(%d<%s>, \"%s\", AT_FDCWD, \"\", %s) = %s\n", - dfd, path, fname, f_flags_str, errstr); + printf("move_mount(%d<%s>, \"%s\", AT_FDCWD<%s>, \"\", %s) = %s\n", + dfd, path, fname, cwd, f_flags_str, errstr); #define t_flags_str "MOVE_MOUNT_T_SYMLINKS|MOVE_MOUNT_T_AUTOMOUNTS|MOVE_MOUNT_T_EMPTY_PATH" k_move_mount(-100, empty, dfd, fname, 0x70); - printf("move_mount(AT_FDCWD, \"\", %d<%s>, \"%s\", %s) = %s\n", - dfd, path, fname, t_flags_str, errstr); + printf("move_mount(AT_FDCWD<%s>, \"\", %d<%s>, \"%s\", %s) = %s\n", + cwd, dfd, path, fname, t_flags_str, errstr); #define set_group_str "MOVE_MOUNT_SET_GROUP" k_move_mount(-100, empty, dfd, fname, 0x100); - printf("move_mount(AT_FDCWD, \"\", %d<%s>, \"%s\", %s) = %s\n", - dfd, path, fname, set_group_str, errstr); + printf("move_mount(AT_FDCWD<%s>, \"\", %d<%s>, \"%s\", %s) = %s\n", + cwd, dfd, path, fname, set_group_str, errstr); k_move_mount(-1, path, -100, empty, 0x177); - printf("move_mount(-1, \"%s\", AT_FDCWD, \"\", %s) = %s\n", - path, f_flags_str "|" t_flags_str "|" set_group_str, errstr); + printf("move_mount(-1, \"%s\", AT_FDCWD<%s>, \"\", %s) = %s\n", + path, cwd, f_flags_str "|" t_flags_str "|" set_group_str, + errstr); k_move_mount(-100, empty, -1, path, -1); - printf("move_mount(AT_FDCWD, \"\", -1, \"%s\", %s) = %s\n", - path, + printf("move_mount(AT_FDCWD<%s>, \"\", -1, \"%s\", %s) = %s\n", + cwd, path, f_flags_str "|" t_flags_str "|" set_group_str "|0xfffffe88", errstr); diff --git a/tests/open_tree.c b/tests/open_tree.c index f88d1dd01..a2025fc7d 100644 --- a/tests/open_tree.c +++ b/tests/open_tree.c @@ -39,6 +39,9 @@ main(void) { skip_if_unavailable("/proc/self/fd/"); +#ifndef PATH_TRACING + char *cwd = get_fd_path(get_dir_fd(".")); +#endif 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); @@ -57,8 +60,8 @@ main(void) 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); + printf("open_tree(AT_FDCWD<%s>, \"%.*s\"..., 0) = %s\n", + cwd, (int) PATH_MAX - 1, fname, errstr); #endif fname[PATH_MAX - 1] = '\0'; diff --git a/tests/openat2.c b/tests/openat2.c index 2b6511463..beae992ce 100644 --- a/tests/openat2.c +++ b/tests/openat2.c @@ -23,11 +23,21 @@ #endif #ifndef FD0_PATH # define FD0_PATH "" +#else +# define YFLAG #endif #ifndef SKIP_IF_PROC_IS_UNAVAILABLE # define SKIP_IF_PROC_IS_UNAVAILABLE #endif +#ifdef YFLAG +# define AT_FDCWD_FMT "<%s>" +# define AT_FDCWD_ARG(arg) arg, +#else +# define AT_FDCWD_FMT +# define AT_FDCWD_ARG(arg) +#endif + static const char sample[] = "openat2.sample"; int @@ -35,6 +45,9 @@ main(void) { SKIP_IF_PROC_IS_UNAVAILABLE; +# ifdef YFLAG + char *cwd = get_fd_path(get_dir_fd(".")); +# endif long rc; const char *rcstr; struct open_how *how = tail_alloc(sizeof(*how)); @@ -47,8 +60,10 @@ main(void) sprintrc(rc)); rc = syscall(__NR_openat2, -100, "", how + 1, sizeof(*how)); - printf("openat2(%s, \"\", %p, %zu) = %s\n", - XLAT_KNOWN(-100, "AT_FDCWD"), how + 1, sizeof(*how), + printf("openat2(%s" AT_FDCWD_FMT ", \"\", %p, %zu) = %s\n", + XLAT_KNOWN(-100, "AT_FDCWD"), + AT_FDCWD_ARG(cwd) + how + 1, sizeof(*how), sprintrc(rc)); rc = syscall(__NR_openat2, -1, sample, how, 11); @@ -121,9 +136,11 @@ main(void) how->mode = 0; how->resolve = 0; rc = syscall(__NR_openat2, -100, "/dev/full", how, sizeof(*how)); - printf("openat2(%s, \"/dev/full\", {flags=%s, resolve=0}, %zu)" - " = %s%s\n", - XLAT_KNOWN(-100, "AT_FDCWD"), XLAT_STR(O_RDONLY|O_NOCTTY), + printf("openat2(%s" AT_FDCWD_FMT ", \"/dev/full\"" + ", {flags=%s, resolve=0}, %zu) = %s%s\n", + XLAT_KNOWN(-100, "AT_FDCWD"), + AT_FDCWD_ARG(cwd) + XLAT_STR(O_RDONLY|O_NOCTTY), sizeof(*how), sprintrc(rc), rc >= 0 ? FD0_PATH : ""); puts("+++ exited with 0 +++"); |