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 }