]> granicus.if.org Git - strace/blob - tests/ioctl_loop.c
Update copyright headers
[strace] / tests / 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-2018 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 <asm/unistd.h>
21 #include <linux/ioctl.h>
22 #include <linux/loop.h>
23 #include "print_fields.h"
24 #include "xlat/loop_cmds.h"
25
26 #ifndef ABBREV
27 # define ABBREV 0
28 #endif
29
30 static long
31 sys_ioctl(kernel_long_t fd, kernel_ulong_t cmd, kernel_ulong_t arg)
32 {
33         return syscall(__NR_ioctl, fd, cmd, arg);
34 }
35
36 static void
37 print_loop_info(struct loop_info * const info, bool print_encrypt,
38                 const char *encrypt_type, const char *encrypt_key,
39                 const char *flags)
40 {
41 #if ABBREV
42         printf("%p", info);
43 #else
44         printf("{lo_number=%d", info->lo_number);
45 # if VERBOSE
46         printf(", lo_device=makedev(%#x, %#x), lo_inode=%lu, "
47                "lo_rdevice=makedev(%#x, %#x)",
48                major(info->lo_device), minor(info->lo_device),
49                info->lo_inode,
50                major(info->lo_rdevice), minor(info->lo_rdevice));
51 # endif /* VERBOSE */
52
53         printf(", lo_offset=%#x", info->lo_offset);
54
55         if (VERBOSE || print_encrypt) {
56                 printf(", lo_encrypt_type=");
57                 if (encrypt_type)
58                         printf("%s", encrypt_type);
59                 else
60                         printf("%#x /* LO_CRYPT_??? */", info->lo_encrypt_type);
61
62                 printf(", lo_encrypt_key_size=%" PRIu32,
63                        (uint32_t) info->lo_encrypt_key_size);
64         }
65
66         printf(", lo_flags=");
67         if (flags)
68                 printf("%s", flags);
69         else
70                 printf("%#x /* LO_FLAGS_??? */", info->lo_flags);
71
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         PRINT_FIELD_CSTRING(", ", *info64, lo_file_name);
135
136         if (VERBOSE || print_encrypt) {
137                 PRINT_FIELD_CSTRING(", ", *info64, lo_crypt_name);
138                 printf(", lo_encrypt_key=\"%.*s\"",
139                        encrypt_key ? (int) strlen(encrypt_key) :
140                        (int) sizeof(info64->lo_encrypt_key),
141                        encrypt_key ? encrypt_key :
142                        (char *) info64->lo_encrypt_key);
143         }
144
145 # if VERBOSE
146         printf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",
147                (uint64_t) info64->lo_init[0],
148                (uint64_t) info64->lo_init[1]);
149 # else /* !VERBOSE */
150         printf(", ...}");
151 # endif /* VERBOSE */
152 #endif /* !ABBREV */
153 }
154
155 int
156 main(void)
157 {
158         static const kernel_ulong_t unknown_loop_cmd =
159                 (kernel_ulong_t) 0xbadc0dedfeed4cedULL;
160         static const kernel_ulong_t magic =
161                 (kernel_ulong_t) 0xdeadbeefbadc0dedULL;
162         static const kernel_ulong_t kernel_mask =
163                 ((kernel_ulong_t) -1) - ((unsigned long) -1L);
164
165         TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_info, info);
166         TAIL_ALLOC_OBJECT_CONST_PTR(struct loop_info64, info64);
167
168         /* Unknown loop commands */
169         sys_ioctl(-1, unknown_loop_cmd, magic);
170         printf("ioctl(-1, _IOC(%s_IOC_READ|_IOC_WRITE, 0x4c, %#x, %#x), "
171                "%#lx) = -1 EBADF (%m)\n",
172                _IOC_DIR((unsigned int) unknown_loop_cmd) & _IOC_NONE ?
173                "_IOC_NONE|" : "",
174                _IOC_NR((unsigned int) unknown_loop_cmd),
175                _IOC_SIZE((unsigned int) unknown_loop_cmd),
176                (unsigned long) magic);
177
178         sys_ioctl(-1, LOOP_SET_BLOCK_SIZE + 1, magic);
179         printf("ioctl(-1, _IOC(%s, 0x4c, %#x, %#x), %#lx) = "
180                "-1 EBADF (%m)\n",
181                _IOC_NONE ? "0" : "_IOC_NONE",
182                _IOC_NR(LOOP_SET_BLOCK_SIZE + 1),
183                _IOC_SIZE(LOOP_SET_BLOCK_SIZE + 1),
184                (unsigned long) magic);
185
186         sys_ioctl(-1, LOOP_CTL_GET_FREE + 1, magic);
187         printf("ioctl(-1, _IOC(%s, 0x4c, %#x, %#x), %#lx) = "
188                "-1 EBADF (%m)\n",
189                _IOC_NONE ? "0" : "_IOC_NONE",
190                _IOC_NR(LOOP_CTL_GET_FREE + 1),
191                _IOC_SIZE(LOOP_CTL_GET_FREE + 1),
192                (unsigned long) magic);
193
194         /* LOOP_SET_FD */
195         sys_ioctl(-1, LOOP_SET_FD, magic);
196         printf("ioctl(-1, LOOP_SET_FD, %d) = -1 EBADF (%m)\n",
197                (unsigned int) magic);
198
199         /* LOOP_CLR_FD */
200         ioctl(-1, LOOP_CLR_FD);
201         printf("ioctl(-1, LOOP_CLR_FD) = -1 EBADF (%m)\n");
202
203         /* LOOP_SET_STATUS */
204         ioctl(-1, LOOP_SET_STATUS, NULL);
205         printf("ioctl(-1, LOOP_SET_STATUS, NULL) = -1 EBADF (%m)\n");
206
207         fill_memory(info, sizeof(*info));
208         info->lo_flags = 0xdeface00;
209         info->lo_name[0] = '\0';
210         info->lo_encrypt_key[0] = '\0';
211         info->lo_encrypt_key_size = 1;
212
213         printf("ioctl(-1, LOOP_SET_STATUS, ");
214         print_loop_info(info, true, NULL, "\\0", NULL);
215         ioctl(-1, LOOP_SET_STATUS, info);
216         printf(") = -1 EBADF (%m)\n");
217
218         fill_memory(info, sizeof(*info));
219         info->lo_encrypt_type = LO_CRYPT_NONE;
220         info->lo_flags = LO_FLAGS_READ_ONLY;
221         memset(info->lo_name, 'A', sizeof(info->lo_name));
222         memset(info->lo_encrypt_key, 'B', sizeof(info->lo_encrypt_key));
223
224         ioctl(-1, LOOP_SET_STATUS, (void *) info + ALIGNOF(info));
225         printf("ioctl(-1, LOOP_SET_STATUS, %p) = -1 EBADF (%m)\n",
226                (void *) info + ALIGNOF(info));
227
228         printf("ioctl(-1, LOOP_SET_STATUS, ");
229         print_loop_info(info, false, "LO_CRYPT_NONE", NULL,
230                         "LO_FLAGS_READ_ONLY");
231         ioctl(-1, LOOP_SET_STATUS, info);
232         printf(") = -1 EBADF (%m)\n");
233
234         /* LOOP_GET_STATUS */
235         ioctl(-1, LOOP_GET_STATUS, NULL);
236         printf("ioctl(-1, LOOP_GET_STATUS, NULL) = -1 EBADF (%m)\n");
237
238         ioctl(-1, LOOP_GET_STATUS, (unsigned long) info | kernel_mask);
239         printf("ioctl(-1, LOOP_GET_STATUS, %p) = -1 EBADF (%m)\n", info);
240
241         /* LOOP_SET_STATUS64 */
242         ioctl(-1, LOOP_SET_STATUS64, NULL);
243         printf("ioctl(-1, LOOP_SET_STATUS64, NULL) = -1 EBADF (%m)\n");
244
245         fill_memory(info64, sizeof(*info64));
246         info64->lo_flags = 0xdec0de00;
247         info64->lo_file_name[0] = '\0';
248         info64->lo_crypt_name[0] = '\0';
249         info64->lo_encrypt_key[0] = '\0';
250         info64->lo_encrypt_key_size = 1;
251
252         printf("ioctl(-1, LOOP_SET_STATUS64, ");
253         print_loop_info64(info64, true, NULL, "\\0", NULL);
254         ioctl(-1, LOOP_SET_STATUS64, info64);
255         printf(") = -1 EBADF (%m)\n");
256
257         fill_memory(info64, sizeof(*info64));
258         info64->lo_flags = LO_FLAGS_READ_ONLY;
259         info64->lo_encrypt_type = LO_CRYPT_NONE;
260         memset(info64->lo_file_name, 'C', sizeof(info64->lo_file_name));
261         memset(info64->lo_crypt_name, 'D', sizeof(info64->lo_crypt_name));
262         memset(info64->lo_encrypt_key, 'E', sizeof(info64->lo_encrypt_key));
263
264         ioctl(-1, LOOP_SET_STATUS64, (void *) info64 + ALIGNOF(info64));
265         printf("ioctl(-1, LOOP_SET_STATUS64, %p) = -1 EBADF (%m)\n",
266                (void *) info64 + ALIGNOF(info64));
267
268         printf("ioctl(-1, LOOP_SET_STATUS64, ");
269         print_loop_info64(info64, false, "LO_CRYPT_NONE", NULL,
270                           "LO_FLAGS_READ_ONLY");
271         ioctl(-1, LOOP_SET_STATUS64, info64);
272         printf(") = -1 EBADF (%m)\n");
273
274         /* LOOP_GET_STATUS64 */
275         ioctl(-1, LOOP_GET_STATUS64, NULL);
276         printf("ioctl(-1, LOOP_GET_STATUS64, NULL) = -1 EBADF (%m)\n");
277
278         ioctl(-1, LOOP_GET_STATUS64, (unsigned long) info64 | kernel_mask);
279         printf("ioctl(-1, LOOP_GET_STATUS64, %p) = -1 EBADF (%m)\n", info64);
280
281         /* LOOP_CHANGE_FD */
282         sys_ioctl(-1, LOOP_CHANGE_FD, magic);
283         printf("ioctl(-1, LOOP_CHANGE_FD, %d) = -1 EBADF (%m)\n",
284                (unsigned int) magic);
285
286         /* LOOP_SET_CAPACITY */
287         ioctl(-1, LOOP_SET_CAPACITY);
288         printf("ioctl(-1, LOOP_SET_CAPACITY) = -1 EBADF (%m)\n");
289
290         /* LOOP_SET_DIRECT_IO */
291         sys_ioctl(-1, LOOP_SET_DIRECT_IO, magic);
292         printf("ioctl(-1, LOOP_SET_DIRECT_IO, %lu) = -1 EBADF (%m)\n",
293                (unsigned long) magic);
294
295         /* LOOP_SET_BLOCK_SIZE */
296         sys_ioctl(-1, LOOP_SET_BLOCK_SIZE, magic);
297         printf("ioctl(-1, LOOP_SET_BLOCK_SIZE, %lu) = -1 EBADF (%m)\n",
298                (unsigned long) magic);
299
300         /* LOOP_CTL_ADD */
301         sys_ioctl(-1, LOOP_CTL_ADD, magic);
302         printf("ioctl(-1, LOOP_CTL_ADD, %d) = -1 EBADF (%m)\n",
303                (unsigned int) magic);
304
305         /* LOOP_CTL_REMOVE */
306         sys_ioctl(-1, LOOP_CTL_REMOVE, magic);
307         printf("ioctl(-1, LOOP_CTL_REMOVE, %d) = -1 EBADF (%m)\n",
308                (unsigned int) magic);
309
310         /* LOOP_CTL_GET_FREE */
311         ioctl(-1, LOOP_CTL_GET_FREE);
312         printf("ioctl(-1, LOOP_CTL_GET_FREE) = -1 EBADF (%m)\n");
313
314         puts("+++ exited with 0 +++");
315         return 0;
316 }