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