From: Dmitry V. Levin Date: Wed, 20 Jan 2016 04:56:25 +0000 (+0000) Subject: Fix dumping of recvmmsg syscall in case of short read X-Git-Tag: v4.12~620 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d44707d889a9a69e3aaebd2535968957cbcddedb;p=strace Fix dumping of recvmmsg syscall in case of short read * net.c (dumpiov_in_mmsghdr): Call dumpiov_upto instead of dumpiov, pass data size limit to dumpiov_upto. * NEWS: Mention this fix. * tests/mmsg.c (main): Update. --- diff --git a/NEWS b/NEWS index d1d5064b..ceddf089 100644 --- a/NEWS +++ b/NEWS @@ -14,7 +14,7 @@ Noteworthy changes in release ?.?? (????-??-??) * Fixed decoding of syscalls unknown to the kernel on s390/s390x. (addresses Debian bug #485979 and Fedora bug #1298294). * Fixed decoding and dumping of readv syscall in case of short read. - * Fixed dumping of recvmsg syscall in case of short read. + * Fixed dumping of recvmsg and recvmmsg syscalls in case of short read. Noteworthy changes in release 4.11 (2015-12-21) =============================================== diff --git a/net.c b/net.c index bd3cb15b..4ea79d2c 100644 --- a/net.c +++ b/net.c @@ -763,8 +763,8 @@ dumpiov_in_mmsghdr(struct tcb *tcp, long addr) if (extractmmsghdr(tcp, addr, i, &mmsg)) { tprintf(" = %lu buffers in vector %u\n", (unsigned long)mmsg.msg_hdr.msg_iovlen, i); - dumpiov(tcp, mmsg.msg_hdr.msg_iovlen, - (long)mmsg.msg_hdr.msg_iov); + dumpiov_upto(tcp, mmsg.msg_hdr.msg_iovlen, + (long)mmsg.msg_hdr.msg_iov, mmsg.msg_len); } } } diff --git a/tests/mmsg.c b/tests/mmsg.c index fe758a7a..1e0d37d7 100644 --- a/tests/mmsg.c +++ b/tests/mmsg.c @@ -87,102 +87,150 @@ main(void) { tprintf("%s", ""); - const int R = 0, W = 1; - int sv[2]; - if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sv)) + int fds[2]; + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds)) perror_msg_and_skip("socketpair"); - assert(R == sv[0]); - assert(W == sv[1]); + assert(0 == fds[0]); + assert(1 == fds[1]); - static const char one[] = "one"; - static const char two[] = "two"; - static const char three[] = "three"; - static const char ascii_one[] = "6f 6e 65"; - static const char ascii_two[] = "74 77 6f"; - static const char ascii_three[] = "74 68 72 65 65"; + static const char w0_c[] = "012"; + const char *w0_d = hexdump_strdup(w0_c); + void *w0 = tail_memdup(w0_c, LENGTH_OF(w0_c)); - void *copy_one = tail_memdup(one, LENGTH_OF(one)); - void *copy_two = tail_memdup(two, LENGTH_OF(two)); - void *copy_three = tail_memdup(three, LENGTH_OF(three)); + static const char w1_c[] = "34567"; + const char *w1_d = hexdump_strdup(w1_c); + void *w1 = tail_memdup(w1_c, LENGTH_OF(w1_c)); - struct iovec iov[] = { + static const char w2_c[] = "89abcde"; + const char *w2_d = hexdump_strdup(w2_c); + void *w2 = tail_memdup(w2_c, LENGTH_OF(w2_c)); + + const struct iovec w0_iov_[] = { { - .iov_base = copy_one, - .iov_len = LENGTH_OF(one) - }, { - .iov_base = copy_two, - .iov_len = LENGTH_OF(two) + .iov_base = w0, + .iov_len = LENGTH_OF(w0_c) }, { - .iov_base = copy_three, - .iov_len = LENGTH_OF(three) + .iov_base = w1, + .iov_len = LENGTH_OF(w1_c) } }; - struct iovec *copy_iov = tail_memdup(iov, sizeof(iov)); + struct iovec *w0_iov = tail_memdup(w0_iov_, sizeof(w0_iov_)); - struct mmsghdr mmh[] = { + const struct iovec w1_iov_[] = { + { + .iov_base = w2, + .iov_len = LENGTH_OF(w2_c) + } + }; + struct iovec *w1_iov = tail_memdup(w1_iov_, sizeof(w1_iov_)); + + const struct mmsghdr w_mmh_[] = { { .msg_hdr = { - .msg_iov = copy_iov + 0, - .msg_iovlen = 2, + .msg_iov = w0_iov, + .msg_iovlen = ARRAY_SIZE(w0_iov_), } }, { .msg_hdr = { - .msg_iov = copy_iov + 2, - .msg_iovlen = 1, + .msg_iov = w1_iov, + .msg_iovlen = ARRAY_SIZE(w1_iov_), } } }; - void *copy_mmh = tail_memdup(mmh, sizeof(mmh)); -# define n_mmh ((unsigned int) (sizeof(mmh)/sizeof(mmh[0]))) + void *w_mmh = tail_memdup(w_mmh_, sizeof(w_mmh_)); + const unsigned int n_w_mmh = ARRAY_SIZE(w_mmh_); - int r = send_mmsg(W, copy_mmh, n_mmh, MSG_DONTROUTE | MSG_NOSIGNAL); + int r = send_mmsg(1, w_mmh, n_w_mmh, MSG_DONTROUTE | MSG_NOSIGNAL); if (r < 0 && errno == ENOSYS) perror_msg_and_skip("sendmmsg"); - assert(r == (int) n_mmh); - assert(close(W) == 0); - tprintf("sendmmsg(%d, {{{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}" + assert(r == (int) n_w_mmh); + assert(close(1) == 0); + tprintf("sendmmsg(1, {{{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}" ", {\"%s\", %u}], msg_controllen=0, msg_flags=0}, %u}" ", {{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}]" ", msg_controllen=0, msg_flags=0}, %u}}, %u" ", MSG_DONTROUTE|MSG_NOSIGNAL) = %d\n" " = %u buffers in vector 0\n" " * %u bytes in buffer 0\n" - " | 00000 %-48s %-16s |\n" + " | 00000 %-49s %-16s |\n" " * %u bytes in buffer 1\n" - " | 00000 %-48s %-16s |\n" + " | 00000 %-49s %-16s |\n" " = %u buffers in vector 1\n" " * %u bytes in buffer 0\n" - " | 00000 %-48s %-16s |\n", - W, 2, one, LENGTH_OF(one), two, LENGTH_OF(two), - LENGTH_OF(one) + LENGTH_OF(two), - 1, three, LENGTH_OF(three), LENGTH_OF(three), - n_mmh, r, - 2, LENGTH_OF(one), ascii_one, one, - LENGTH_OF(two), ascii_two, two, - 1, LENGTH_OF(three), ascii_three, three); - - assert(recv_mmsg(R, copy_mmh, n_mmh, MSG_DONTWAIT, NULL) == (int) n_mmh); - assert(close(R) == 0); - tprintf("recvmmsg(%d, {{{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}" - ", {\"%s\", %u}], msg_controllen=0, msg_flags=0}, %u}" - ", {{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}]" + " | 00000 %-49s %-16s |\n", + ARRAY_SIZE(w0_iov_), w0_c, LENGTH_OF(w0_c), + w1_c, LENGTH_OF(w1_c), + LENGTH_OF(w0_c) + LENGTH_OF(w1_c), + ARRAY_SIZE(w1_iov_), w2_c, LENGTH_OF(w2_c), LENGTH_OF(w2_c), + n_w_mmh, r, + ARRAY_SIZE(w0_iov_), LENGTH_OF(w0_c), w0_d, w0_c, + LENGTH_OF(w1_c), w1_d, w1_c, + ARRAY_SIZE(w1_iov_), LENGTH_OF(w2_c), w2_d, w2_c); + + const unsigned int w_len = + LENGTH_OF(w0_c) + LENGTH_OF(w1_c) + LENGTH_OF(w2_c); + const unsigned int r_len = (w_len + 1) / 2; + void *r0 = tail_alloc(r_len); + void *r1 = tail_alloc(r_len); + void *r2 = tail_alloc(r_len); + const struct iovec r0_iov_[] = { + { + .iov_base = r0, + .iov_len = r_len + } + }; + struct iovec *r0_iov = tail_memdup(r0_iov_, sizeof(r0_iov_)); + const struct iovec r1_iov_[] = { + { + .iov_base = r1, + .iov_len = r_len + }, + { + .iov_base = r2, + .iov_len = r_len + } + }; + struct iovec *r1_iov = tail_memdup(r1_iov_, sizeof(r1_iov_)); + + const struct mmsghdr r_mmh_[] = { + { + .msg_hdr = { + .msg_iov = r0_iov, + .msg_iovlen = ARRAY_SIZE(r0_iov_), + } + }, { + .msg_hdr = { + .msg_iov = r1_iov, + .msg_iovlen = ARRAY_SIZE(r1_iov_), + } + } + }; + void *r_mmh = tail_memdup(r_mmh_, sizeof(r_mmh_)); + const unsigned int n_r_mmh = ARRAY_SIZE(r_mmh_); + + static const char r0_c[] = "01234567"; + const char *r0_d = hexdump_strdup(r0_c); + static const char r1_c[] = "89abcde"; + const char *r1_d = hexdump_strdup(r1_c); + + assert(recv_mmsg(0, r_mmh, n_r_mmh, MSG_DONTWAIT, NULL) == (int) n_r_mmh); + assert(close(0) == 0); + tprintf("recvmmsg(0, {{{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}]" + ", msg_controllen=0, msg_flags=0}, %u}" + ", {{msg_name(0)=NULL, msg_iov(%u)=[{\"%s\", %u}, {\"\", %u}]" ", msg_controllen=0, msg_flags=0}, %u}}, %u" ", MSG_DONTWAIT, NULL) = %d (left NULL)\n" " = %u buffers in vector 0\n" " * %u bytes in buffer 0\n" - " | 00000 %-48s %-16s |\n" - " * %u bytes in buffer 1\n" - " | 00000 %-48s %-16s |\n" + " | 00000 %-49s %-16s |\n" " = %u buffers in vector 1\n" " * %u bytes in buffer 0\n" - " | 00000 %-48s %-16s |\n", - R, 2, one, LENGTH_OF(one), two, LENGTH_OF(two), - LENGTH_OF(one) + LENGTH_OF(two), - 1, three, LENGTH_OF(three), LENGTH_OF(three), - n_mmh, r, - 2, LENGTH_OF(one), ascii_one, one, - LENGTH_OF(two), ascii_two, two, - 1, LENGTH_OF(three), ascii_three, three); + " | 00000 %-49s %-16s |\n", + ARRAY_SIZE(r0_iov_), r0_c, r_len, LENGTH_OF(r0_c), + ARRAY_SIZE(r1_iov_), r1_c, r_len, r_len, LENGTH_OF(r1_c), + n_r_mmh, r, + ARRAY_SIZE(r0_iov_), LENGTH_OF(r0_c), r0_d, r0_c, + ARRAY_SIZE(r1_iov_), LENGTH_OF(r1_c), r1_d, r1_c); tprintf("+++ exited with 0 +++\n"); return 0;