]> granicus.if.org Git - strace/blobdiff - net.c
io: change size types from unsigned long to kernel_ureg_t
[strace] / net.c
diff --git a/net.c b/net.c
index bcb9e4f642e734e92b935b64c89e12b2ca3f95d9..00cfd707e04c147f75b813856df0b61fce85a66d 100644 (file)
--- a/net.c
+++ b/net.c
@@ -29,7 +29,6 @@
  */
 
 #include "defs.h"
-#include "msghdr.h"
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
 #include "xlat/socketlayers.h"
 
 #include "xlat/inet_protocols.h"
-
-#if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG
-# define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
-#endif
 #include "xlat/netlink_protocols.h"
 
 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
@@ -109,7 +104,8 @@ print_ifindex(unsigned int ifindex)
 }
 
 static void
-decode_sockbuf(struct tcb *tcp, int fd, long addr, long addrlen)
+decode_sockbuf(struct tcb *const tcp, const int fd, const kernel_ureg_t addr,
+              const long addrlen)
 {
 
        switch (verbose(tcp) ? getfdproto(tcp, fd) : SOCK_PROTO_UNKNOWN) {
@@ -117,7 +113,7 @@ decode_sockbuf(struct tcb *tcp, int fd, long addr, long addrlen)
                decode_netlink(tcp, addr, addrlen);
                break;
        default:
-               printstr(tcp, addr, addrlen);
+               printstrn(tcp, addr, addrlen);
        }
 }
 
@@ -174,8 +170,9 @@ SYS_FUNC(bind)
 {
        printfd(tcp, tcp->u_arg[0]);
        tprints(", ");
-       decode_sockaddr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
-       tprintf(", %lu", tcp->u_arg[2]);
+       const int addrlen = tcp->u_arg[2];
+       decode_sockaddr(tcp, tcp->u_arg[1], addrlen);
+       tprintf(", %d", addrlen);
 
        return RVAL_DECODED;
 }
@@ -189,44 +186,64 @@ SYS_FUNC(listen)
        return RVAL_DECODED;
 }
 
+static bool
+fetch_socklen(struct tcb *const tcp, int *const plen,
+             const kernel_ureg_t sockaddr, const kernel_ureg_t socklen)
+{
+       return verbose(tcp) && sockaddr && socklen
+              && umove(tcp, socklen, plen) == 0;
+}
+
 static int
-do_sockname(struct tcb *tcp, int flags_arg)
+decode_sockname(struct tcb *tcp)
 {
+       int ulen, rlen;
+
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
                tprints(", ");
-               return 0;
+               if (fetch_socklen(tcp, &ulen, tcp->u_arg[1], tcp->u_arg[2])) {
+                       set_tcb_priv_ulong(tcp, ulen);
+                       return 0;
+               } else {
+                       printaddr(tcp->u_arg[1]);
+                       tprints(", ");
+                       printaddr(tcp->u_arg[2]);
+                       return RVAL_DECODED;
+               }
        }
 
-       int len;
-       if (!tcp->u_arg[2] || !verbose(tcp) || syserror(tcp) ||
-           umove(tcp, tcp->u_arg[2], &len) < 0) {
+       ulen = get_tcb_priv_ulong(tcp);
+
+       if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &rlen) < 0) {
                printaddr(tcp->u_arg[1]);
-               tprints(", ");
-               printaddr(tcp->u_arg[2]);
+               tprintf(", [%d]", ulen);
        } else {
-               decode_sockaddr(tcp, tcp->u_arg[1], len);
-               tprintf(", [%d]", len);
+               decode_sockaddr(tcp, tcp->u_arg[1], ulen > rlen ? rlen : ulen);
+               if (ulen != rlen)
+                       tprintf(", [%d->%d]", ulen, rlen);
+               else
+                       tprintf(", [%d]", rlen);
        }
 
