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