From: Denys Vlasenko Date: Thu, 30 Jul 2015 11:29:20 +0000 (+0200) Subject: net.c: recvfrom fixes X-Git-Tag: v4.11~316 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=383386de73799a7c977e729c1e104ba6d6b3630c;p=strace net.c: recvfrom fixes This change fixes these three problems (before/after is shown): On interrupted syscall, flags are not decoded: -recvfrom(3, 0x7fff0a41e306, 10, 2, 0, 0) = ? ERESTARTSYS +recvfrom(3, 0x7fff0a41e306, 10, MSG_PEEK, 0, 0) = ? ERESTARTSYS If peer address is unavalable (example: anon sockets from socketpair()), kernel returns socklen of 0, but we ignore that and show bogus sockaddr data: -recvfrom(3, "123456789\0", 10, MSG_PEEK, {sa_family=0x7777 /* AF_??? */, sa_data="wwwwwwwwwwwwww"}, [0]) = 10 +recvfrom(3, "123456789\0", 10, MSG_PEEK, 0x7ffde6edf760, [0]) = 10 SYS_FUNC(recvfrom) passes address of fromlen, not fromlen, to printsock(): - printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]); + printsock(tcp, tcp->u_arg[4], fromlen); Signed-off-by: Denys Vlasenko --- diff --git a/net.c b/net.c index a4a2de54..7412519b 100644 --- a/net.c +++ b/net.c @@ -146,7 +146,12 @@ printsock(struct tcb *tcp, long addr, int addrlen) } addrbuf; char string_addr[100]; - if (addrlen < 2 || addrlen > (int) sizeof(addrbuf)) + if (addrlen < 2) { + tprintf("%#lx", addr); + return; + } + + if (addrlen > (int) sizeof(addrbuf)) addrlen = sizeof(addrbuf); memset(&addrbuf, 0, sizeof(addrbuf)); @@ -807,28 +812,31 @@ SYS_FUNC(recvfrom) printfd(tcp, tcp->u_arg[0]); tprints(", "); } else { + /* buf */ if (syserror(tcp)) { - tprintf("%#lx, %lu, %lu, %#lx, %#lx", - tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3], - tcp->u_arg[4], tcp->u_arg[5]); - return 0; + tprintf("%#lx", tcp->u_arg[1]); + } else { + printstr(tcp, tcp->u_arg[1], tcp->u_rval); } - /* buf */ - printstr(tcp, tcp->u_arg[1], tcp->u_rval); /* len */ tprintf(", %lu, ", tcp->u_arg[2]); /* flags */ printflags(msg_flags, tcp->u_arg[3], "MSG_???"); - /* from address, len */ + if (syserror(tcp)) { + tprintf(", %#lx, %#lx", tcp->u_arg[4], tcp->u_arg[5]); + return 0; + } tprints(", "); if (!tcp->u_arg[4] || !tcp->u_arg[5] || umove(tcp, tcp->u_arg[5], &fromlen) < 0) { + /* from address, len */ printaddr(tcp->u_arg[4]); tprints(", "); printaddr(tcp->u_arg[5]); return 0; } - printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]); + /* from address */ + printsock(tcp, tcp->u_arg[4], fromlen); /* from length */ tprintf(", [%u]", fromlen); }