-       if (flags_arg >= 0) {
-               tprints(", ");
-               printflags(sock_type_flags, tcp->u_arg[flags_arg],
-                          "SOCK_???");
-       }
-       return 0;
+       return RVAL_DECODED;
 }
 
 SYS_FUNC(accept)
 {
-       do_sockname(tcp, -1);
-       return RVAL_FD;
+       return decode_sockname(tcp) | RVAL_FD;
 }
 
 SYS_FUNC(accept4)
 {
-       do_sockname(tcp, 3);
-       return RVAL_FD;
+       int rc = decode_sockname(tcp);
+
+       if (rc & RVAL_DECODED) {
+               tprints(", ");
+               printflags(sock_type_flags, tcp->u_arg[3], "SOCK_???");
+       }
+
+       return rc | RVAL_FD;
 }
 
 SYS_FUNC(send)
@@ -250,50 +267,15 @@ SYS_FUNC(sendto)
        /* flags */
        printflags(msg_flags, tcp->u_arg[3], "MSG_???");
        /* to address */
+       const int addrlen = tcp->u_arg[5];
        tprints(", ");
-       decode_sockaddr(tcp, tcp->u_arg[4], tcp->u_arg[5]);
+       decode_sockaddr(tcp, tcp->u_arg[4], addrlen);
        /* to length */
-       tprintf(", %lu", tcp->u_arg[5]);
-
-       return RVAL_DECODED;
-}
-
-SYS_FUNC(sendmsg)
-{
-       printfd(tcp, tcp->u_arg[0]);
-       tprints(", ");
-       decode_msghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
-       /* flags */
-       tprints(", ");
-       printflags(msg_flags, tcp->u_arg[2], "MSG_???");
+       tprintf(", %d", addrlen);
 
        return RVAL_DECODED;
 }
 
