From b49c65cece4a1059e09ec4ead7cbb3bb890039f9 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Wed, 20 Jul 2016 02:28:25 +0000 Subject: [PATCH] tests: check decoding of socketcall syscall * tests/socketcall.c: New file. * tests/socketcall.test: New test. * tests/.gitignore: Add socketcall. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add socketcall.test. --- tests/.gitignore | 1 + tests/Makefile.am | 2 + tests/socketcall.c | 104 ++++++++++++++++++++++++++++++++++++++++++ tests/socketcall.test | 6 +++ 4 files changed, 113 insertions(+) create mode 100644 tests/socketcall.c create mode 100755 tests/socketcall.test diff --git a/tests/.gitignore b/tests/.gitignore index c9e62191..d0a6183c 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -250,6 +250,7 @@ signal_receive signalfd sigreturn sleep +socketcall splice stack-fcall stat diff --git a/tests/Makefile.am b/tests/Makefile.am index 9db29dba..6fae83ca 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -306,6 +306,7 @@ check_PROGRAMS = \ signalfd \ sigreturn \ sleep \ + socketcall \ splice \ stack-fcall \ stat \ @@ -625,6 +626,7 @@ DECODER_TESTS = \ siginfo.test \ signalfd.test \ sigreturn.test \ + socketcall.test \ splice.test \ stat.test \ stat64.test \ diff --git a/tests/socketcall.c b/tests/socketcall.c new file mode 100644 index 00000000..ad1803be --- /dev/null +++ b/tests/socketcall.c @@ -0,0 +1,104 @@ +/* + * Check decoding of socketcall syscall. + * + * 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 + +#ifdef __NR_socketcall + +# include +# include +# include + +# include "xlat.h" +# include "xlat/socketcalls.h" + +static const char * +xlookup_uint(const struct xlat *xlat, const unsigned int val) +{ + for (; xlat->str != NULL; xlat++) + if (xlat->val == val) + return xlat->str; + return NULL; +} + +static const int sc_min = 1, sc_max = 20; +static void *efault; + +static void +test_socketcall(const int i, const void *const addr) +{ + static const unsigned long a[] = { + (unsigned long) 0xface2fedbadc2ded, + (unsigned long) 0xface3fedbadc3ded, + (unsigned long) 0xface4fedbadc4ded, + (unsigned long) 0xface5fedbadc5ded + }; + const unsigned long call = + (unsigned long) 0xfacefeed00000000 | (unsigned int) i; + + long rc = syscall(__NR_socketcall, call, addr, + a[0], a[1], a[2], a[3]); + + if (i < sc_min || i > sc_max) { + printf("socketcall(%d, %p, %#lx, %#lx, %#lx, %#lx)" + " = %ld %s (%m)\n", (int) call, addr, + a[0], a[1], a[2], a[3], rc, errno2name()); + } else if (addr == efault) { + const char *const str = xlookup_uint(socketcalls, i); + assert(str); + printf("socketcall(%s, %p, %#lx, %#lx, %#lx, %#lx)" + " = %ld %s (%m)\n", str, addr, a[0], a[1], a[2], a[3], + rc, errno2name()); + } +} +int +main(void) +{ + assert((unsigned) sc_min == socketcalls[0].val); + assert((unsigned) sc_max == socketcalls[ARRAY_SIZE(socketcalls) - 2].val); + + const unsigned long *const args = tail_alloc(sizeof(*args) * 6); + efault = tail_alloc(1) + 1; + + int i; + for (i = sc_min - 3; i <= sc_max + 3; ++i) { + test_socketcall(i, efault); + test_socketcall(i, args); + } + + puts("+++ exited with 0 +++"); + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_socketcall") + +#endif diff --git a/tests/socketcall.test b/tests/socketcall.test new file mode 100755 index 00000000..b12ac02e --- /dev/null +++ b/tests/socketcall.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check decoding of socketcall syscall. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -- 2.40.0