From 3b31d33ada0dc55a897e131026abafbc1907c073 Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Mon, 17 Oct 2016 02:17:48 +0300 Subject: [PATCH] tests: check decoding of {init,finit,delete}_module syscalls * tests/delete_module.c: New file. * tests/finit_module.c: Likewise. * tests/init_delete_module.h: Likewise. * tests/init_module.c: Likewise. * tests/delete_module.test: New test. * tests/finit_module.test: Likewise. * tests/init_module.test: Likewise. * tests/.gitignore: Add delete_nodule, finit_module, and init_module. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add delete_module.test, finit_module.test, and init_module.test. (EXTRA_DIST): Add init_delete_module.h. --- tests/.gitignore | 3 + tests/Makefile.am | 7 +++ tests/delete_module.c | 115 ++++++++++++++++++++++++++++++++++++ tests/delete_module.test | 6 ++ tests/finit_module.c | 117 +++++++++++++++++++++++++++++++++++++ tests/finit_module.test | 6 ++ tests/init_delete_module.h | 67 +++++++++++++++++++++ tests/init_module.c | 106 +++++++++++++++++++++++++++++++++ tests/init_module.test | 6 ++ 9 files changed, 433 insertions(+) create mode 100644 tests/delete_module.c create mode 100755 tests/delete_module.test create mode 100644 tests/finit_module.c create mode 100755 tests/finit_module.test create mode 100644 tests/init_delete_module.h create mode 100644 tests/init_module.c create mode 100755 tests/init_module.test diff --git a/tests/.gitignore b/tests/.gitignore index 17bfea9d..97ae554e 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -31,6 +31,7 @@ clock_xettime copy_file_range count-f creat +delete_module dup dup2 dup3 @@ -61,6 +62,7 @@ fdatasync file_handle file_ioctl filter-unavailable +finit_module flock fork-f fstat @@ -101,6 +103,7 @@ getuid getuid32 getxxid inet-cmsg +init_module inotify inotify_init1 ioctl diff --git a/tests/Makefile.am b/tests/Makefile.am index e8dff046..a24ada2c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -91,6 +91,7 @@ check_PROGRAMS = \ copy_file_range \ count-f \ creat \ + delete_module \ dup \ dup2 \ dup3 \ @@ -121,6 +122,7 @@ check_PROGRAMS = \ file_handle \ file_ioctl \ filter-unavailable \ + finit_module \ flock \ fork-f \ fstat \ @@ -161,6 +163,7 @@ check_PROGRAMS = \ getuid32 \ getxxid \ inet-cmsg \ + init_module \ inotify \ inotify_init1 \ ioctl \ @@ -445,6 +448,7 @@ DECODER_TESTS = \ clock_xettime.test \ copy_file_range.test \ creat.test \ + delete_module.test \ dup.test \ dup2.test \ dup3.test \ @@ -474,6 +478,7 @@ DECODER_TESTS = \ fdatasync.test \ file_handle.test \ file_ioctl.test \ + finit_module.test \ flock.test \ fstat.test \ fstat64.test \ @@ -513,6 +518,7 @@ DECODER_TESTS = \ getuid32.test \ getxxid.test \ inet-cmsg.test \ + init_module.test \ inotify.test \ inotify_init1.test \ ioctl.test \ @@ -779,6 +785,7 @@ EXTRA_DIST = init.sh run.sh match.awk \ fstatat.c \ fstatx.c \ getresugid.c \ + init_delete_module.h \ ipc.sh \ ipc_msgbuf.expected \ ksysent.sed \ diff --git a/tests/delete_module.c b/tests/delete_module.c new file mode 100644 index 00000000..5a317603 --- /dev/null +++ b/tests/delete_module.c @@ -0,0 +1,115 @@ +/* + * Check decoding of delete_module syscall. + * + * Copyright (c) 2016 Eugene Syromyatnikov + * 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 + +#if defined(__NR_delete_module) + +# include +# include +# include + +# include "init_delete_module.h" + +int +main(void) +{ + static const struct { + kernel_ulong_t val; + const char *str; + unsigned int val_prefix, val_suffix; + } flags[] = { + { ARG_STR(0), 0, 0 }, + { (kernel_ulong_t) 0xffffffff00000000ULL | O_NONBLOCK, + "O_NONBLOCK", 0, 0 }, + { (kernel_ulong_t) 0xbadc0dedfacef157ULL & ~(O_NONBLOCK | O_TRUNC), + " /* O_??? */", 0xfacef157U & ~(O_NONBLOCK | O_TRUNC), 0}, + { (kernel_ulong_t) (0xfacef157deade71cULL & ~O_NONBLOCK) | O_TRUNC, + "O_TRUNC", 0, 0xdeade71c & ~(O_NONBLOCK | O_TRUNC)}, + { -1LL, "O_NONBLOCK|O_TRUNC", 0, -1U & ~(O_NONBLOCK | O_TRUNC)}, + }; + + long rc; + char *bogus_param1 = tail_alloc(PARAM1_LEN); + char *bogus_param2 = tail_alloc(PARAM2_LEN); + const char *errstr; + + fill_memory_ex(bogus_param1, PARAM1_LEN, PARAM1_BASE, PARAM1_LEN); + fill_memory_ex(bogus_param2, PARAM2_LEN, PARAM2_BASE, PARAM2_LEN); + + rc = syscall(__NR_delete_module, NULL, bogus_zero); + printf("delete_module(NULL, 0) = %s\n", sprintrc(rc)); + + rc = syscall(__NR_delete_module, bogus_param1, flags[0].val); + errstr = sprintrc(rc); + + printf("delete_module(\""); + print_str(PARAM1_BASE, MAX_STRLEN, false); + printf("\"..., %s) = %s\n", flags[0].str, errstr); + + bogus_param1[PARAM1_LEN - 1] = '\0'; + + rc = syscall(__NR_delete_module, bogus_param1, flags[1].val); + errstr = sprintrc(rc); + + printf("delete_module(\""); + print_str(PARAM1_BASE, MAX_STRLEN, false); + printf("\", %s) = %s\n", flags[1].str, errstr); + + rc = syscall(__NR_delete_module, bogus_param2 + PARAM2_LEN, + flags[2].val); + printf("delete_module(%p, %#x%s) = %s\n", + bogus_param2 + PARAM2_LEN, flags[2].val_prefix, + flags[2].str, sprintrc(rc)); + + rc = syscall(__NR_delete_module, bogus_param2, flags[3].val); + printf("delete_module(%p, %s|%#x) = %s\n", + bogus_param2, flags[3].str, flags[3].val_suffix, sprintrc(rc)); + + bogus_param2[PARAM2_LEN - 1] = '\0'; + + rc = syscall(__NR_delete_module, bogus_param2, flags[4].val); + errstr = sprintrc(rc); + + printf("delete_module(\""); + print_str(PARAM2_BASE, PARAM2_LEN - 1, true); + printf("\", %s|%#x) = %s\n", flags[4].str, flags[4].val_suffix, errstr); + + puts("+++ exited with 0 +++"); + + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_delete_module"); + +#endif diff --git a/tests/delete_module.test b/tests/delete_module.test new file mode 100755 index 00000000..fb86ec9a --- /dev/null +++ b/tests/delete_module.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check decoding of delete_module syscall. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -a23 diff --git a/tests/finit_module.c b/tests/finit_module.c new file mode 100644 index 00000000..0394fad1 --- /dev/null +++ b/tests/finit_module.c @@ -0,0 +1,117 @@ +/* + * Check decoding of finit_module syscall. + * + * Copyright (c) 2016 Eugene Syromyatnikov + * 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 + +#if defined(__NR_finit_module) + +# include +# include + +# include "init_delete_module.h" + +int +main(void) +{ + static const kernel_ulong_t bogus_fd = + (kernel_ulong_t) 0xdeb0d1edbeeff00dULL; + + static const struct { + kernel_ulong_t val; + const char *str; + } flags[] = { + { ARG_STR(0) }, + { (kernel_ulong_t) 0xffffffff00000002ULL, + "MODULE_INIT_IGNORE_VERMAGIC" }, + { (kernel_ulong_t) 0xbadc0deddefaced0ULL, + "0xdefaced0 /* MODULE_INIT_??? */" }, + { (kernel_ulong_t) 0xfacef157dec0ded1ULL, + "MODULE_INIT_IGNORE_MODVERSIONS|0xdec0ded0" }, + { -1LL, "MODULE_INIT_IGNORE_MODVERSIONS|" + "MODULE_INIT_IGNORE_VERMAGIC|0xfffffffc" }, + }; + + long rc; + char *bogus_param1 = tail_alloc(PARAM1_LEN); + char *bogus_param2 = tail_alloc(PARAM2_LEN); + const char *errstr; + + fill_memory_ex(bogus_param1, PARAM1_LEN, PARAM1_BASE, PARAM1_LEN); + fill_memory_ex(bogus_param2, PARAM2_LEN, PARAM2_BASE, PARAM2_LEN); + + rc = syscall(__NR_finit_module, bogus_zero, NULL, bogus_zero); + printf("finit_module(0, NULL, 0) = %s\n", sprintrc(rc)); + + rc = syscall(__NR_finit_module, bogus_fd, bogus_param1, flags[0].val); + errstr = sprintrc(rc); + + printf("finit_module(%d, \"", (int) bogus_fd); + print_str(PARAM1_BASE, MAX_STRLEN, false); + printf("\"..., %s) = %s\n", flags[0].str, errstr); + + bogus_param1[PARAM1_LEN - 1] = '\0'; + + rc = syscall(__NR_finit_module, bogus_fd, bogus_param1, flags[1].val); + errstr = sprintrc(rc); + + printf("finit_module(%d, \"", (int) bogus_fd); + print_str(PARAM1_BASE, MAX_STRLEN, false); + printf("\", %s) = %s\n", flags[1].str, errstr); + + rc = syscall(__NR_finit_module, bogus_fd, bogus_param2 + PARAM2_LEN, + flags[2].val); + printf("finit_module(%d, %p, %s) = %s\n", + (int) bogus_fd, bogus_param2 + PARAM2_LEN, flags[2].str, + sprintrc(rc)); + + rc = syscall(__NR_finit_module, bogus_fd, bogus_param2, flags[3].val); + printf("finit_module(%d, %p, %s) = %s\n", + (int) bogus_fd, bogus_param2, flags[3].str, sprintrc(rc)); + + bogus_param2[PARAM2_LEN - 1] = '\0'; + + rc = syscall(__NR_finit_module, bogus_fd, bogus_param2, flags[4].val); + errstr = sprintrc(rc); + + printf("finit_module(%d, \"", (int) bogus_fd); + print_str(PARAM2_BASE, PARAM2_LEN - 1, true); + printf("\", %s) = %s\n", flags[4].str, errstr); + + puts("+++ exited with 0 +++"); + + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_finit_module"); + +#endif diff --git a/tests/finit_module.test b/tests/finit_module.test new file mode 100755 index 00000000..bd644f38 --- /dev/null +++ b/tests/finit_module.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check decoding of finit_module syscall. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -a25 diff --git a/tests/init_delete_module.h b/tests/init_delete_module.h new file mode 100644 index 00000000..f16994c7 --- /dev/null +++ b/tests/init_delete_module.h @@ -0,0 +1,67 @@ +/* + * Helper header containing common code for finit_module, init_module, + * and delete_module tests. + * + * Copyright (c) 2016 Eugene Syromyatnikov + * 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. + */ + +#ifndef STRACE_TESTS_INIT_DELETE_MODULE_H +#define STRACE_TESTS_INIT_DELETE_MODULE_H + +# include +# include + +# include "kernel_types.h" + + +enum { + PARAM1_LEN = 33, + PARAM2_LEN = 8, + PARAM1_BASE = 0x30, + PARAM2_BASE = 0x80, + MAX_STRLEN = 32, +}; + +static const kernel_ulong_t bogus_zero = + (kernel_ulong_t) 0xffffffff00000000ULL; + +static void +print_str(unsigned int base, unsigned int len, bool escape) +{ + unsigned int i; + + if (!escape) { + for (i = base; i < (base + len); i++) + putc(i, stdout); + + return; + } + + for (i = base; i < (base + len); i++) + printf("\\%u%u%u", (i >> 6) & 0x3, (i >> 3) & 0x7, i & 0x7); +} + +#endif /* !STRACE_TESTS_INIT_DELETE_MODULE_H */ diff --git a/tests/init_module.c b/tests/init_module.c new file mode 100644 index 00000000..88ef9ec8 --- /dev/null +++ b/tests/init_module.c @@ -0,0 +1,106 @@ +/* + * Check decoding of init_module syscall. + * + * Copyright (c) 2016 Eugene Syromyatnikov + * 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 + +#if defined(__NR_init_module) + +# include +# include + +# include "init_delete_module.h" + +int +main(void) +{ + + static const kernel_ulong_t bogus_addr = + (kernel_ulong_t) 0xfffffeedfffffaceULL; + static const kernel_ulong_t bogus_len = + (kernel_ulong_t) 0xfffffca7ffffc0deULL; + + long rc; + char *bogus_param1 = tail_alloc(PARAM1_LEN); + char *bogus_param2 = tail_alloc(PARAM2_LEN); + const char *errstr; + + fill_memory_ex(bogus_param1, PARAM1_LEN, PARAM1_BASE, PARAM1_LEN); + fill_memory_ex(bogus_param2, PARAM2_LEN, PARAM2_BASE, PARAM2_LEN); + + rc = syscall(__NR_init_module, NULL, bogus_zero, NULL); + printf("init_module(NULL, %llu, NULL) = %s\n", + (unsigned long long) bogus_zero, sprintrc(rc)); + + rc = syscall(__NR_init_module, bogus_addr, 0, bogus_param1); + errstr = sprintrc(rc); + + printf("init_module(%#llx, 0, \"", (unsigned long long) bogus_addr); + print_str(PARAM1_BASE, MAX_STRLEN, false); + printf("\"...) = %s\n", errstr); + + bogus_param1[PARAM1_LEN - 1] = '\0'; + + rc = syscall(__NR_init_module, bogus_addr, 0, bogus_param1); + errstr = sprintrc(rc); + + printf("init_module(%#llx, 0, \"", (unsigned long long) bogus_addr); + print_str(PARAM1_BASE, MAX_STRLEN, false); + printf("\") = %s\n", errstr); + + rc = syscall(__NR_init_module, bogus_addr, bogus_len, + bogus_param2 + PARAM2_LEN); + printf("init_module(%#llx, %llu, %p) = %s\n", + (unsigned long long) bogus_addr, (unsigned long long) bogus_len, + bogus_param2 + PARAM2_LEN, sprintrc(rc)); + + rc = syscall(__NR_init_module, NULL, bogus_len, bogus_param2); + printf("init_module(NULL, %llu, %p) = %s\n", + (unsigned long long) bogus_len, bogus_param2, sprintrc(rc)); + + bogus_param2[PARAM2_LEN - 1] = '\0'; + + rc = syscall(__NR_init_module, NULL, bogus_len, bogus_param2); + errstr = sprintrc(rc); + + printf("init_module(NULL, %llu, \"", (unsigned long long) bogus_len); + print_str(PARAM2_BASE, PARAM2_LEN - 1, true); + printf("\") = %s\n", errstr); + + puts("+++ exited with 0 +++"); + + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_init_module"); + +#endif diff --git a/tests/init_module.test b/tests/init_module.test new file mode 100755 index 00000000..ef7c7325 --- /dev/null +++ b/tests/init_module.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check decoding of init_module syscall. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -a27 -- 2.40.0