From: Dmitry V. Levin Date: Sat, 8 Jul 2017 14:57:44 +0000 (+0000) Subject: net: enhance decoding of getsockopt's optlen argument X-Git-Tag: v4.19~320 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=657b04b83b13f1c3f6bf4d4da9537d0ba16d830c;p=strace net: enhance decoding of getsockopt's optlen argument As the last argument of getsockopt syscall has read-write semantics, print both user and kernel values when they differ. * net.c (SYS_FUNC(getsockopt)): On entering syscall, fetch and save the length specified to the kernel. On error, print the length saved on entering. When the saved length and the length returned by the kernel differ, print both values. * NEWS: Mention this. * tests/net-icmp_filter.c (main): Update expected output. --- diff --git a/NEWS b/NEWS index 1e82a607..70f9fa2f 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ Noteworthy changes in release ?.?? (????-??-??) =============================================== +* Improvements + * Enhanced decoding of optlen argument of getsockopt syscall. Noteworthy changes in release 4.18 (2017-07-05) =============================================== diff --git a/net.c b/net.c index bfa794f9..807eb250 100644 --- a/net.c +++ b/net.c @@ -614,20 +614,35 @@ print_getsockopt(struct tcb *const tcp, const unsigned int level, SYS_FUNC(getsockopt) { + int ulen, rlen; + if (entering(tcp)) { print_sockopt_fd_level_name(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2], true); - } else { - int len; - if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) { + if (verbose(tcp) && tcp->u_arg[4] + && umove(tcp, tcp->u_arg[4], &ulen) == 0) { + set_tcb_priv_ulong(tcp, ulen); + return 0; + } else { printaddr(tcp->u_arg[3]); tprints(", "); printaddr(tcp->u_arg[4]); + return RVAL_DECODED; + } + } else { + ulen = get_tcb_priv_ulong(tcp); + + if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &rlen) < 0) { + printaddr(tcp->u_arg[3]); + tprintf(", [%d]", ulen); } else { print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2], - tcp->u_arg[3], len); - tprintf(", [%d]", len); + tcp->u_arg[3], rlen); + if (ulen != rlen) + tprintf(", [%d->%d]", ulen, rlen); + else + tprintf(", [%d]", rlen); } } return 0; diff --git a/tests/net-icmp_filter.c b/tests/net-icmp_filter.c index 71e530d2..1dd1f218 100644 --- a/tests/net-icmp_filter.c +++ b/tests/net-icmp_filter.c @@ -49,8 +49,8 @@ main(void) TAIL_ALLOC_OBJECT_CONST_PTR(struct icmp_filter, f); getsockopt(-1, SOL_RAW, ICMP_FILTER, f, plen); - printf("getsockopt(-1, SOL_RAW, ICMP_FILTER, %p, %p) = -1 %s (%m)\n", - f, plen, errno2name()); + printf("getsockopt(-1, SOL_RAW, ICMP_FILTER, %p, [%d]) = -1 %s (%m)\n", + f, *plen, errno2name()); setsockopt(-1, SOL_RAW, ICMP_FILTER, efault, sizeof(*f)); printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %p, %u) = -1 %s (%m)\n",