From ede97886b8c9c7f793d73e3c4f98410f23569c17 Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Fri, 5 Jan 2018 21:11:26 +0100 Subject: [PATCH] tests: check decoding of modify_ldt syscall * tests/modify_ldt.c: New file. * tests/gen_tests.in: Add modify_ldt test. * tests/pure_executables.list: Add modify_ldt. * tests/.gitignore: Likewise. --- tests/.gitignore | 1 + tests/gen_tests.in | 1 + tests/modify_ldt.c | 159 ++++++++++++++++++++++++++++++++++++ tests/pure_executables.list | 1 + 4 files changed, 162 insertions(+) create mode 100644 tests/modify_ldt.c diff --git a/tests/.gitignore b/tests/.gitignore index cfd66c68..09452701 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -190,6 +190,7 @@ mmsg mmsg-silent mmsg_name mmsg_name-v +modify_ldt mount move_pages mq diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 8dff19fd..0b79a4b3 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -174,6 +174,7 @@ mmsg -e read=0 -e write=1 -e trace=recvmmsg,sendmmsg mmsg-silent -a25 -e verbose=none -e trace=sendmmsg,recvmmsg mmsg_name -a25 -e trace=sendmmsg,recvmmsg mmsg_name-v -v -a25 -e trace=sendmmsg,recvmmsg +modify_ldt -a23 mount move_pages -s3 mq -a32 -e trace=mq_getsetattr,mq_open,mq_unlink diff --git a/tests/modify_ldt.c b/tests/modify_ldt.c new file mode 100644 index 00000000..510ae0b2 --- /dev/null +++ b/tests/modify_ldt.c @@ -0,0 +1,159 @@ +/* + * Check decoding of modify_ldt syscall. + * + * Copyright (c) 2018 The strace developers. + * 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_modify_ldt && defined HAVE_STRUCT_USER_DESC + +# include +# include +# include +# include + +void +print_user_desc(struct user_desc *us, const char *entry_str) +{ + if (entry_str) + printf("{entry_number=%s", entry_str); + else + printf("{entry_number=%u", us->entry_number); + + printf(", base_addr=%#08x" + ", limit=%#08x" + ", seg_32bit=%u" + ", contents=%u" + ", read_exec_only=%u" + ", limit_in_pages=%u" + ", seg_not_present=%u" + ", useable=%u" +#ifdef __x86_64__ + ", lm=%u" +#endif + "}", + us->base_addr, + us->limit, + us->seg_32bit, + us->contents, + us->read_exec_only, + us->limit_in_pages, + us->seg_not_present, + us->useable +#ifdef __x86_64__ + , us->lm +#endif + ); +} + +void +printrc(long rc) +{ +#ifdef __x86_64__ + int err = -rc; + + /* Thanks, long return type of syscall(2) */ + printf("%lld", zero_extend_signed_to_ull(rc)); + + if (err > 0 && err < 0x1000) { + errno = err; + printf(" %s (%m)", errno2name()); + } +#else + printf("%s", sprintrc(rc)); +#endif + + puts(""); +} + +int +main(void) +{ + static const kernel_ulong_t bogus_func = + (kernel_ulong_t) 0xbadc0dedda7a1057ULL; + static const kernel_ulong_t bogus_bytecount = + (kernel_ulong_t) 0xdeadfacefa57beefULL; + + struct user_desc *us = tail_alloc(sizeof(*us)); + long rc; + + fill_memory(us, sizeof(*us)); + + rc = syscall(__NR_modify_ldt, 0, 0, 0); + printf("modify_ldt(0, NULL, 0) = "); + printrc(rc); + + rc = syscall(__NR_modify_ldt, bogus_func, (kernel_long_t) -1, + bogus_bytecount); + printf("modify_ldt(%d, %#llx, %llu) = ", + (int) bogus_func, + zero_extend_signed_to_ull((kernel_long_t) -1), + (unsigned long long) bogus_bytecount); + printrc(rc); + + rc = syscall(__NR_modify_ldt, bogus_func, us + 1, 0); + printf("modify_ldt(%d, %p, 0) = ", (int) bogus_func, us + 1); + printrc(rc); + + rc = syscall(__NR_modify_ldt, bogus_func, us, 42); + printf("modify_ldt(%d, %p, 42) = ", (int) bogus_func, us); + printrc(rc); + + rc = syscall(__NR_modify_ldt, bogus_func, us + 1, sizeof(*us)); + printf("modify_ldt(%d, %p, %zu) = ", + (int) bogus_func, us + 1, sizeof(*us)); + printrc(rc); + + rc = syscall(__NR_modify_ldt, bogus_func, us, sizeof(*us)); + printf("modify_ldt(%d, ", (int) bogus_func); + print_user_desc(us, NULL); + printf(", %zu) = ", sizeof(*us)); + printrc(rc); + + fill_memory_ex(us, sizeof(*us), 0x55, 80); + us->entry_number = -1; + us->base_addr = 0; + us->limit = 0; + + rc = syscall(__NR_modify_ldt, bogus_func, us, sizeof(*us)); + printf("modify_ldt(%d, ", (int) bogus_func); + print_user_desc(us, "-1"); + printf(", %zu) = ", sizeof(*us)); + printrc(rc); + + puts("+++ exited with 0 +++"); + + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_modify_ldt && HAVE_STRUCT_USER_DESC"); + +#endif diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 0d1964de..07fa99ff 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -154,6 +154,7 @@ mmap mmap64 mmsg mmsg_name +modify_ldt mount move_pages mq -- 2.40.0