-SYS_FUNC(sendmmsg)
-{
-       if (entering(tcp)) {
-               /* sockfd */
-               printfd(tcp, tcp->u_arg[0]);
-               tprints(", ");
-               if (!verbose(tcp)) {
-                       printaddr(tcp->u_arg[1]);
-                       /* vlen */
-                       tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
-                       /* flags */
-                       printflags(msg_flags, tcp->u_arg[3], "MSG_???");
-                       return RVAL_DECODED;
-               }
-       } else {
-               decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, false);
-               /* vlen */
-               tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
-               /* flags */
-               printflags(msg_flags, tcp->u_arg[3], "MSG_???");
-       }
-       return 0;
-}
-
 SYS_FUNC(recv)
 {
        if (entering(tcp)) {
@@ -315,11 +297,14 @@ SYS_FUNC(recv)
 
 SYS_FUNC(recvfrom)
 {
-       int fromlen;
+       int ulen, rlen;
 
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
                tprints(", ");
+               if (fetch_socklen(tcp, &ulen, tcp->u_arg[4], tcp->u_arg[5])) {
+                       set_tcb_priv_ulong(tcp, ulen);
+               }
        } else {
                /* buf */
                if (syserror(tcp)) {
@@ -328,94 +313,40 @@ SYS_FUNC(recvfrom)
                        decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
                                     tcp->u_rval);
                }
-               /* len */
+               /* size */
                tprintf(", %lu, ", tcp->u_arg[2]);
                /* flags */
                printflags(msg_flags, tcp->u_arg[3], "MSG_???");
                tprints(", ");
-               if (syserror(tcp) || !tcp->u_arg[4] || !tcp->u_arg[5] ||
-                   umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
-                       /* from address, len */
+
+               ulen = get_tcb_priv_ulong(tcp);
+
+               if (!fetch_socklen(tcp, &rlen, tcp->u_arg[4], tcp->u_arg[5])) {
+                       /* from address */
                        printaddr(tcp->u_arg[4]);
                        tprints(", ");
+                       /* from length */
                        printaddr(tcp->u_arg[5]);
                        return 0;
                }
+               if (syserror(tcp)) {
+                       /* from address */
+                       printaddr(tcp->u_arg[4]);
+                       /* from length */
+                       tprintf(", [%d]", ulen);
+                       return 0;
+               }
                /* from address */
-               decode_sockaddr(tcp, tcp->u_arg[4], fromlen);
+               decode_sockaddr(tcp, tcp->u_arg[4], ulen > rlen ? rlen : ulen);
                /* from length */
-               tprintf(", [%u]", fromlen);
-       }
-       return 0;
-}
-
-SYS_FUNC(recvmsg)
-{
-       if (entering(tcp)) {
-               printfd(tcp, tcp->u_arg[0]);
-               tprints(", ");
-       } else {
-               if (syserror(tcp))
-                       printaddr(tcp->u_arg[1]);
+               if (ulen != rlen)
+                       tprintf(", [%d->%d]", ulen, rlen);
                else
-                       decode_msghdr(tcp, tcp->u_arg[1], tcp->u_rval);
-               /* flags */
-               tprints(", ");
-               printflags(msg_flags, tcp->u_arg[2], "MSG_???");
+                       tprintf(", [%d]", rlen);
        }
        return 0;
 }
 
-SYS_FUNC(recvmmsg)
-{
-       static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
-
-       if (entering(tcp)) {
-               printfd(tcp, tcp->u_arg[0]);
-               tprints(", ");
-               if (verbose(tcp)) {
-                       /* Abusing tcp->auxstr as temp storage.
-                        * Will be used and cleared on syscall exit.
-                        */
-                       tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]);
-               } else {
-                       printaddr(tcp->u_arg[1]);
-                       /* vlen */
-                       tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
-                       /* flags */
-                       printflags(msg_flags, tcp->u_arg[3], "MSG_???");
-                       tprints(", ");
-                       print_timespec(tcp, tcp->u_arg[4]);
-               }
-               return 0;
-       } else {
-               if (verbose(tcp)) {
-                       decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, true);
-                       /* vlen */
-                       tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
-                       /* flags */
-                       printflags(msg_flags, tcp->u_arg[3], "MSG_???");
-                       tprints(", ");
-                       /* timeout on entrance */
-                       tprints(tcp->auxstr);
-                       tcp->auxstr = NULL;
-               }
-               if (syserror(tcp))
-                       return 0;
-               if (tcp->u_rval == 0) {
-                       tcp->auxstr = "Timeout";
-                       return RVAL_STR;
-               }
-               if (!verbose(tcp))
-                       return 0;
-               /* timeout on exit */
-               snprintf(str, sizeof(str), "left %s",
-                        sprint_timespec(tcp, tcp->u_arg[4]));
-               tcp->auxstr = str;
-               return RVAL_STR;
-       }
-}
-
 #include "xlat/shutdown_modes.h"
 
 SYS_FUNC(shutdown)
@@ -429,7 +360,7 @@ SYS_FUNC(shutdown)
 
 SYS_FUNC(getsockname)
 {
-       return do_sockname(tcp, -1);
+       return decode_sockname(tcp);
 }
 
 static void
@@ -443,7 +374,7 @@ printpair_fd(struct tcb *tcp, const int i0, const int i1)
 }
 
 static void
-decode_pair_fd(struct tcb *tcp, const long addr)
+decode_pair_fd(struct tcb *const tcp, const kernel_ureg_t addr)
 {
        int pair[2];
 
@@ -556,7 +487,7 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
 }
 
 static void
