Home | History | Annotate | Download | only in tests
      1 /*
      2  * This file is part of ioctl_loop strace test.
      3  *
      4  * Copyright (c) 2016 JingPiao Chen <chenjingpiao (at) gmail.com>
      5  * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr (at) gmail.com>
      6  * Copyright (c) 2016-2017 The strace developers.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. The name of the author may not be used to endorse or promote products
     18  *    derived from this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 
     33 #include "tests.h"
     34 #include <stdio.h>
     35 #include <stdbool.h>
     36 #include <string.h>
     37 #include <inttypes.h>
     38 #include <sys/ioctl.h>
     39 #include <sys/sysmacros.h>
     40 #include <linux/ioctl.h>
     41 #include <linux/loop.h>
     42 #include "print_fields.h"
     43 #include "xlat/loop_cmds.h"
     44 
     45 #ifndef ABBREV
     46 # define ABBREV 0
     47 #endif
     48 
     49 static void
     50 print_loop_info(struct loop_info * const info, bool print_encrypt,
     51 		const char *encrypt_type, const char *encrypt_key,
     52 		const char *flags)
     53 {
     54 #if ABBREV
     55 	printf("%p", info);
     56 #else
     57 	printf("{lo_number=%d", info->lo_number);
     58 # if VERBOSE
     59 	printf(", lo_device=makedev(%u, %u), lo_inode=%lu, "
     60 	       "lo_rdevice=makedev(%u, %u)",
     61 	       major(info->lo_device), minor(info->lo_device),
     62 	       info->lo_inode,
     63 	       major(info->lo_rdevice), minor(info->lo_rdevice));
     64 # endif /* VERBOSE */
     65 
     66 	printf(", lo_offset=%#x", info->lo_offset);
     67 
     68 	if (VERBOSE || print_encrypt) {
     69 		printf(", lo_encrypt_type=");
     70 		if (encrypt_type)
     71 			printf("%s", encrypt_type);
     72 		else
     73 			printf("%#x /* LO_CRYPT_??? */", info->lo_encrypt_type);
     74 
     75 		printf(", lo_encrypt_key_size=%" PRIu32,
     76 		       (uint32_t) info->lo_encrypt_key_size);
     77 	}
     78 
     79 	printf(", lo_flags=");
     80 	if (flags)
     81 		printf("%s", flags);
     82 	else
     83 		printf("%#x /* LO_FLAGS_??? */", info->lo_flags);
     84 
     85 	PRINT_FIELD_CSTRING(", ", *info, lo_name);
     86 
     87 	if (VERBOSE || print_encrypt)
     88 		printf(", lo_encrypt_key=\"%.*s\"",
     89 		       encrypt_key ? (int) strlen(encrypt_key) :
     90 		       (int) sizeof(info->lo_encrypt_key),
     91 		       encrypt_key ? encrypt_key :
     92 		       (char *) info->lo_encrypt_key);
     93 
     94 # if VERBOSE
     95 	printf(", lo_init=[%#lx, %#lx]"
     96 	       ", reserved=[%#hhx, %#hhx, %#hhx, %#hhx]}",
     97 	       info->lo_init[0], info->lo_init[1],
     98 	       info->reserved[0], info->reserved[1],
     99 	       info->reserved[2], info->reserved[3]);
    100 # else /* !VERBOSE */
    101 	printf(", ...}");
    102 # endif /* VERBOSE */
    103 #endif /* !ABBREV */
    104 }
    105 
    106 static void
    107 print_loop_info64(struct loop_info64 * const info64, bool print_encrypt,
    108 		  const char *encrypt_type, const char *encrypt_key,
    109 		  const char *flags)
    110 {
    111 #if ABBREV
    112 	printf("%p", info64);
    113 #else
    114 # if VERBOSE
    115 	printf("{lo_device=makedev(%u, %u), lo_inode=%" PRIu64
    116 	       ", lo_rdevice=makedev(%u, %u), lo_offset=%#" PRIx64
    117 	       ", lo_sizelimit=%" PRIu64 ", lo_number=%" PRIu32,
    118 	       major(info64->lo_device), minor(info64->lo_device),
    119 	       (uint64_t) info64->lo_inode,
    120 	       major(info64->lo_rdevice), minor(info64->lo_rdevice),
    121 	       (uint64_t) info64->lo_offset,
    122 	       (uint64_t) info64->lo_sizelimit,
    123 	       (uint32_t) info64->lo_number);
    124 # else /* !VERBOSE */
    125 	printf("{lo_offset=%#" PRIx64 ", lo_number=%" PRIu32,
    126 	       (uint64_t) info64->lo_offset,
    127 	       (uint32_t) info64->lo_number);
    128 # endif /* VERBOSE */
    129 
    130 	if (VERBOSE || print_encrypt) {
    131 		printf(", lo_encrypt_type=");
    132 		if (encrypt_type)
    133 			printf("%s", encrypt_type);
    134 		else
    135 			printf("%#x /* LO_CRYPT_??? */",
    136 			       info64->lo_encrypt_type);
    137 
    138 		printf(", lo_encrypt_key_size=%" PRIu32,
    139 		       info64->lo_encrypt_key_size);
    140 	}
    141 
    142 	printf(", lo_flags=");
    143 	if (flags)
    144 		printf("%s", flags);
    145 	else
    146 		printf("%#x /* LO_FLAGS_??? */", info64->lo_flags);
    147 	PRINT_FIELD_CSTRING(", ", *info64, lo_file_name);
    148 
    149 	if (VERBOSE || print_encrypt) {
    150 		PRINT_FIELD_CSTRING(", ", *info64, lo_crypt_name);
    151 		printf(", lo_encrypt_key=\"%.*s\"",
    152 		       encrypt_key ? (int) strlen(encrypt_key) :
    153 		       (int) sizeof(info64->lo_encrypt_key),
    154 		       encrypt_key ? encrypt_key :
    155 		       (char *) info64->lo_encrypt_key);
    156 	}
    157 
    158 # if VERBOSE
    159 	printf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",
    160 	       (uint64_t) info64->lo_init[0],
    161 	       (uint64_t) info64->lo_init[1]);
    162 # else /* !VERBOSE */
    163 	printf(", ...}");
    164 # endif /* VERBOSE */
    165 #endif /* !ABBREV */
    166 }
    167 
    168 int
    169 main(void)
    170 {
    171 	static const kernel_ulong_t unknown_loop_cmd =
    172 		(kernel_ulong_t) 0xbadc0dedfeed4cedULL;
    173 	static const kernel_ulong_t magic =
    174 		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
    175 	static const kernel_ulong_t kernel_mask =
    176 		((kernel_ulong_t) -1) - ((unsigned long) -1L);
    177 
    178 	TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_info, info);
    179 	TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_info64, info64);
    180 
    181 	/* Unknown loop commands */
    182 	ioctl(-1, unknown_loop_cmd, magic);
    183 	printf("ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE%s, 0x4c, %#x, %#x), "
    184 	       "%#lx) = -1 EBADF (%m)\n",
    185 	       _IOC_DIR((unsigned int) unknown_loop_cmd) & _IOC_NONE ?
    186 	       "|_IOC_NONE" : "",
    187 	       _IOC_NR((unsigned int) unknown_loop_cmd),
    188 	       _IOC_SIZE((unsigned int) unknown_loop_cmd),
    189 	       (unsigned long) magic);
    190 
    191 	ioctl(-1, LOOP_SET_BLOCK_SIZE + 1, magic);
    192 	printf("ioctl(-1, _IOC(0, 0x4c, %#x, %#x), %#lx) = "
    193 	       "-1 EBADF (%m)\n",
    194 	       _IOC_NR(LOOP_SET_BLOCK_SIZE + 1),
    195 	       _IOC_SIZE(LOOP_SET_BLOCK_SIZE + 1),
    196 	       (unsigned long) magic);
    197 
    198 	ioctl(-1, LOOP_CTL_GET_FREE + 1, magic);
    199 	printf("ioctl(-1, _IOC(0, 0x4c, %#x, %#x), %#lx) = "
    200 	       "-1 EBADF (%m)\n",
    201 	       _IOC_NR(LOOP_CTL_GET_FREE + 1),
    202 	       _IOC_SIZE(LOOP_CTL_GET_FREE + 1),
    203 	       (unsigned long) magic);
    204 
    205 	/* LOOP_SET_FD */
    206 	ioctl(-1, LOOP_SET_FD, magic);
    207 	printf("ioctl(-1, LOOP_SET_FD, %d) = -1 EBADF (%m)\n",
    208 	       (unsigned int) magic);
    209 
    210 	/* LOOP_CLR_FD */
    211 	ioctl(-1, LOOP_CLR_FD);
    212 	printf("ioctl(-1, LOOP_CLR_FD) = -1 EBADF (%m)\n");
    213 
    214 	/* LOOP_SET_STATUS */
    215 	ioctl(-1, LOOP_SET_STATUS, NULL);
    216 	printf("ioctl(-1, LOOP_SET_STATUS, NULL) = -1 EBADF (%m)\n");
    217 
    218 	fill_memory(info, sizeof(*info));
    219 	info->lo_flags = 0xdeface00;
    220 	info->lo_name[0] = '\0';
    221 	info->lo_encrypt_key[0] = '\0';
    222 	info->lo_encrypt_key_size = 1;
    223 
    224 	printf("ioctl(-1, LOOP_SET_STATUS, ");
    225 	print_loop_info(info, true, NULL, "\\0", NULL);
    226 	ioctl(-1, LOOP_SET_STATUS, info);
    227 	printf(") = -1 EBADF (%m)\n");
    228 
    229 	fill_memory(info, sizeof(*info));
    230 	info->lo_encrypt_type = LO_CRYPT_NONE;
    231 	info->lo_flags = LO_FLAGS_READ_ONLY;
    232 	memset(info->lo_name, 'A', sizeof(info->lo_name));
    233 	memset(info->lo_encrypt_key, 'B', sizeof(info->lo_encrypt_key));
    234 
    235 	ioctl(-1, LOOP_SET_STATUS, (void *) info + ALIGNOF(info));
    236 	printf("ioctl(-1, LOOP_SET_STATUS, %p) = -1 EBADF (%m)\n",
    237 	       (void *) info + ALIGNOF(info));
    238 
    239 	printf("ioctl(-1, LOOP_SET_STATUS, ");
    240 	print_loop_info(info, false, "LO_CRYPT_NONE", NULL,
    241 			"LO_FLAGS_READ_ONLY");
    242 	ioctl(-1, LOOP_SET_STATUS, info);
    243 	printf(") = -1 EBADF (%m)\n");
    244 
    245 	/* LOOP_GET_STATUS */
    246 	ioctl(-1, LOOP_GET_STATUS, NULL);
    247 	printf("ioctl(-1, LOOP_GET_STATUS, NULL) = -1 EBADF (%m)\n");
    248 
    249 	ioctl(-1, LOOP_GET_STATUS, (unsigned long) info | kernel_mask);
    250 	printf("ioctl(-1, LOOP_GET_STATUS, %p) = -1 EBADF (%m)\n", info);
    251 
    252 	/* LOOP_SET_STATUS64 */
    253 	ioctl(-1, LOOP_SET_STATUS64, NULL);
    254 	printf("ioctl(-1, LOOP_SET_STATUS64, NULL) = -1 EBADF (%m)\n");
    255 
    256 	fill_memory(info64, sizeof(*info64));
    257 	info64->lo_flags = 0xdec0de00;
    258 	info64->lo_file_name[0] = '\0';
    259 	info64->lo_crypt_name[0] = '\0';
    260 	info64->lo_encrypt_key[0] = '\0';
    261 	info64->lo_encrypt_key_size = 1;
    262 
    263 	printf("ioctl(-1, LOOP_SET_STATUS64, ");
    264 	print_loop_info64(info64, true, NULL, "\\0", NULL);
    265 	ioctl(-1, LOOP_SET_STATUS64, info64);
    266 	printf(") = -1 EBADF (%m)\n");
    267 
    268 	fill_memory(info64, sizeof(*info64));
    269 	info64->lo_flags = LO_FLAGS_READ_ONLY;
    270 	info64->lo_encrypt_type = LO_CRYPT_NONE;
    271 	memset(info64->lo_file_name, 'C', sizeof(info64->lo_file_name));
    272 	memset(info64->lo_crypt_name, 'D', sizeof(info64->lo_crypt_name));
    273 	memset(info64->lo_encrypt_key, 'E', sizeof(info64->lo_encrypt_key));
    274 
    275 	ioctl(-1, LOOP_SET_STATUS64, (void *) info64 + ALIGNOF(info64));
    276 	printf("ioctl(-1, LOOP_SET_STATUS64, %p) = -1 EBADF (%m)\n",
    277 	       (void *) info64 + ALIGNOF(info64));
    278 
    279 	printf("ioctl(-1, LOOP_SET_STATUS64, ");
    280 	print_loop_info64(info64, false, "LO_CRYPT_NONE", NULL,
    281 			  "LO_FLAGS_READ_ONLY");
    282 	ioctl(-1, LOOP_SET_STATUS64, info64);
    283 	printf(") = -1 EBADF (%m)\n");
    284 
    285 	/* LOOP_GET_STATUS64 */
    286 	ioctl(-1, LOOP_GET_STATUS64, NULL);
    287 	printf("ioctl(-1, LOOP_GET_STATUS64, NULL) = -1 EBADF (%m)\n");
    288 
    289 	ioctl(-1, LOOP_GET_STATUS64, (unsigned long) info64 | kernel_mask);
    290 	printf("ioctl(-1, LOOP_GET_STATUS64, %p) = -1 EBADF (%m)\n", info64);
    291 
    292 	/* LOOP_CHANGE_FD */
    293 	ioctl(-1, LOOP_CHANGE_FD, magic);
    294 	printf("ioctl(-1, LOOP_CHANGE_FD, %d) = -1 EBADF (%m)\n",
    295 	       (unsigned int) magic);
    296 
    297 	/* LOOP_SET_CAPACITY */
    298 	ioctl(-1, LOOP_SET_CAPACITY);
    299 	printf("ioctl(-1, LOOP_SET_CAPACITY) = -1 EBADF (%m)\n");
    300 
    301 	/* LOOP_SET_DIRECT_IO */
    302 	ioctl(-1, LOOP_SET_DIRECT_IO, magic);
    303 	printf("ioctl(-1, LOOP_SET_DIRECT_IO, %lu) = -1 EBADF (%m)\n",
    304 	       (unsigned long) magic);
    305 
    306 	/* LOOP_SET_BLOCK_SIZE */
    307 	ioctl(-1, LOOP_SET_BLOCK_SIZE, magic);
    308 	printf("ioctl(-1, LOOP_SET_BLOCK_SIZE, %lu) = -1 EBADF (%m)\n",
    309 	       (unsigned long) magic);
    310 
    311 	/* LOOP_CTL_ADD */
    312 	ioctl(-1, LOOP_CTL_ADD, magic);
    313 	printf("ioctl(-1, LOOP_CTL_ADD, %d) = -1 EBADF (%m)\n",
    314 	       (unsigned int) magic);
    315 
    316 	/* LOOP_CTL_REMOVE */
    317 	ioctl(-1, LOOP_CTL_REMOVE, magic);
    318 	printf("ioctl(-1, LOOP_CTL_REMOVE, %d) = -1 EBADF (%m)\n",
    319 	       (unsigned int) magic);
    320 
    321 	/* LOOP_CTL_GET_FREE */
    322 	ioctl(-1, LOOP_CTL_GET_FREE);
    323 	printf("ioctl(-1, LOOP_CTL_GET_FREE) = -1 EBADF (%m)\n");
    324 
    325 	puts("+++ exited with 0 +++");
    326 	return 0;
    327 }
    328