From 3127a6a2754ee3c5cef94c91b9583a39cb3fe7b7 Mon Sep 17 00:00:00 2001 From: JingPiao Chen Date: Tue, 27 Dec 2016 11:43:30 +0800 Subject: [PATCH] tests: check decoding of LOOP_* ioctls * tests/ioctl_loop.c: New file. * tests/ioctl_loop-v.c: Likewise. * tests/ioctl_loop.test: New test. * tests/ioctl_loop-v.test: Likewise. * tests/.gitignore: Add ioctl_loop and ioctl_loop-v. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add ioctl_loop.test and ioctl_loop-v.test. Co-authored-by: Eugene Syromyatnikov --- tests/.gitignore | 2 + tests/Makefile.am | 4 + tests/ioctl_loop-v.c | 2 + tests/ioctl_loop-v.test | 12 +++ tests/ioctl_loop.c | 221 ++++++++++++++++++++++++++++++++++++++++ tests/ioctl_loop.test | 12 +++ 6 files changed, 253 insertions(+) create mode 100644 tests/ioctl_loop-v.c create mode 100755 tests/ioctl_loop-v.test create mode 100644 tests/ioctl_loop.c create mode 100755 tests/ioctl_loop.test diff --git a/tests/.gitignore b/tests/.gitignore index a0a400a5..e4be0001 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -118,6 +118,8 @@ ioctl_dm ioctl_dm-v ioctl_evdev ioctl_evdev-v +ioctl_loop +ioctl_loop-v ioctl_mtd ioctl_rtc ioctl_rtc-v diff --git a/tests/Makefile.am b/tests/Makefile.am index d9dd1c98..205b9b68 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -179,6 +179,8 @@ check_PROGRAMS = \ ioctl_dm-v \ ioctl_evdev \ ioctl_evdev-v \ + ioctl_loop \ + ioctl_loop-v \ ioctl_mtd \ ioctl_rtc \ ioctl_rtc-v \ @@ -575,6 +577,8 @@ DECODER_TESTS = \ ioctl_dm-v.test \ ioctl_evdev.test \ ioctl_evdev-v.test \ + ioctl_loop-v.test \ + ioctl_loop.test \ ioctl_mtd.test \ ioctl_rtc.test \ ioctl_rtc-v.test \ diff --git a/tests/ioctl_loop-v.c b/tests/ioctl_loop-v.c new file mode 100644 index 00000000..22e75727 --- /dev/null +++ b/tests/ioctl_loop-v.c @@ -0,0 +1,2 @@ +#define VERBOSE 1 +#include "ioctl_loop.c" diff --git a/tests/ioctl_loop-v.test b/tests/ioctl_loop-v.test new file mode 100755 index 00000000..ff3995d8 --- /dev/null +++ b/tests/ioctl_loop-v.test @@ -0,0 +1,12 @@ +#!/bin/sh + +# Check non-abbreviated decoding of LOOP_* ioctls. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +run_strace -a22 -v -eioctl $args > "$EXP" +check_prog grep +grep -v '^ioctl([012],' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" +rm -f "$EXP" "$OUT" diff --git a/tests/ioctl_loop.c b/tests/ioctl_loop.c new file mode 100644 index 00000000..d2b0574f --- /dev/null +++ b/tests/ioctl_loop.c @@ -0,0 +1,221 @@ +/* + * This file is part of ioctl_loop strace test. + * + * Copyright (c) 2016 JingPiao Chen + * 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 +#include +#include +#include +#include +#include +#include +#include "xlat/loop_cmds.h" + +static void +print_loop_info(struct loop_info * const info, bool print_encrypt, + const char *encrypt_type, const char *encrypt_key, + const char *flags) +{ + printf("{lo_number=%d", info->lo_number); +# if VERBOSE + printf(", lo_device=makedev(%u, %u), lo_inode=%lu, " + "lo_rdevice=makedev(%u, %u)", + major(info->lo_device), minor(info->lo_device), + info->lo_inode, + major(info->lo_rdevice), minor(info->lo_rdevice)); +# endif /* VERBOSE */ + + printf(", lo_offset=%#x", info->lo_offset); + + if (VERBOSE || print_encrypt) { + printf(", lo_encrypt_type="); + if (encrypt_type) + printf("%s", encrypt_type); + else + printf("%#x /* LO_CRYPT_??? */", info->lo_encrypt_type); + + printf(", lo_encrypt_key_size=%" PRIu32, + (uint32_t) info->lo_encrypt_key_size); + } + + printf(", lo_flags="); + if (flags) + printf("%s", flags); + else + printf("%#x /* LO_FLAGS_??? */", info->lo_flags); + + printf(", lo_name=\"%.*s\"", + (int) sizeof(info->lo_name) - 1, info->lo_name); + + if (VERBOSE || print_encrypt) + printf(", lo_encrypt_key=\"%.*s\"", + encrypt_key ? (int) strlen(encrypt_key) : + (int) sizeof(info->lo_encrypt_key), + encrypt_key ? encrypt_key : + (char *) info->lo_encrypt_key); + +# if VERBOSE + printf(", lo_init=[%#lx, %#lx]" + ", reserved=[%#hhx, %#hhx, %#hhx, %#hhx]}", + info->lo_init[0], info->lo_init[1], + info->reserved[0], info->reserved[1], + info->reserved[2], info->reserved[3]); +# else /* !VERBOSE */ + printf(", ...}"); +# endif /* VERBOSE */ +} + +static void +print_loop_info64(struct loop_info64 * const info64, bool print_encrypt, + const char *encrypt_type, const char *encrypt_key, + const char *flags) +{ +# if VERBOSE + printf("{lo_device=makedev(%u, %u), lo_inode=%" PRIu64 + ", lo_rdevice=makedev(%u, %u), lo_offset=%#" PRIx64 + ", lo_sizelimit=%" PRIu64 ", lo_number=%" PRIu32, + major(info64->lo_device), minor(info64->lo_device), + (uint64_t) info64->lo_inode, + major(info64->lo_rdevice), minor(info64->lo_rdevice), + (uint64_t) info64->lo_offset, + (uint64_t) info64->lo_sizelimit, + (uint32_t) info64->lo_number); +# else /* !VERBOSE */ + printf("{lo_offset=%#" PRIx64 ", lo_number=%" PRIu32, + (uint64_t) info64->lo_offset, + (uint32_t) info64->lo_number); +# endif /* VERBOSE */ + + if (VERBOSE || print_encrypt) { + printf(", lo_encrypt_type="); + if (encrypt_type) + printf("%s", encrypt_type); + else + printf("%#x /* LO_CRYPT_??? */", + info64->lo_encrypt_type); + + printf(", lo_encrypt_key_size=%" PRIu32, + info64->lo_encrypt_key_size); + } + + printf(", lo_flags="); + if (flags) + printf("%s", flags); + else + printf("%#x /* LO_FLAGS_??? */", info64->lo_flags); + printf(", lo_file_name=\"%.*s\"", + (int) sizeof(info64->lo_file_name) - 1, info64->lo_file_name); + + if (VERBOSE || print_encrypt) + printf(", lo_crypt_name=\"%.*s\", lo_encrypt_key=\"%.*s\"", + (int) sizeof(info64->lo_crypt_name) - 1, + info64->lo_crypt_name, + encrypt_key ? (int) strlen(encrypt_key) : + (int) sizeof(info64->lo_encrypt_key), + encrypt_key ? encrypt_key : + (char *) info64->lo_encrypt_key); + +# if VERBOSE + printf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}", + (uint64_t) info64->lo_init[0], + (uint64_t) info64->lo_init[1]); +# else /* !VERBOSE */ + printf(", ...}"); +# endif /* VERBOSE */ +} + +static const unsigned int magic = 0xdeadbeef; +static const unsigned long lmagic = (unsigned long) 0xdeadbeefbadc0dedULL; + +int +main(void) +{ + ioctl(-1, LOOP_SET_FD, magic); + printf("ioctl(-1, LOOP_SET_FD, %d) = -1 EBADF (%m)\n", magic); + + ioctl(-1, LOOP_CLR_FD, 0); + printf("ioctl(-1, LOOP_CLR_FD) = -1 EBADF (%m)\n"); + + struct loop_info *const info = tail_alloc(sizeof(*info)); + + fill_memory((void *) info, sizeof(*info)); + info->lo_encrypt_type = LO_CRYPT_NONE; + info->lo_flags = LO_FLAGS_READ_ONLY; + memset(info->lo_name, 'A', sizeof(info->lo_name)); + memset(info->lo_encrypt_key, 'B', sizeof(info->lo_encrypt_key)); + printf("ioctl(-1, LOOP_SET_STATUS, "); + print_loop_info(info, false, "LO_CRYPT_NONE", NULL, + "LO_FLAGS_READ_ONLY"); + ioctl(-1, LOOP_SET_STATUS, info); + printf(") = -1 EBADF (%m)\n"); + + ioctl(-1, LOOP_GET_STATUS, info); + printf("ioctl(-1, LOOP_GET_STATUS, %p) = -1 EBADF (%m)\n", info); + + struct loop_info64 *const info64 = tail_alloc(sizeof(*info64)); + + fill_memory((void *) info64, sizeof(*info64)); + info64->lo_flags = LO_FLAGS_READ_ONLY; + info64->lo_encrypt_type = LO_CRYPT_NONE; + memset(info64->lo_file_name, 'C', sizeof(info64->lo_file_name)); + memset(info64->lo_crypt_name, 'D', sizeof(info64->lo_crypt_name)); + memset(info64->lo_encrypt_key, 'E', sizeof(info64->lo_encrypt_key)); + + printf("ioctl(-1, LOOP_SET_STATUS64, "); + print_loop_info64(info64, false, "LO_CRYPT_NONE", NULL, + "LO_FLAGS_READ_ONLY"); + ioctl(-1, LOOP_SET_STATUS64, info64); + printf(") = -1 EBADF (%m)\n"); + + ioctl(-1, LOOP_GET_STATUS64, info64); + printf("ioctl(-1, LOOP_GET_STATUS64, %p) = -1 EBADF (%m)\n", info64); + + ioctl(-1, LOOP_CHANGE_FD, magic); + printf("ioctl(-1, LOOP_CHANGE_FD, %d) = -1 EBADF (%m)\n", magic); + + ioctl(-1, LOOP_SET_CAPACITY, 0); + printf("ioctl(-1, LOOP_SET_CAPACITY) = -1 EBADF (%m)\n"); + + ioctl(-1, LOOP_SET_DIRECT_IO, lmagic); + printf("ioctl(-1, LOOP_SET_DIRECT_IO, %lu) = -1 EBADF (%m)\n", lmagic); + + ioctl(-1, LOOP_CTL_ADD, magic); + printf("ioctl(-1, LOOP_CTL_ADD, %d) = -1 EBADF (%m)\n", magic); + + ioctl(-1, LOOP_CTL_REMOVE, magic); + printf("ioctl(-1, LOOP_CTL_REMOVE, %d) = -1 EBADF (%m)\n", magic); + + ioctl(-1, LOOP_CTL_GET_FREE, 0); + printf("ioctl(-1, LOOP_CTL_GET_FREE) = -1 EBADF (%m)\n"); + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/ioctl_loop.test b/tests/ioctl_loop.test new file mode 100755 index 00000000..112cd636 --- /dev/null +++ b/tests/ioctl_loop.test @@ -0,0 +1,12 @@ +#!/bin/sh + +# Check decoding of LOOP_* ioctls. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +run_strace -a22 -eioctl $args > "$EXP" +check_prog grep +grep -v '^ioctl([012],' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" +rm -f "$EXP" "$OUT" -- 2.40.0