(root)/
strace-6.5/
tests-mx32/
ioctl_loop.c
       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   * Copyright (c) 2016-2021 The strace developers.
       7   * All rights reserved.
       8   *
       9   * SPDX-License-Identifier: GPL-2.0-or-later
      10   */
      11  
      12  
      13  #include "tests.h"
      14  #include <stdio.h>
      15  #include <string.h>
      16  #include <inttypes.h>
      17  #include <unistd.h>
      18  #include <sys/ioctl.h>
      19  #include <sys/sysmacros.h>
      20  #include "scno.h"
      21  #include <linux/ioctl.h>
      22  #include <linux/loop.h>
      23  #include "print_fields.h"
      24  
      25  #ifndef ABBREV
      26  # define ABBREV 0
      27  #endif
      28  
      29  static long
      30  sys_ioctl(kernel_long_t fd, kernel_ulong_t cmd, kernel_ulong_t arg)
      31  {
      32  	return syscall(__NR_ioctl, fd, cmd, arg);
      33  }
      34  
      35  static void
      36  print_loop_info(struct loop_info * const info, bool print_encrypt,
      37  		const char *encrypt_type, const char *encrypt_key,
      38  		const char *flags)
      39  {
      40  #if ABBREV
      41  	printf("%p", info);
      42  #else
      43  	printf("{lo_number=%d", info->lo_number);
      44  # if VERBOSE
      45  	printf(", lo_device=makedev(%#x, %#x), lo_inode=%lu, "
      46  	       "lo_rdevice=makedev(%#x, %#x)",
      47  	       major(info->lo_device), minor(info->lo_device),
      48  	       info->lo_inode,
      49  	       major(info->lo_rdevice), minor(info->lo_rdevice));
      50  # endif /* VERBOSE */
      51  
      52  	printf(", lo_offset=%#x", info->lo_offset);
      53  
      54  	if (VERBOSE || print_encrypt) {
      55  		printf(", lo_encrypt_type=");
      56  		if (encrypt_type)
      57  			printf("%s", encrypt_type);
      58  		else
      59  			printf("%#x /* LO_CRYPT_??? */", info->lo_encrypt_type);
      60  
      61  		printf(", lo_encrypt_key_size=%" PRIu32,
      62  		       (uint32_t) info->lo_encrypt_key_size);
      63  	}
      64  
      65  	printf(", lo_flags=");
      66  	if (flags)
      67  		printf("%s", flags);
      68  	else
      69  		printf("%#x /* LO_FLAGS_??? */", info->lo_flags);
      70  
      71  	printf(", ");
      72  	PRINT_FIELD_CSTRING(*info, lo_name);
      73  
      74  	if (VERBOSE || print_encrypt)
      75  		printf(", lo_encrypt_key=\"%.*s\"",
      76  		       encrypt_key ? (int) strlen(encrypt_key) :
      77  		       (int) sizeof(info->lo_encrypt_key),
      78  		       encrypt_key ? encrypt_key :
      79  		       (char *) info->lo_encrypt_key);
      80  
      81  # if VERBOSE
      82  	printf(", lo_init=[%#lx, %#lx]"
      83  	       ", reserved=[%#hhx, %#hhx, %#hhx, %#hhx]}",
      84  	       info->lo_init[0], info->lo_init[1],
      85  	       info->reserved[0], info->reserved[1],
      86  	       info->reserved[2], info->reserved[3]);
      87  # else /* !VERBOSE */
      88  	printf(", ...}");
      89  # endif /* VERBOSE */
      90  #endif /* !ABBREV */
      91  }
      92  
      93  static void
      94  print_loop_info64(struct loop_info64 * const info64, bool print_encrypt,
      95  		  const char *encrypt_type, const char *encrypt_key,
      96  		  const char *flags)
      97  {
      98  #if ABBREV
      99  	printf("%p", info64);
     100  #else
     101  # if VERBOSE
     102  	printf("{lo_device=makedev(%#x, %#x), lo_inode=%" PRIu64
     103  	       ", lo_rdevice=makedev(%#x, %#x), lo_offset=%#" PRIx64
     104  	       ", lo_sizelimit=%" PRIu64 ", lo_number=%" PRIu32,
     105  	       major(info64->lo_device), minor(info64->lo_device),
     106  	       (uint64_t) info64->lo_inode,
     107  	       major(info64->lo_rdevice), minor(info64->lo_rdevice),
     108  	       (uint64_t) info64->lo_offset,
     109  	       (uint64_t) info64->lo_sizelimit,
     110  	       (uint32_t) info64->lo_number);
     111  # else /* !VERBOSE */
     112  	printf("{lo_offset=%#" PRIx64 ", lo_number=%" PRIu32,
     113  	       (uint64_t) info64->lo_offset,
     114  	       (uint32_t) info64->lo_number);
     115  # endif /* VERBOSE */
     116  
     117  	if (VERBOSE || print_encrypt) {
     118  		printf(", lo_encrypt_type=");
     119  		if (encrypt_type)
     120  			printf("%s", encrypt_type);
     121  		else
     122  			printf("%#x /* LO_CRYPT_??? */",
     123  			       info64->lo_encrypt_type);
     124  
     125  		printf(", lo_encrypt_key_size=%" PRIu32,
     126  		       info64->lo_encrypt_key_size);
     127  	}
     128  
     129  	printf(", lo_flags=");
     130  	if (flags)
     131  		printf("%s", flags);
     132  	else
     133  		printf("%#x /* LO_FLAGS_??? */", info64->lo_flags);
     134  	printf(", ");
     135  	PRINT_FIELD_CSTRING(*info64, lo_file_name);
     136  
     137  	if (VERBOSE || print_encrypt) {
     138  		printf(", ");
     139  		PRINT_FIELD_CSTRING(*info64, lo_crypt_name);
     140  		printf(", lo_encrypt_key=\"%.*s\"",
     141  		       encrypt_key ? (int) strlen(encrypt_key) :
     142  		       (int) sizeof(info64->lo_encrypt_key),
     143  		       encrypt_key ? encrypt_key :
     144  		       (char *) info64->lo_encrypt_key);
     145  	}
     146  
     147  # if VERBOSE
     148  	printf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",
     149  	       (uint64_t) info64->lo_init[0],
     150  	       (uint64_t) info64->lo_init[1]);
     151  # else /* !VERBOSE */
     152  	printf(", ...}");
     153  # endif /* VERBOSE */
     154  #endif /* !ABBREV */
     155  }
     156  
     157  static void
     158  print_loop_config(struct loop_config *config, bool print_reserved)
     159  {
     160  #if ABBREV
     161  	printf("%p", config);
     162  #else
     163  	printf("{fd=%d, block_size=%u, info=",
     164  	       (int) config->fd, config->block_size);
     165  	print_loop_info64(&config->info, false, "LO_CRYPT_NONE", NULL,
     166  			  "LO_FLAGS_READ_ONLY");
     167  	if (print_reserved) {
     168  		printf(", __reserved=");
     169  		for (size_t i = 0; i < ARRAY_SIZE(config->__reserved); ++i)
     170  			printf("%s%#llx", (i ? ", " : "["),
     171  			       (unsigned long long) config->__reserved[i]);
     172  		printf("]");
     173  	}
     174  	printf("}");
     175  #endif /* !ABBREV */
     176  }
     177  
     178  int
     179  main(void)
     180  {
     181  	static const kernel_ulong_t unknown_loop_cmd =
     182  		(kernel_ulong_t) 0xbadc0dedfeed4cedULL;
     183  	static const kernel_ulong_t magic =
     184  		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
     185  	static const kernel_ulong_t kernel_mask =
     186  		((kernel_ulong_t) -1) - ((unsigned long) -1L);
     187  
     188  	TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_info, info);
     189  	TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_info64, info64);
     190  	TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_config, config);
     191  
     192  	/* Unknown loop commands */
     193  	sys_ioctl(-1, unknown_loop_cmd, magic);
     194  	printf("ioctl(-1, _IOC(%s_IOC_READ|_IOC_WRITE, 0x4c, %#x, %#x), "
     195  	       "%#lx) = -1 EBADF (%m)\n",
     196  	       _IOC_DIR((unsigned int) unknown_loop_cmd) & _IOC_NONE ?
     197  	       "_IOC_NONE|" : "",
     198  	       _IOC_NR((unsigned int) unknown_loop_cmd),
     199  	       _IOC_SIZE((unsigned int) unknown_loop_cmd),
     200  	       (unsigned long) magic);
     201  
     202  	sys_ioctl(-1, LOOP_CONFIGURE + 1, magic);
     203  	printf("ioctl(-1, _IOC(%s, 0x4c, %#x, %#x), %#lx) = "
     204  	       "-1 EBADF (%m)\n",
     205  	       _IOC_NONE ? "0" : "_IOC_NONE",
     206  	       _IOC_NR(LOOP_CONFIGURE + 1),
     207  	       _IOC_SIZE(LOOP_CONFIGURE + 1),
     208  	       (unsigned long) magic);
     209  
     210  	sys_ioctl(-1, LOOP_CTL_GET_FREE + 1, magic);
     211  	printf("ioctl(-1, _IOC(%s, 0x4c, %#x, %#x), %#lx) = "
     212  	       "-1 EBADF (%m)\n",
     213  	       _IOC_NONE ? "0" : "_IOC_NONE",
     214  	       _IOC_NR(LOOP_CTL_GET_FREE + 1),
     215  	       _IOC_SIZE(LOOP_CTL_GET_FREE + 1),
     216  	       (unsigned long) magic);
     217  
     218  	/* LOOP_SET_FD */
     219  	sys_ioctl(-1, LOOP_SET_FD, magic);
     220  	printf("ioctl(-1, LOOP_SET_FD, %d) = -1 EBADF (%m)\n",
     221  	       (unsigned int) magic);
     222  
     223  	/* LOOP_CLR_FD */
     224  	ioctl(-1, LOOP_CLR_FD);
     225  	printf("ioctl(-1, LOOP_CLR_FD) = -1 EBADF (%m)\n");
     226  
     227  	/* LOOP_SET_STATUS */
     228  	ioctl(-1, LOOP_SET_STATUS, NULL);
     229  	printf("ioctl(-1, LOOP_SET_STATUS, NULL) = -1 EBADF (%m)\n");
     230  
     231  	fill_memory(info, sizeof(*info));
     232  	info->lo_flags = 0xdeface00;
     233  	info->lo_name[0] = '\0';
     234  	info->lo_encrypt_key[0] = '\0';
     235  	info->lo_encrypt_key_size = 1;
     236  
     237  	printf("ioctl(-1, LOOP_SET_STATUS, ");
     238  	print_loop_info(info, true, NULL, "\\0", NULL);
     239  	ioctl(-1, LOOP_SET_STATUS, info);
     240  	printf(") = -1 EBADF (%m)\n");
     241  
     242  	fill_memory(info, sizeof(*info));
     243  	info->lo_encrypt_type = LO_CRYPT_NONE;
     244  	info->lo_flags = LO_FLAGS_READ_ONLY;
     245  	memset(info->lo_name, 'A', sizeof(info->lo_name));
     246  	memset(info->lo_encrypt_key, 'B', sizeof(info->lo_encrypt_key));
     247  
     248  	ioctl(-1, LOOP_SET_STATUS, (void *) info + ALIGNOF(info));
     249  	printf("ioctl(-1, LOOP_SET_STATUS, %p) = -1 EBADF (%m)\n",
     250  	       (void *) info + ALIGNOF(info));
     251  
     252  	printf("ioctl(-1, LOOP_SET_STATUS, ");
     253  	print_loop_info(info, false, "LO_CRYPT_NONE", NULL,
     254  			"LO_FLAGS_READ_ONLY");
     255  	ioctl(-1, LOOP_SET_STATUS, info);
     256  	printf(") = -1 EBADF (%m)\n");
     257  
     258  	/* LOOP_GET_STATUS */
     259  	ioctl(-1, LOOP_GET_STATUS, NULL);
     260  	printf("ioctl(-1, LOOP_GET_STATUS, NULL) = -1 EBADF (%m)\n");
     261  
     262  	ioctl(-1, LOOP_GET_STATUS, (unsigned long) info | kernel_mask);
     263  	printf("ioctl(-1, LOOP_GET_STATUS, %p) = -1 EBADF (%m)\n", info);
     264  
     265  	/* LOOP_SET_STATUS64 */
     266  	ioctl(-1, LOOP_SET_STATUS64, NULL);
     267  	printf("ioctl(-1, LOOP_SET_STATUS64, NULL) = -1 EBADF (%m)\n");
     268  
     269  	fill_memory(info64, sizeof(*info64));
     270  	info64->lo_flags = 0xdec0de00;
     271  	info64->lo_file_name[0] = '\0';
     272  	info64->lo_crypt_name[0] = '\0';
     273  	info64->lo_encrypt_key[0] = '\0';
     274  	info64->lo_encrypt_key_size = 1;
     275  
     276  	printf("ioctl(-1, LOOP_SET_STATUS64, ");
     277  	print_loop_info64(info64, true, NULL, "\\0", NULL);
     278  	ioctl(-1, LOOP_SET_STATUS64, info64);
     279  	printf(") = -1 EBADF (%m)\n");
     280  
     281  	fill_memory(info64, sizeof(*info64));
     282  	info64->lo_flags = LO_FLAGS_READ_ONLY;
     283  	info64->lo_encrypt_type = LO_CRYPT_NONE;
     284  	memset(info64->lo_file_name, 'C', sizeof(info64->lo_file_name));
     285  	memset(info64->lo_crypt_name, 'D', sizeof(info64->lo_crypt_name));
     286  	memset(info64->lo_encrypt_key, 'E', sizeof(info64->lo_encrypt_key));
     287  
     288  	ioctl(-1, LOOP_SET_STATUS64, (void *) info64 + ALIGNOF(info64));
     289  	printf("ioctl(-1, LOOP_SET_STATUS64, %p) = -1 EBADF (%m)\n",
     290  	       (void *) info64 + ALIGNOF(info64));
     291  
     292  	printf("ioctl(-1, LOOP_SET_STATUS64, ");
     293  	print_loop_info64(info64, false, "LO_CRYPT_NONE", NULL,
     294  			  "LO_FLAGS_READ_ONLY");
     295  	ioctl(-1, LOOP_SET_STATUS64, info64);
     296  	printf(") = -1 EBADF (%m)\n");
     297  
     298  	/* LOOP_GET_STATUS64 */
     299  	ioctl(-1, LOOP_GET_STATUS64, NULL);
     300  	printf("ioctl(-1, LOOP_GET_STATUS64, NULL) = -1 EBADF (%m)\n");
     301  
     302  	ioctl(-1, LOOP_GET_STATUS64, (unsigned long) info64 | kernel_mask);
     303  	printf("ioctl(-1, LOOP_GET_STATUS64, %p) = -1 EBADF (%m)\n", info64);
     304  
     305  	/* LOOP_CONFIGURE */
     306  	ioctl(-1, LOOP_CONFIGURE, NULL);
     307  	printf("ioctl(-1, LOOP_CONFIGURE, NULL) = -1 EBADF (%m)\n");
     308  
     309  	fill_memory(config, sizeof(*config));
     310  	config->info.lo_flags = LO_FLAGS_READ_ONLY;
     311  	config->info.lo_encrypt_type = LO_CRYPT_NONE;
     312  	memset(config->info.lo_file_name, 'C', sizeof(config->info.lo_file_name));
     313  	memset(config->info.lo_crypt_name, 'D', sizeof(config->info.lo_crypt_name));
     314  	memset(config->info.lo_encrypt_key, 'E', sizeof(config->info.lo_encrypt_key));
     315  
     316  	ioctl(-1, LOOP_CONFIGURE, (void *) config + ALIGNOF(config));
     317  	printf("ioctl(-1, LOOP_CONFIGURE, %p) = -1 EBADF (%m)\n",
     318  	       (void *) config + ALIGNOF(config));
     319  
     320  	printf("ioctl(-1, LOOP_CONFIGURE, ");
     321  	print_loop_config(config, true);
     322  	ioctl(-1, LOOP_CONFIGURE, config);
     323  	printf(") = -1 EBADF (%m)\n");
     324  
     325  	memset(config->__reserved, 0, sizeof(config->__reserved));
     326  	printf("ioctl(-1, LOOP_CONFIGURE, ");
     327  	print_loop_config(config, false);
     328  	ioctl(-1, LOOP_CONFIGURE, config);
     329  	printf(") = -1 EBADF (%m)\n");
     330  
     331  	/* LOOP_CHANGE_FD */
     332  	sys_ioctl(-1, LOOP_CHANGE_FD, magic);
     333  	printf("ioctl(-1, LOOP_CHANGE_FD, %d) = -1 EBADF (%m)\n",
     334  	       (unsigned int) magic);
     335  
     336  	/* LOOP_SET_CAPACITY */
     337  	ioctl(-1, LOOP_SET_CAPACITY);
     338  	printf("ioctl(-1, LOOP_SET_CAPACITY) = -1 EBADF (%m)\n");
     339  
     340  	/* LOOP_SET_DIRECT_IO */
     341  	sys_ioctl(-1, LOOP_SET_DIRECT_IO, magic);
     342  	printf("ioctl(-1, LOOP_SET_DIRECT_IO, %lu) = -1 EBADF (%m)\n",
     343  	       (unsigned long) magic);
     344  
     345  	/* LOOP_SET_BLOCK_SIZE */
     346  	sys_ioctl(-1, LOOP_SET_BLOCK_SIZE, magic);
     347  	printf("ioctl(-1, LOOP_SET_BLOCK_SIZE, %lu) = -1 EBADF (%m)\n",
     348  	       (unsigned long) magic);
     349  
     350  	/* LOOP_CTL_ADD */
     351  	sys_ioctl(-1, LOOP_CTL_ADD, magic);
     352  	printf("ioctl(-1, LOOP_CTL_ADD, %d) = -1 EBADF (%m)\n",
     353  	       (unsigned int) magic);
     354  
     355  	/* LOOP_CTL_REMOVE */
     356  	sys_ioctl(-1, LOOP_CTL_REMOVE, magic);
     357  	printf("ioctl(-1, LOOP_CTL_REMOVE, %d) = -1 EBADF (%m)\n",
     358  	       (unsigned int) magic);
     359  
     360  	/* LOOP_CTL_GET_FREE */
     361  	ioctl(-1, LOOP_CTL_GET_FREE);
     362  	printf("ioctl(-1, LOOP_CTL_GET_FREE) = -1 EBADF (%m)\n");
     363  
     364  	puts("+++ exited with 0 +++");
     365  	return 0;
     366  }