From: Dmitry V. Levin Date: Thu, 20 Jun 2019 09:49:27 +0000 (+0000) Subject: Implement decoding of CLONE_PIDFD flag of clone syscall X-Git-Tag: v5.2~52 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b28e9837acf9dc508801d58d641bf5ef7f1e9113;p=strace Implement decoding of CLONE_PIDFD flag of clone syscall * clone.c (SYS_FUNC(clone)): Print pidfd returned by the kernel when CLONE_PIDFD flag is set. * tests/clone-flags.c (main): Check it. --- diff --git a/clone.c b/clone.c index 66be1645..e74a53ce 100644 --- a/clone.c +++ b/clone.c @@ -116,13 +116,18 @@ SYS_FUNC(clone) * I'm trying to figure out whether there is a *legitimate* * use of this flag which we should respect. */ - if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID + if ((flags & (CLONE_PARENT_SETTID|CLONE_PIDFD|CLONE_CHILD_SETTID |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0) return RVAL_DECODED; } else { - if (flags & CLONE_PARENT_SETTID) { + if (flags & (CLONE_PARENT_SETTID|CLONE_PIDFD)) { + kernel_ulong_t addr = tcp->u_arg[ARG_PTID]; + tprints(", parent_tid="); - printnum_int(tcp, tcp->u_arg[ARG_PTID], "%u"); + if (flags & CLONE_PARENT_SETTID) + printnum_int(tcp, addr, "%u"); + else + printnum_fd(tcp, addr); } if (flags & CLONE_SETTLS) { tprints(", tls="); diff --git a/tests/clone-flags.c b/tests/clone-flags.c index c6fb49be..b7475cfd 100644 --- a/tests/clone-flags.c +++ b/tests/clone-flags.c @@ -10,6 +10,7 @@ #include "tests.h" #include +#include #include #include #include @@ -17,6 +18,10 @@ #include #include +#define XLAT_MACROS_ONLY +#include "xlat/clone_flags.h" +#undef XLAT_MACROS_ONLY + static const int child_exit_status = 42; static pid_t pid; @@ -124,5 +129,23 @@ main(void) SYSCALL_NAME, child_stack_printed, STACK_SIZE_ARG "CLONE_PARENT_SETTID|SIGCHLD", *ptid, pid); + char buf[PATH_MAX]; + if (readlink("/proc/self/fd/0", buf, sizeof(buf) - 1) > 0) { + *ptid = 0; + pid = do_clone(child, child_stack, child_stack_size, + CLONE_PIDFD|SIGCHLD, 0, ptid); + char *fname = 0; + if (asprintf(&fname, "/proc/self/fd/%d", *ptid) < 0) + perror_msg_and_fail("asprintf"); + int rc = readlink(fname, buf, sizeof(buf) - 1); + if ((unsigned int) rc >= sizeof(buf)) + perror_msg_and_fail("readlink"); + buf[rc] = '\0'; + printf("%s(child_stack=%#lx" STACK_SIZE_FMT ", flags=%s" + ", parent_tid=[%u<%s>]) = %d\n", + SYSCALL_NAME, child_stack_printed, STACK_SIZE_ARG + "CLONE_PIDFD|SIGCHLD", *ptid, buf, pid); + } + return 0; }