[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