]> granicus.if.org Git - strace/commitdiff
tests: check decoding of LOOP_* ioctls
authorJingPiao Chen <chenjingpiao@gmail.com>
Tue, 27 Dec 2016 03:43:30 +0000 (11:43 +0800)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 4 Jan 2017 19:59:27 +0000 (19:59 +0000)
* 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 <evgsyr@gmail.com>
tests/.gitignore
tests/Makefile.am
tests/ioctl_loop-v.c [new file with mode: 0644]
tests/ioctl_loop-v.test [new file with mode: 0755]
tests/ioctl_loop.c [new file with mode: 0644]
tests/ioctl_loop.test [new file with mode: 0755]

index a0a400a5d2230b1c5d2a7c3328b403784de5e886..e4be00015169f84c6fde7bedd055c825c020d320 100644 (file)
@@ -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
index d9dd1c9892a0c07cf60df1b7e06123592fb9bfd3..205b9b68515282ca5b8e64692172ee175f2bb494 100644 (file)
@@ -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 (file)
index 0000000..22e7572
--- /dev/null
@@ -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 (executable)
index 0000000..ff3995d
--- /dev/null
@@ -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 (file)
index 0000000..d2b0574
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * This file is part of ioctl_loop strace test.
+ *
+ * Copyright (c) 2016 JingPiao Chen <chenjingpiao@gmail.com>
+ * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@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 <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/ioctl.h>
+#include <sys/sysmacros.h>
+#include <linux/loop.h>
+#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 (executable)
index 0000000..112cd63
--- /dev/null
@@ -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"