• 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-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