Home | History | Annotate | Download | only in tests-m32
      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 "xlat/loop_cmds.h"
     43 
     44 #ifndef ABBREV
     45 # define ABBREV 0
     46 #endif
     47 
     48 static void
     49 print_loop_info(struct loop_info * const info, bool print_encrypt,
     50 		const char *encrypt_type, const char *encrypt_key,
     51 		const char *flags)
     52 {
     53 #if ABBREV
     54 	printf("%p", info);
     55 #else
     56 	printf("{lo_number=%d", info->lo_number);
     57 # if VERBOSE
     58 	printf(", lo_device=makedev(%u, %u), lo_inode=%lu, "
     59 	       "lo_rdevice=makedev(%u, %u)",
     60 	       major(info->lo_device), minor(info->lo_device),
     61 	       info->lo_inode,
     62 	       major(info->lo_rdevice), minor(info->lo_rdevice));
     63 # endif /* VERBOSE */
     64 
     65 	printf(", lo_offset=%#x", info->lo_offset);
     66 
     67 	if (VERBOSE || print_encrypt) {
     68 		printf(", lo_encrypt_type=");
     69 		if (encrypt_type)
     70 			printf("%s", encrypt_type);
     71 		else
     72 			printf("%#x /* LO_CRYPT_??? */", info->lo_encrypt_type);
     73 
     74 		printf(", lo_encrypt_key_size=%" PRIu32,
     75 		       (uint32_t) info->lo_encrypt_key_size);
     76 	}
     77 
     78 	printf(", lo_flags=");
     79 	if (flags)
     80 		printf("%s", flags);
     81 	else
     82 		printf("%#x /* LO_FLAGS_??? */", info->lo_flags);
     83 
     84 	printf(", lo_name=\"%.*s\"",
     85 	       (int) sizeof(info->lo_name) - 1, 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 	printf(", lo_file_name=\"%.*s\"",
    148 	       (int) sizeof(info64->lo_file_name) - 1, info64->lo_file_name);
    149 
    150 	if (VERBOSE || print_encrypt)
    151 		printf(", lo_crypt_name=\"%.*s\", lo_encrypt_key=\"%.*s\"",
    152 		       (int) sizeof(info64->lo_crypt_name) - 1,
    153 		       info64->lo_crypt_name,
    154 		       encrypt_key ? (int) strlen(encrypt_key) :
    155 		       (int) sizeof(info64->lo_encrypt_key),
    156 		       encrypt_key ? encrypt_key :
    157 		       (char *) info64->lo_encrypt_key);
    158 
    159 # if VERBOSE
    160 	printf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",
    161 	       (uint64_t) info64->lo_init[0],
    162 	       (uint64_t) info64->lo_init[1]);
    163 # else /* !VERBOSE */
    164 	printf(", ...}");
    165 # endif /* VERBOSE */
    166 #endif /* !ABBREV */
    167 }
    168 
    169 int
    170 main(void)
    171 {
    172 	static const kernel_ulong_t unknown_loop_cmd =
    173 		(kernel_ulong_t) 0xbadc0dedfeed4cedULL;
    174 	static const kernel_ulong_t magic =
    175 		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
    176 	static const kernel_ulong_t kernel_mask =
    177 		((kernel_ulong_t) -1) - ((unsigned long) -1L);
    178 
    179 	TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_info, info);
    180 	TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_info64, info64);
    181 
    182 	/* Unknown loop commands */
    183 	ioctl(-1, unknown_loop_cmd, magic);
    184 	printf("ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE%s, 0x4c, %#x, %#x), "
    185 	       "%#lx) = -1 EBADF (%m)\n",
    186 	       _IOC_DIR((unsigned int) unknown_loop_cmd) & _IOC_NONE ?
    187 	       "|_IOC_NONE" : "",
    188 	       _IOC_NR((unsigned int) unknown_loop_cmd),
    189 	       _IOC_SIZE((unsigned int) unknown_loop_cmd),
    190 	       (unsigned long) magic);
    191 
    192 	ioctl(-1, LOOP_SET_DIRECT_IO + 1, magic);
    193 	printf("ioctl(-1, _IOC(0, 0x4c, %#x, %#x), %#lx) = "
    194 	       "-1 EBADF (%m)\n",
    195 	       _IOC_NR(LOOP_SET_DIRECT_IO + 1),
    196 	       _IOC_SIZE(LOOP_SET_DIRECT_IO + 1),
    197 	       (unsigned long) magic);
    198 
    199 	ioctl(-1, LOOP_CTL_GET_FREE + 1, magic);
    200 	printf("ioctl(-1, _IOC(0, 0x4c, %#x, %#x), %#lx) = "
    201 	       "-1 EBADF (%m)\n",
    202 	       _IOC_NR(LOOP_CTL_GET_FREE + 1),
    203 	       _IOC_SIZE(LOOP_CTL_GET_FREE + 1),
    204 	       (unsigned long) magic);
    205 
    206 	/* LOOP_SET_FD */
    207 	ioctl(-1, LOOP_SET_FD, magic);
    208 	printf("ioctl(-1, LOOP_SET_FD, %d) = -1 EBADF (%m)\n",
    209 	       (unsigned int) magic);
    210 
    211 	/* LOOP_CLR_FD */
    212 	ioctl(-1, LOOP_CLR_FD);
    213 	printf("ioctl(-1, LOOP_CLR_FD) = -1 EBADF (%m)\n");
    214 
    215 	/* LOOP_SET_STATUS */
    216 	ioctl(-1, LOOP_SET_STATUS, NULL);
    217 	printf("ioctl(-1, LOOP_SET_STATUS, NULL) = -1 EBADF (%m)\n");
    218 
    219 	fill_memory(info, sizeof(*info));
    220 	info->lo_flags = 0xdeface00;
    221 	info->lo_name[0] = '\0';
    222 	info->lo_encrypt_key[0] = '\0';
    223 	info->lo_encrypt_key_size = 1;
    224 
    225 	printf("ioctl(-1, LOOP_SET_STATUS, ");
    226 	print_loop_info(info, true, NULL, "\\0", NULL);
    227 	ioctl(-1, LOOP_SET_STATUS, info);
    228 	printf(") = -1 EBADF (%m)\n");
    229 
    230 	fill_memory(info, sizeof(*info));
    231 	info->lo_encrypt_type = LO_CRYPT_NONE;
    232 	info->lo_flags = LO_FLAGS_READ_ONLY;
    233 	memset(info->lo_name, 'A', sizeof(info->lo_name));
    234 	memset(info->lo_encrypt_key, 'B', sizeof(info->lo_encrypt_key));
    235 
    236 	ioctl(-1, LOOP_SET_STATUS, (void *) info + ALIGNOF(info));
    237 	printf("ioctl(-1, LOOP_SET_STATUS, %p) = -1 EBADF (%m)\n",
    238 	       (void *) info + ALIGNOF(info));
    239 
    240 	printf("ioctl(-1, LOOP_SET_STATUS, ");
    241 	print_loop_info(info, false, "LO_CRYPT_NONE", NULL,
    242 			"LO_FLAGS_READ_ONLY");
    243 	ioctl(-1, LOOP_SET_STATUS, info);
    244 	printf(") = -1 EBADF (%m)\n");
    245 
    246 	/* LOOP_GET_STATUS */
    247 	ioctl(-1, LOOP_GET_STATUS, NULL);
    248 	printf("ioctl(-1, LOOP_GET_STATUS, NULL) = -1 EBADF (%m)\n");
    249 
    250 	ioctl(-1, LOOP_GET_STATUS, (unsigned long) info | kernel_mask);
    251 	printf("ioctl(-1, LOOP_GET_STATUS, %p) = -1 EBADF (%m)\n", info);
    252 
    253 	/* LOOP_SET_STATUS64 */
    254 	ioctl(-1, LOOP_SET_STATUS64, NULL);
    255 	printf("ioctl(-1, LOOP_SET_STATUS64, NULL) = -1 EBADF (%m)\n");
    256 
    257 	fill_memory(info64, sizeof(*info64));
    258 	info64->lo_flags = 0xdec0de00;
    259 	info64->lo_file_name[0] = '\0';
    260 	info64->lo_crypt_name[0] = '\0';
    261 	info64->lo_encrypt_key[0] = '\0';
    262 	info64->lo_encrypt_key_size = 1;
    263 
    264 	printf("ioctl(-1, LOOP_SET_STATUS64, ");
    265 	print_loop_info64(info64, true, NULL, "\\0", NULL);
    266 	ioctl(-1, LOOP_SET_STATUS64, info64);
    267 	printf(") = -1 EBADF (%m)\n");
    268 
    269 	fill_memory(info64, sizeof(*info64));
    270 	info64->lo_flags = LO_FLAGS_READ_ONLY;
    271 	info64->lo_encrypt_type = LO_CRYPT_NONE;
    272 	memset(info64->lo_file_name, 'C', sizeof(info64->lo_file_name));
    273 	memset(info64->lo_crypt_name, 'D', sizeof(info64->lo_crypt_name));
    274 	memset(info64->lo_encrypt_key, 'E', sizeof(info64->lo_encrypt_key));
    275 
    276 	ioctl(-1, LOOP_SET_STATUS64, (void *) info64 + ALIGNOF(info64));
    277 	printf("ioctl(-1, LOOP_SET_STATUS64, %p) = -1 EBADF (%m)\n",
    278 	       (void *) info64 + ALIGNOF(info64));
    279 
    280 	printf("ioctl(-1, LOOP_SET_STATUS64, ");
    281 	print_loop_info64(info64, false, "LO_CRYPT_NONE", NULL,
    282 			  "LO_FLAGS_READ_ONLY");
    283 	ioctl(-1, LOOP_SET_STATUS64, info64);
    284 	printf(") = -1 EBADF (%m)\n");
    285 
    286 	/* LOOP_GET_STATUS64 */
    287 	ioctl(-1, LOOP_GET_STATUS64, NULL);
    288 	printf("ioctl(-1, LOOP_GET_STATUS64, NULL) = -1 EBADF (%m)\n");
    289 
    290 	ioctl(-1, LOOP_GET_STATUS64, (unsigned long) info64 | kernel_mask);
    291 	printf("ioctl(-1, LOOP_GET_STATUS64, %p) = -1 EBADF (%m)\n", info64);
    292 
    293 	/* LOOP_CHANGE_FD */
    294 	ioctl(-1, LOOP_CHANGE_FD, magic);
    295 	printf("ioctl(-1, LOOP_CHANGE_FD, %d) = -1 EBADF (%m)\n",
    296 	       (unsigned int) magic);
    297 
    298 	/* LOOP_SET_CAPACITY */
    299 	ioctl(-1, LOOP_SET_CAPACITY);
    300 	printf("ioctl(-1, LOOP_SET_CAPACITY) = -1 EBADF (%m)\n");
    301 
    302 	/* LOOP_SET_DIRECT_IO */
    303 	ioctl(-1, LOOP_SET_DIRECT_IO, magic);
    304 	printf("ioctl(-1, LOOP_SET_DIRECT_IO, %lu) = -1 EBADF (%m)\n",
    305 	       (unsigned long) magic);
    306 
    307 	/* LOOP_CTL_ADD */
    308 	ioctl(-1, LOOP_CTL_ADD, magic);
    309 	printf("ioctl(-1, LOOP_CTL_ADD, %d) = -1 EBADF (%m)\n",
    310 	       (unsigned int) magic);
    311 
    312 	/* LOOP_CTL_REMOVE */
    313 	ioctl(-1, LOOP_CTL_REMOVE, magic);
    314 	printf("ioctl(-1, LOOP_CTL_REMOVE, %d) = -1 EBADF (%m)\n",
    315 	       (unsigned int) magic);
    316 
    317 	/* LOOP_CTL_GET_FREE */
    318 	ioctl(-1, LOOP_CTL_GET_FREE);
    319 	printf("ioctl(-1, LOOP_CTL_GET_FREE) = -1 EBADF (%m)\n");
    320 
    321 	puts("+++ exited with 0 +++");
    322 	return 0;
    323 }
    324