]> granicus.if.org Git - strace/commitdiff
Add decoding of sockets descriptor 'paths' for network calls
authorPhilippe Ombredanne <pombredanne@nexb.com>
Sat, 1 Feb 2014 17:57:45 +0000 (09:57 -0800)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 2 Feb 2014 16:51:22 +0000 (16:51 +0000)
* net.c (sys_bind, sys_listen, do_accept, sys_send, sys_sendto,
sys_sendmsg, sys_sendmmsg, sys_recv, sys_recvfrom, sys_recvmsg,
sys_recvmmsg, sys_shutdown, sys_getsockopt, sys_setsockopt): Decode
socket descriptor arguments using printfd.
* pathtrace.c (pathtrace_match): Also check TRACE_NETWORK syscalls
that take socket descriptor arguments.
* tests/net-fd.test: New test for socket descriptor arguments decoding.
* tests/Makefile.am (TESTS): Add net-fd.test.
(net-fd.log): New dependency on net.log.

Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
net.c
pathtrace.c
tests/Makefile.am
tests/net-fd.test [new file with mode: 0755]

diff --git a/net.c b/net.c
index dd1e4469103b4b9625a2feead0baf5b8af28716b..b6c8cc9cdbb5aded5bd32738f8bda9a7f182ac0f 100644 (file)
--- a/net.c
+++ b/net.c
@@ -1711,7 +1711,8 @@ int
 sys_bind(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
                tprintf(", %lu", tcp->u_arg[2]);
        }
@@ -1728,7 +1729,9 @@ int
 sys_listen(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
+               tprintf("%lu", tcp->u_arg[1]);
        }
        return 0;
 }
@@ -1737,7 +1740,8 @@ static int
 do_accept(struct tcb *tcp, int flags_arg)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                return 0;
        }
        if (!tcp->u_arg[2])