-print_linger(struct tcb *tcp, long addr, int len)
+print_linger(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
 {
        struct linger linger;
 
@@ -573,7 +504,7 @@ print_linger(struct tcb *tcp, long addr, int len)
 
 #ifdef SO_PEERCRED
 static void
-print_ucred(struct tcb *tcp, long addr, int len)
+print_ucred(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
 {
        struct ucred uc;
 
@@ -591,7 +522,8 @@ print_ucred(struct tcb *tcp, long addr, int len)
 
 #ifdef PACKET_STATISTICS
 static void
-print_tpacket_stats(struct tcb *tcp, long addr, int len)
+print_tpacket_stats(struct tcb *const tcp, const kernel_ureg_t addr,
+                   const int len)
 {
        struct tpacket_stats stats;
 
@@ -609,7 +541,7 @@ print_tpacket_stats(struct tcb *tcp, long addr, int len)
 #include "xlat/icmpfilterflags.h"
 
 static void
-print_icmp_filter(struct tcb *tcp, const long addr, int len)
+print_icmp_filter(struct tcb *const tcp, const kernel_ureg_t addr, int len)
 {
        struct icmp_filter filter = {};
 
@@ -629,8 +561,9 @@ print_icmp_filter(struct tcb *tcp, const long addr, int len)
 }
 
 static void
-print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
-                long addr, int len)
+print_getsockopt(struct tcb *const tcp, const unsigned int level,
+                const unsigned int name, const kernel_ureg_t addr,
+                const int len)
 {
        if (addr && verbose(tcp))
        switch (level) {
@@ -672,7 +605,7 @@ print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
                if (len == sizeof(int)) {
                        printnum_int(tcp, addr, "%d");
                } else {
-                       printstr(tcp, addr, len);
+                       printstrn(tcp, addr, len);
                }
        } else {
                printaddr(addr);
@@ -703,12 +636,13 @@ SYS_FUNC(getsockopt)
 
 #ifdef IP_ADD_MEMBERSHIP
 static void
-print_mreq(struct tcb *tcp, long addr, unsigned int len)
+print_mreq(struct tcb *const tcp, const kernel_ureg_t addr,
+          const unsigned int len)
 {
        struct ip_mreq mreq;
 
        if (len < sizeof(mreq)) {
-               printstr(tcp, addr, len);
+               printstrn(tcp, addr, len);
                return;
        }
        if (umove_or_printaddr(tcp, addr, &mreq))
@@ -726,7 +660,8 @@ print_mreq(struct tcb *tcp, long addr, unsigned int len)
 
 #ifdef IPV6_ADD_MEMBERSHIP
 static void
-print_mreq6(struct tcb *tcp, long addr, unsigned int len)
+print_mreq6(struct tcb *const tcp, const kernel_ureg_t addr,
+           const unsigned int len)
 {
        struct ipv6_mreq mreq;
 
@@ -750,13 +685,13 @@ print_mreq6(struct tcb *tcp, long addr, unsigned int len)
        return;
 
 fail:
-       printstr(tcp, addr, len);
+       printstrn(tcp, addr, len);
 }
 #endif /* IPV6_ADD_MEMBERSHIP */
 
 #ifdef MCAST_JOIN_GROUP
 static void
-print_group_req(struct tcb *tcp, long addr, int len)
+print_group_req(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
 {
        struct group_req greq;
 
@@ -768,14 +703,14 @@ print_group_req(struct tcb *tcp, long addr, int len)
 
        tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
        print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
-       tprintf("}");
+       tprints("}");
 
 }
 #endif /* MCAST_JOIN_GROUP */
 
 #ifdef PACKET_RX_RING
 static void
-print_tpacket_req(struct tcb *tcp, long addr, int len)
+print_tpacket_req(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
 {
        struct tpacket_req req;
 
@@ -797,7 +732,7 @@ print_tpacket_req(struct tcb *tcp, long addr, int len)
 # include "xlat/packet_mreq_type.h"
 
 static void
-print_packet_mreq(struct tcb *tcp, long addr, int len)
+print_packet_mreq(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
 {
        struct packet_mreq mreq;
 
@@ -820,8 +755,9 @@ print_packet_mreq(struct tcb *tcp, long addr, int len)
 #endif /* PACKET_ADD_MEMBERSHIP */
 
 static void
-print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
-                long addr, int len)
+print_setsockopt(struct tcb *const tcp, const unsigned int level,
+                const unsigned int name, const kernel_ureg_t addr,
+                const int len)
 {
        if (addr && verbose(tcp))
        switch (level) {
@@ -901,7 +837,7 @@ print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
                if (len == sizeof(int)) {
                        printnum_int(tcp, addr, "%d");
                } else {
-                       printstr(tcp, addr, len);
+                       printstrn(tcp, addr, len);
                }
        } else {
                printaddr(addr);