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