1/* 2 * This file is part of ioctl_loop strace test. 3 * 4 * Copyright (c) 2016 JingPiao Chen <chenjingpiao@gmail.com> 5 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 32#include "tests.h" 33#include <stdio.h> 34#include <stdbool.h> 35#include <string.h> 36#include <inttypes.h> 37#include <sys/ioctl.h> 38#include <sys/sysmacros.h> 39#include <linux/ioctl.h> 40#include <linux/loop.h> 41#include "xlat/loop_cmds.h" 42 43#ifndef ABBREV 44# define ABBREV 0 45#endif 46 47static void 48print_loop_info(struct loop_info * const info, bool print_encrypt, 49 const char *encrypt_type, const char *encrypt_key, 50 const char *flags) 51{ 52#if ABBREV 53 printf("%p", info); 54#else 55 printf("{lo_number=%d", info->lo_number); 56# if VERBOSE 57 printf(", lo_device=makedev(%u, %u), lo_inode=%lu, " 58 "lo_rdevice=makedev(%u, %u)", 59 major(info->lo_device), minor(info->lo_device), 60 info->lo_inode, 61 major(info->lo_rdevice), minor(info->lo_rdevice)); 62# endif /* VERBOSE */ 63 64 printf(", lo_offset=%#x", info->lo_offset); 65 66 if (VERBOSE || print_encrypt) { 67 printf(", lo_encrypt_type="); 68 if (encrypt_type) 69 printf("%s", encrypt_type); 70 else 71 printf("%#x /* LO_CRYPT_??? */", info->lo_encrypt_type); 72 73 printf(", lo_encrypt_key_size=%" PRIu32, 74 (uint32_t) info->lo_encrypt_key_size); 75 } 76 77 printf(", lo_flags="); 78 if (flags) 79 printf("%s", flags); 80 else 81 printf("%#x /* LO_FLAGS_??? */", info->lo_flags); 82 83 printf(", lo_name=\"%.*s\"", 84 (int) sizeof(info->lo_name) - 1, info->lo_name); 85 86 if (VERBOSE || print_encrypt) 87 printf(", lo_encrypt_key=\"%.*s\"", 88 encrypt_key ? (int) strlen(encrypt_key) : 89 (int) sizeof(info->lo_encrypt_key), 90 encrypt_key ? encrypt_key : 91 (char *) info->lo_encrypt_key); 92 93# if VERBOSE 94 printf(", lo_init=[%#lx, %#lx]" 95 ", reserved=[%#hhx, %#hhx, %#hhx, %#hhx]}", 96 info->lo_init[0], info->lo_init[1], 97 info->reserved[0], info->reserved[1], 98 info->reserved[2], info->reserved[3]); 99# else /* !VERBOSE */ 100 printf(", ...}"); 101# endif /* VERBOSE */ 102#endif /* !ABBREV */ 103} 104 105static void 106print_loop_info64(struct loop_info64 * const info64, bool print_encrypt, 107 const char *encrypt_type, const char *encrypt_key, 108 const char *flags) 109{ 110#if ABBREV 111 printf("%p", info64); 112#else 113# if VERBOSE 114 printf("{lo_device=makedev(%u, %u), lo_inode=%" PRIu64 115 ", lo_rdevice=makedev(%u, %u), lo_offset=%#" PRIx64 116 ", lo_sizelimit=%" PRIu64 ", lo_number=%" PRIu32, 117 major(info64->lo_device), minor(info64->lo_device), 118 (uint64_t) info64->lo_inode, 119 major(info64->lo_rdevice), minor(info64->lo_rdevice), 120 (uint64_t) info64->lo_offset, 121 (uint64_t) info64->lo_sizelimit, 122 (uint32_t) info64->lo_number); 123# else /* !VERBOSE */ 124 printf("{lo_offset=%#" PRIx64 ", lo_number=%" PRIu32, 125 (uint64_t) info64->lo_offset, 126 (uint32_t) info64->lo_number); 127# endif /* VERBOSE */ 128 129 if (VERBOSE || print_encrypt) { 130 printf(", lo_encrypt_type="); 131 if (encrypt_type) 132 printf("%s", encrypt_type); 133 else 134 printf("%#x /* LO_CRYPT_??? */", 135 info64->lo_encrypt_type); 136 137 printf(", lo_encrypt_key_size=%" PRIu32, 138 info64->lo_encrypt_key_size); 139 } 140 141 printf(", lo_flags="); 142 if (flags) 143 printf("%s", flags); 144 else 145 printf("%#x /* LO_FLAGS_??? */", info64->lo_flags); 146 printf(", lo_file_name=\"%.*s\"", 147 (int) sizeof(info64->lo_file_name) - 1, info64->lo_file_name); 148 149 if (VERBOSE || print_encrypt) 150 printf(", lo_crypt_name=\"%.*s\", lo_encrypt_key=\"%.*s\"", 151 (int) sizeof(info64->lo_crypt_name) - 1, 152 info64->lo_crypt_name, 153 encrypt_key ? (int) strlen(encrypt_key) : 154 (int) sizeof(info64->lo_encrypt_key), 155 encrypt_key ? encrypt_key : 156 (char *) info64->lo_encrypt_key); 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 168int 169main(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 struct loop_info * const info = tail_alloc(sizeof(*info)); 179 struct loop_info64 * const info64 = tail_alloc(sizeof(*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_DIRECT_IO + 1, magic); 192 printf("ioctl(-1, _IOC(0, 0x4c, %#x, %#x), %#lx) = " 193 "-1 EBADF (%m)\n", 194 _IOC_NR(LOOP_SET_DIRECT_IO + 1), 195 _IOC_SIZE(LOOP_SET_DIRECT_IO + 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_CTL_ADD */ 307 ioctl(-1, LOOP_CTL_ADD, magic); 308 printf("ioctl(-1, LOOP_CTL_ADD, %d) = -1 EBADF (%m)\n", 309 (unsigned int) magic); 310 311 /* LOOP_CTL_REMOVE */ 312 ioctl(-1, LOOP_CTL_REMOVE, magic); 313 printf("ioctl(-1, LOOP_CTL_REMOVE, %d) = -1 EBADF (%m)\n", 314 (unsigned int) magic); 315 316 /* LOOP_CTL_GET_FREE */ 317 ioctl(-1, LOOP_CTL_GET_FREE); 318 printf("ioctl(-1, LOOP_CTL_GET_FREE) = -1 EBADF (%m)\n"); 319 320 puts("+++ exited with 0 +++"); 321 return 0; 322} 323