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