• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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