@@ -1777,7 +1781,8 @@ int
 sys_send(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
                tprintf(", %lu, ", tcp->u_arg[2]);
                /* flags */
@@ -1790,7 +1795,8 @@ int
 sys_sendto(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
                tprintf(", %lu, ", tcp->u_arg[2]);
                /* flags */
@@ -1810,7 +1816,8 @@ int
 sys_sendmsg(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                printmsghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
                /* flags */
                tprints(", ");
@@ -1824,7 +1831,8 @@ sys_sendmmsg(struct tcb *tcp)
 {
        if (entering(tcp)) {
                /* sockfd */
-               tprintf("%d, ", (int) tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                if (!verbose(tcp)) {
                        tprintf("%#lx, %u, ",
                                tcp->u_arg[1], (unsigned int) tcp->u_arg[2]);
@@ -1843,7 +1851,8 @@ int
 sys_recv(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
        } else {
                if (syserror(tcp))
                        tprintf("%#lx", tcp->u_arg[1]);
@@ -1862,7 +1871,8 @@ sys_recvfrom(struct tcb *tcp)
        int fromlen;
 
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
        } else {
                if (syserror(tcp)) {
                        tprintf("%#lx, %lu, %lu, %#lx, %#lx",
@@ -1906,7 +1916,8 @@ int
 sys_recvmsg(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
        } else {
                if (syserror(tcp) || !verbose(tcp))
                        tprintf("%#lx", tcp->u_arg[1]);
@@ -1926,7 +1937,8 @@ sys_recvmmsg(struct tcb *tcp)
        static char str[5 + TIMESPEC_TEXT_BUFSIZE];
 
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                if (verbose(tcp)) {
                        sprint_timespec(str, tcp, tcp->u_arg[4]);
                        /* Abusing tcp->auxstr as temp storage.
@@ -1976,7 +1988,8 @@ int
 sys_shutdown(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
        }
        return 0;
@@ -2077,7 +2090,8 @@ int
 sys_getsockopt(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                printxval(socketlayers, tcp->u_arg[1], "SOL_???");
                tprints(", ");
                switch (tcp->u_arg[1]) {
@@ -2343,7 +2357,8 @@ int
 sys_setsockopt(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               tprintf("%ld, ", tcp->u_arg[0]);
+               printfd(tcp, tcp->u_arg[0]);
+               tprints(", ");
                printsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
                              tcp->u_arg[3], tcp->u_arg[4]);
                tprintf(", %lu", tcp->u_arg[4]);
index 03f6681fff3d2ab93634e7deab06b6ac94f051c6..f6c3b80f72e3fcf3c97253d36276c30be58a40a5 100644 (file)
@@ -80,7 +80,7 @@ fdmatch(struct tcb *tcp, int fd)
 
 /*
  * Add a path to the set we're tracing.
- * Secifying NULL will delete all paths.
+ * Specifying NULL will delete all paths.
  */
 static void
 storepath(const char *path)
@@ -158,7 +158,7 @@ pathtrace_match(struct tcb *tcp)
 
        s = tcp->s_ent;
 
-       if (!(s->sys_flags & (TRACE_FILE | TRACE_DESC)))
+       if (!(s->sys_flags & (TRACE_FILE | TRACE_DESC | TRACE_NETWORK)))
                return 0;
 
        /*
@@ -339,11 +339,13 @@ pathtrace_match(struct tcb *tcp)
            s->sys_func == sys_timerfd_settime ||
            s->sys_func == sys_timerfd_gettime ||
            s->sys_func == sys_epoll_create ||
+           s->sys_func == sys_socket ||
+           s->sys_func == sys_socketpair ||
            strcmp(s->sys_name, "fanotify_init") == 0)
        {
                /*
-                * These have TRACE_FILE or TRACE_DESCRIPTOR set, but they
-                * don't have any file descriptor or path args to test.
+                * These have TRACE_FILE or TRACE_DESCRIPTOR or TRACE_NETWORK set,
+                * but they don't have any file descriptor or path args to test.
                 */
                return 0;
        }
@@ -356,7 +358,7 @@ pathtrace_match(struct tcb *tcp)
        if (s->sys_flags & TRACE_FILE)
                return upathmatch(tcp, tcp->u_arg[0]);
 
-       if (s->sys_flags & TRACE_DESC)
+       if (s->sys_flags & (TRACE_DESC | TRACE_NETWORK))
                return fdmatch(tcp, tcp->u_arg[0]);
 
        return 0;
index 56c4a06715cf62b61e8ac98746080c1da618ae2e..82226df32f0186e1ccac30e6e974c1b1d897f6d4 100644 (file)
@@ -11,10 +11,13 @@ TESTS = \
        sigaction.test \
        stat.test \
        net.test \
+       net-fd.test \
        detach-sleeping.test \
        detach-stopped.test \
        detach-running.test
 
+net-fd.log: net.log
+
 TEST_LOG_COMPILER = $(srcdir)/run.sh
 
 EXTRA_DIST = init.sh run.sh sigaction.awk $(TESTS)
diff --git a/tests/net-fd.test b/tests/net-fd.test
new file mode 100755 (executable)
index 0000000..0f6b4e2
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# Check how network syscalls are traced when decoding socket descriptors
+
+. "${srcdir=.}/init.sh"
+
+# strace -y is implemented using /proc/self/fd
+[ -d /proc/self/fd/ ] ||
+       framework_skip_ '/proc/self/fd/ is not available'
+
+check_prog grep
+check_prog rm
+
+rm -f $LOG.*
+
+./net-accept-connect ||
+       fail_ 'net-accept-connect failed'
+
+# using -y to test socket descriptors 'paths' decoding
+args="-tt -ff -y -o $LOG -enetwork ./net-accept-connect"
+$STRACE $args ||
+       fail_ "strace $args failed"
+
+"$srcdir"/../strace-log-merge $LOG > $LOG || {
+       cat $LOG
+       fail_ 'strace-log-merge failed'
+}
+
+rm -f $LOG.*
+
+grep_log()
+{
+       local syscall="$1"; shift
+       local prefix='[1-9][0-9]* +[0-9]+:[0-9]+:[0-9]+\.[0-9]+ +'
+
+       LC_ALL=C grep -E -x "$prefix$syscall$@" $LOG > /dev/null || {
+               cat $LOG
+               fail_ "strace -enetwork failed to trace \"$syscall\" properly"
+       }
+}
+grep_log bind '\(0<socket:\[[0-9]+\]>, \{sa_family=AF_(LOCAL|UNIX|FILE), sun_path="local-stream"\}, 15\) += 0'
+grep_log listen '\(0<socket:\[[0-9]+\]>, 5\) += 0'
+grep_log getsockname '\(0<socket:\[[0-9]+\]>, \{sa_family=AF_(LOCAL|UNIX|FILE), sun_path="local-stream"\}, \[15\]\) += 0'
+grep_log accept '\(0<socket:\[[0-9]+\]>, \{sa_family=AF_(LOCAL|UNIX|FILE), NULL\}, \[2\]\) += 1'
+grep_log connect '\(1<socket:\[[0-9]+\]>, \{sa_family=AF_(LOCAL|UNIX|FILE), sun_path="local-stream"\}, 15\) += 0'
+
+exit 0