[PATCH v5 8/8] tests: check fd filter

Eugene Syromiatnikov esyr at redhat.com
Mon Jul 24 16:03:40 UTC 2017


On Wed, Jul 19, 2017 at 05:26:51PM +0700, Nikolay Marchuk wrote:
> * tests/filtering_fd-syntax.test: New file.
> * tests/filtering_fd.c: Likewise.
> * tests/filtering_fd.test: Likewise.
> * tests/options-syntax.test: Remove fd filtering checks.
> * tests/.gitignore: Add filtering_fd.
> * tests/Makefile.am (check_PROGRAMS): Add filtering_fd.
> (MISC_TESTS): Add filering_fd-syntax.test, filtering_fd.test.
> ---
>  tests/.gitignore               |   1 +
>  tests/Makefile.am              |   3 +
>  tests/filtering_fd-syntax.test |  42 +++++++++++
>  tests/filtering_fd.c           | 158 +++++++++++++++++++++++++++++++++++++++++
>  tests/filtering_fd.test        |  27 +++++++
>  tests/options-syntax.test      |  11 ---
>  6 files changed, 231 insertions(+), 11 deletions(-)
>  create mode 100755 tests/filtering_fd-syntax.test
>  create mode 100644 tests/filtering_fd.c
>  create mode 100755 tests/filtering_fd.test
> 
> diff --git a/tests/.gitignore b/tests/.gitignore
> index 9bed8e8..fdc7255 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -66,6 +66,7 @@ fdatasync
>  file_handle
>  file_ioctl
>  filter-unavailable
> +filtering_fd
>  finit_module
>  flock
>  fork-f
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index bb23343..628039a 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -86,6 +86,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
>  	execve-v \
>  	execveat-v \
>  	filter-unavailable \
> +	filtering_fd \
>  	fork-f \
>  	getpid	\
>  	getppid	\
> @@ -248,6 +249,8 @@ MISC_TESTS = \
>  	detach-sleeping.test \
>  	detach-stopped.test \
>  	filter-unavailable.test \
> +	filtering_fd-syntax.test \
> +	filtering_fd.test \
>  	filtering_syscall-syntax.test \
>  	get_regs.test \
>  	interactive_block.test \
> diff --git a/tests/filtering_fd-syntax.test b/tests/filtering_fd-syntax.test
> new file mode 100755
> index 0000000..f67d527
> --- /dev/null
> +++ b/tests/filtering_fd-syntax.test
> @@ -0,0 +1,42 @@
> +#!/bin/sh
> +#
> +# Check fd set parsing syntax.
> +#
> +# Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
> +# 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.
> +
> +. "${srcdir=.}/syntax.sh"
> +
> +for arg in \! \!, , ,, \
> +	   -1 \
> +	   not_fd \
> +	   2147483648 \
> +	   4294967296 \
> +	   ; do
> +	check_e "invalid descriptor '$arg'" -e "trace(fd $arg)"
> +done
> +
> +check_e "invalid descriptor ''" -e "trace(fd && fd 0)"
> +check_e "invalid descriptor '!'" -e "trace(fd 0,\!)"
> diff --git a/tests/filtering_fd.c b/tests/filtering_fd.c
> new file mode 100644
> index 0000000..806aba0
> --- /dev/null
> +++ b/tests/filtering_fd.c
> @@ -0,0 +1,158 @@
> +/*
> + * Check decoding of non-standard fd filters
> + *
> + * Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a at gmail.com>
> + * 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 <asm/unistd.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <sys/mman.h>
> +
> +#ifdef __NR_dup2
> +void
> +test_dup2(void)
> +{
> +	int rc = dup2(5, -1);
> +	printf("dup2(5, -1) = %s\n", sprintrc(rc));
> +	rc = dup2(-1, 5);
> +	printf("dup2(-1, 5) = %s\n", sprintrc(rc));
> +}
> +#endif
> +
> +#ifdef __NR_linkat
> +void
> +test_linkat(void)
> +{
> +	int rc = linkat(5, "old", -1, "new", 0);
> +	printf("linkat(5, \"old\", -1, \"new\", 0) = %s\n", sprintrc(rc));
> +	rc = linkat(-1, "old", 5, "new", 0);
> +	printf("linkat(-1, \"old\", 5, \"new\", 0) = %s\n", sprintrc(rc));
> +}
> +#endif
> +
> +#ifdef __NR_symlinkat
> +void
> +test_symlinkat(void)
> +{
> +	int rc = symlinkat("new", 5, "old");
> +	printf("symlinkat(\"new\", 5, \"old\") = %s\n", sprintrc(rc));
> +}
> +#endif
> +
> +#ifdef __NR_epoll_ctl
> +# include <sys/epoll.h>
> +void
> +test_epoll(void)
> +{
> +	int rc = epoll_ctl(-1, EPOLL_CTL_ADD, 5, NULL);
> +	printf("epoll_ctl(-1, EPOLL_CTL_ADD, 5, NULL) = %s\n", sprintrc(rc));
> +}
> +#endif
> +
> +#if defined HAVE_SYS_FANOTIFY_H && defined HAVE_FANOTIFY_MARK && \
> +	defined __NR_fanotify_mark
> +# include <sys/fanotify.h>
> +void
> +test_fanotify_mark(void)
> +{
> +	int rc = fanotify_mark(-1, 0, 0, 5, ".");
> +	printf("fanotify_mark(-1, 0, 0, 5, \".\") = %s\n", sprintrc(rc));
> +}
> +#endif
> +
> +#if defined __NR_select || defined __NR__newselect
> +# include <sys/select.h>
> +void
> +test_select(void)
> +{
> +	fd_set readset;
> +	FD_ZERO(&readset);
> +	FD_SET(5, &readset);
> +	int rc;
> +# ifndef __NR__newselect
> +	rc = syscall(__NR_select, 6, &readset, NULL, NULL, NULL);
> +	printf("select(6, [5], NULL, NULL, NULL) = %s\n", sprintrc(rc));
> +# else
> +	rc = syscall(__NR__newselect, 6, &readset, NULL, NULL, NULL);
> +	printf("_newselect(6, [5], NULL, NULL, NULL) = %s\n", sprintrc(rc));
> +# endif
> +}
> +#endif
> +
> +#ifdef __NR_poll
> +# include <poll.h>
> +void
> +test_poll(void)
> +{
> +	struct pollfd pfds = {.fd = 5, .events = POLLIN};
> +	poll(&pfds, 1, 1);
> +	printf("poll([{fd=5, events=POLLIN}], 1, 1) = 1 "
> +	       "([{fd=5, revents=POLLNVAL}])\n");
> +}
> +#endif
> +
> +int
> +main(int argc, char **argv)
> +{
> +	const char *const name = argc > 1 ? argv[1] : "mmap";
> +#ifdef __NR_dup2
> +	test_dup2();
> +#endif
You do not need these ifdef's if you use #ifdef ... void test_dup2() { ... }
#else void test_dup2() {} #endif idiom for defining specific checks.

> +
> +#ifdef __NR_linkat
> +	test_linkat();
> +#endif
> +
> +	mmap(NULL, 0, PROT_NONE, MAP_FILE, 5, 0);
> +	printf("%s(NULL, 0, PROT_NONE, MAP_FILE, 5, 0) = -1 EBADF (%m)\n",
> +	       name);
> +
> +#ifdef __NR_symlinkat
> +	test_symlinkat();
> +#endif
> +
> +#ifdef __NR_epoll_ctl
> +	test_epoll();
> +#endif
> +
> +#if defined HAVE_SYS_FANOTIFY_H && defined HAVE_FANOTIFY_MARK && \
> +	defined __NR_fanotify_mark
> +	test_fanotify_mark();
> +#endif
> +
> +#if defined __NR_select || defined __NR__newselect
> +	test_select();
> +#endif
> +
> +#ifdef __NR_poll
> +	test_poll();
> +#endif
> +
> +	puts("+++ exited with 0 +++");
> +	return 0;
> +}
It makes sense also check for negative matches, that nothing what
shouldn't been matched, is actually matched.

> diff --git a/tests/filtering_fd.test b/tests/filtering_fd.test
> new file mode 100755
> index 0000000..ec58f2e
> --- /dev/null
> +++ b/tests/filtering_fd.test
> @@ -0,0 +1,27 @@
> +#!/bin/sh
> +
> +# Check fd filtering
> +
> +. "${srcdir=.}/init.sh"
> +
> +check_prog grep
> +check_prog sed
> +run_prog > /dev/null
> +
> +syscall=
> +for n in mmap mmap2; do
> +	$STRACE -e$n -h > /dev/null && syscall=$syscall,$n
> +done
> +run_strace -e "trace(syscall $syscall && fd 5)" $args > /dev/null
> +
> +if grep '^mmap(NULL, 0, PROT_NONE,' < "$LOG" > /dev/null; then
> +	mmap=mmap
> +elif grep '^mmap2(NULL, 0, PROT_NONE,' < "$LOG" > /dev/null; then
> +	mmap=mmap2
> +else
> +	dump_log_and_fail_with "mmap/mmap2 not found in $STRACE $args output"
> +fi
I think it's better to move this check to some common file and not just
copy-paste it from mmap.test.

> +
> +run_prog "../$NAME" "$mmap" > /dev/null
> +run_strace -a12 -e "trace(fd 5)" $args > "$EXP"
> +match_diff "$LOG" "$EXP"
> diff --git a/tests/options-syntax.test b/tests/options-syntax.test
> index 47f6b66..f13506e 100755
> --- a/tests/options-syntax.test
> +++ b/tests/options-syntax.test
> @@ -37,17 +37,6 @@ check_e "Invalid process id: 'a'" -p 1,a
>  check_e "Syscall 'chdir' for -b isn't supported" -b chdir
>  check_e "Syscall 'chdir' for -b isn't supported" -b execve -b chdir
>  
> -check_e "invalid descriptor '-1'" -eread=-1
> -check_e "invalid descriptor '-42'" -ewrite=-42
> -check_e "invalid descriptor '2147483648'" -eread=2147483648
> -check_e "invalid descriptor '4294967296'" -ewrite=4294967296
> -check_e "invalid descriptor 'foo'" -eread=foo
> -check_e "invalid descriptor ''" -ewrite=
> -check_e "invalid descriptor ','" -eread=,
> -check_e "invalid descriptor '!'" -ewrite='!'
> -check_e "invalid descriptor '!'" -eread='0,!'
> -check_e "invalid descriptor '!,'" -ewrite='!,'
Note that these checks also check for various variants of -eread/-ewrite
syntax, I see no replacement for them in the code added.

> -
>  check_h 'must have PROG [ARGS] or -p PID'
>  check_h 'PROG [ARGS] must be specified with -D' -D -p $$
>  check_h '-c and -C are mutually exclusive' -c -C true
> -- 
> 2.1.4




More information about the Strace-devel mailing list