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.
This commit is contained in:
parent
1d17ac7c32
commit
eb5c233d99
12
net.c
12
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(")");
|
||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -125,6 +125,7 @@ move_pages
|
||||
mq
|
||||
nanosleep
|
||||
net-accept-connect
|
||||
net-icmp_filter
|
||||
net-y-unix
|
||||
net-yy-inet
|
||||
net-yy-unix
|
||||
|
@ -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 \
|
||||
|
85
tests/net-icmp_filter.c
Normal file
85
tests/net-icmp_filter.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Check decoding of ICMP_FILTER.
|
||||
*
|
||||
* Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
|
||||
* 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 <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/icmp.h>
|
||||
|
||||
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<<ICMP_ECHOREPLY |
|
||||
1<<ICMP_DEST_UNREACH |
|
||||
1<<ICMP_SOURCE_QUENCH |
|
||||
1<<ICMP_REDIRECT |
|
||||
1<<ICMP_TIME_EXCEEDED |
|
||||
1<<ICMP_PARAMETERPROB);
|
||||
|
||||
setsockopt(-1, SOL_RAW, ICMP_FILTER, f, -2);
|
||||
printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %p, -2) = -1 %s (%m)\n",
|
||||
f, errno2name());
|
||||
|
||||
setsockopt(-1, SOL_RAW, ICMP_FILTER, f, sizeof(*f));
|
||||
printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %s, %u) = -1 %s (%m)\n",
|
||||
"~(1<<ICMP_ECHOREPLY|1<<ICMP_DEST_UNREACH|1<<ICMP_SOURCE_QUENCH"
|
||||
"|1<<ICMP_REDIRECT|1<<ICMP_TIME_EXCEEDED|1<<ICMP_PARAMETERPROB)",
|
||||
(unsigned) sizeof(*f), errno2name());
|
||||
|
||||
setsockopt(-1, SOL_RAW, ICMP_FILTER, f, sizeof(*f) * 2);
|
||||
printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %s, %u) = -1 %s (%m)\n",
|
||||
"~(1<<ICMP_ECHOREPLY|1<<ICMP_DEST_UNREACH|1<<ICMP_SOURCE_QUENCH"
|
||||
"|1<<ICMP_REDIRECT|1<<ICMP_TIME_EXCEEDED|1<<ICMP_PARAMETERPROB)",
|
||||
(unsigned) sizeof(*f) * 2, errno2name());
|
||||
|
||||
puts("+++ exited with 0 +++");
|
||||
return 0;
|
||||
}
|
6
tests/net-icmp_filter.test
Executable file
6
tests/net-icmp_filter.test
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check decoding of ICMP_FILTER.
|
||||
|
||||
. "${srcdir=.}/init.sh"
|
||||
run_strace_match_diff -e trace=getsockopt,setsockopt
|
Loading…
x
Reference in New Issue
Block a user