From: Dmitry V. Levin Date: Fri, 6 May 2016 00:06:15 +0000 (+0000) Subject: Fix corner cases of ICMP_FILTER decoding X-Git-Tag: v4.12~225 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eb5c233d99b210e2e74472c27fd196f3fdb1c059;p=strace Fix corner cases of ICMP_FILTER decoding * net.c (print_icmp_filter): Print icmp_filter for any positive length. * tests/net-icmp_filter.c: New file. * tests/net-icmp_filter.test: New test. * tests/.gitignore: Add net-icmp_filter. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add net-icmp_filter.test. --- diff --git a/net.c b/net.c index f6d8c7df..c34b6aaf 100644 --- a/net.c +++ b/net.c @@ -1249,16 +1249,20 @@ print_tpacket_stats(struct tcb *tcp, long addr, int len) # include "xlat/icmpfilterflags.h" static void -print_icmp_filter(struct tcb *tcp, long addr, int len) +print_icmp_filter(struct tcb *tcp, const long addr, int len) { - struct icmp_filter filter; + struct icmp_filter filter = {}; - if (len != sizeof(filter) || - umove(tcp, addr, &filter) < 0) { + if (len > (int) sizeof(filter)) + len = sizeof(filter); + else if (len <= 0) { printaddr(addr); return; } + if (umoven_or_printaddr(tcp, addr, len, &filter)) + return; + tprints("~("); printflags(icmpfilterflags, ~filter.data, "ICMP_???"); tprints(")"); diff --git a/tests/.gitignore b/tests/.gitignore index b90ea4b4..102d8edd 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -125,6 +125,7 @@ move_pages mq nanosleep net-accept-connect +net-icmp_filter net-y-unix net-yy-inet net-yy-unix diff --git a/tests/Makefile.am b/tests/Makefile.am index 48bf5170..c09701dc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -178,6 +178,7 @@ check_PROGRAMS = \ mq \ nanosleep \ net-accept-connect \ + net-icmp_filter \ net-y-unix \ net-yy-inet \ net-yy-unix \ @@ -455,6 +456,7 @@ DECODER_TESTS = \ move_pages.test \ mq.test \ nanosleep.test \ + net-icmp_filter.test \ net-y-unix.test \ net-yy-inet.test \ net-yy-unix.test \ diff --git a/tests/net-icmp_filter.c b/tests/net-icmp_filter.c new file mode 100644 index 00000000..c710906f --- /dev/null +++ b/tests/net-icmp_filter.c @@ -0,0 +1,85 @@ +/* + * Check decoding of ICMP_FILTER. + * + * Copyright (c) 2016 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" +#include +#include +#include + +int +main(void) +{ + getsockopt(-1, SOL_RAW, ICMP_FILTER, 0, 0); + printf("getsockopt(-1, SOL_RAW, ICMP_FILTER, 0, 0) = -1 %s (%m)\n", + errno2name()); + + setsockopt(-1, SOL_RAW, ICMP_FILTER, NULL, 0); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, NULL, 0) = -1 %s (%m)\n", + errno2name()); + + (void) tail_alloc(1); + socklen_t *const plen = tail_alloc(sizeof(*plen)); + void *const efault = plen + 1; + struct icmp_filter *const f = tail_alloc(sizeof(*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()); + + setsockopt(-1, SOL_RAW, ICMP_FILTER, efault, sizeof(*f)); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %p, %u) = -1 %s (%m)\n", + efault, (unsigned) sizeof(*f), errno2name()); + + f->data = ~( + 1<