2 * Check decoding of DM_* commands of ioctl syscall.
4 * Copyright (c) 2016 Mikulas Patocka <mpatocka@redhat.com>
5 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
6 * Copyright (c) 2016-2017 The strace developers.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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.
34 #ifdef HAVE_LINUX_DM_IOCTL_H
37 # include <inttypes.h>
42 # include <sys/ioctl.h>
43 # include <linux/ioctl.h>
44 # include <linux/dm-ioctl.h>
50 # define STR32 "AbCdEfGhIjKlMnOpQrStUvWxYz012345"
52 # define ALIGNED_SIZE(s_, t_) \
53 (((s_) + (ALIGNOF(t_) - 1UL)) & ~(ALIGNOF(t_) - 1UL))
54 # define ALIGNED_OFFSET(t_, m_) \
55 ALIGNED_SIZE(offsetof(t_, m_), t_)
57 static const char str129[] = STR32 STR32 STR32 STR32 "6";
59 static const __u64 dts_sector_base = (__u64) 0xdeadca75facef157ULL;
60 static const __u64 dts_sector_step = (__u64) 0x100000001ULL;
61 static const __u64 dts_length_base = (__u64) 0xbadc0dedda7a1057ULL;
62 static const __u64 dts_length_step = (__u64) 0x700000007ULL;
63 static const __s32 dts_status_base = (__s32) 3141592653U;
64 static const __s32 dts_status_step = 0x1234;
66 static const size_t min_sizeof_dm_ioctl =
67 offsetof(struct dm_ioctl, data);
73 struct dm_target_spec target_spec;
74 char target_params[256];
77 struct dm_target_msg target_msg;
78 char target_string[256];
84 struct dm_table_open_test {
86 struct dm_target_spec target0;
88 struct dm_target_spec target1;
90 struct dm_target_spec target2;
92 struct dm_target_spec target3;
94 struct dm_target_spec target4;
96 struct dm_target_spec target5;
98 struct dm_target_spec target6;
100 struct dm_target_spec target7;
102 struct dm_target_spec target8;
104 struct dm_target_spec target9;
108 struct dm_target_msg_test {
110 struct dm_target_msg msg;
122 init_s(struct dm_ioctl *s, size_t size, size_t offs)
125 s->version[0] = DM_VERSION_MAJOR;
129 s->data_start = offs;
131 strcpy(s->name, "nnn");
132 strcpy(s->uuid, "uuu");
136 init_dm_target_spec(struct dm_target_spec *ptr, uint32_t id)
138 ptr->sector_start = dts_sector_base + dts_sector_step * id;
139 ptr->length = dts_length_base + dts_length_step * id;
140 ptr->status = dts_status_base + dts_status_step * id;
142 strncpy(ptr->target_type, str129 +
143 id % (sizeof(str129) - sizeof(ptr->target_type)),
144 id % (sizeof(ptr->target_type) + 1));
145 if (id % (sizeof(ptr->target_type) + 1) < sizeof(ptr->target_type))
146 ptr->target_type[id % (sizeof(ptr->target_type) + 1)] = '\0';
151 print_dm_target_spec(struct dm_target_spec *ptr, uint32_t id)
153 printf("{sector_start=%" PRI__u64 ", length=%" PRI__u64 ", "
154 "target_type=\"%.*s\", string=",
155 dts_sector_base + dts_sector_step * id,
156 dts_length_base + dts_length_step * id,
157 (int) (id % (sizeof(ptr->target_type) + 1)),
158 str129 + id % (sizeof(str129) - sizeof(ptr->target_type)));
160 # endif /* VERBOSE */
165 static kernel_ulong_t dummy_dm_ioctl1 =
166 _IOC(_IOC_READ, DM_IOCTL, 0, 0x1fff);
167 static kernel_ulong_t dummy_dm_ioctl2 =
168 _IOC(_IOC_READ|_IOC_WRITE, DM_IOCTL, 0xed, 0);
169 static kernel_ulong_t dummy_dm_arg =
170 (kernel_ulong_t) 0xbadc0dedda7a1057ULL;
171 /* We can't check these properly for now */
172 static struct args dummy_check_cmds_nodev[] = {
173 { ARG_STR(DM_REMOVE_ALL), false },
174 { ARG_STR(DM_LIST_DEVICES), true },
175 { ARG_STR(DM_LIST_VERSIONS), true },
177 static struct args dummy_check_cmds[] = {
178 { ARG_STR(DM_DEV_CREATE), false },
179 { ARG_STR(DM_DEV_REMOVE), false, true },
180 { ARG_STR(DM_DEV_STATUS), false },
181 { ARG_STR(DM_DEV_WAIT), true, true },
182 { ARG_STR(DM_TABLE_CLEAR), false },
183 { ARG_STR(DM_TABLE_DEPS), true },
184 { ARG_STR(DM_TABLE_STATUS), true },
187 struct dm_ioctl *unaligned_dm_arg =
188 tail_alloc(offsetof(struct dm_ioctl, data));
189 struct dm_ioctl *dm_arg =
190 tail_alloc(ALIGNED_OFFSET(struct dm_ioctl, data));
191 struct dm_table_open_test *dm_arg_open1 =
192 tail_alloc(ALIGNED_OFFSET(struct dm_table_open_test, target1));
193 struct dm_table_open_test *dm_arg_open2 =
194 tail_alloc(ALIGNED_OFFSET(struct dm_table_open_test, param1));
195 struct dm_table_open_test *dm_arg_open3 =
196 tail_alloc(ALIGNED_OFFSET(struct dm_table_open_test, target9));
197 struct dm_target_msg_test *dm_arg_msg =
198 tail_alloc(sizeof(*dm_arg_msg));
205 /* Incorrect operation */
206 ioctl(-1, _IOW(DM_IOCTL, 0xde, int), dm_arg);
207 printf("ioctl(-1, _IOC(_IOC_WRITE, %#x, 0xde, %#zx), %p) = "
209 DM_IOCTL, sizeof(int), dm_arg);
211 ioctl(-1, dummy_dm_ioctl1, 0);
212 printf("ioctl(-1, _IOC(_IOC_READ, %#x, 0, %#x), 0) = -1 EBADF (%m)\n",
213 DM_IOCTL, (unsigned int) _IOC_SIZE(dummy_dm_ioctl1));
215 ioctl(-1, dummy_dm_ioctl2, dummy_dm_arg);
216 printf("ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, %#x, %#x, 0), %#lx) = "
218 DM_IOCTL, (unsigned int) _IOC_NR(dummy_dm_ioctl2),
219 (unsigned long) dummy_dm_arg);
223 /* Incorrect pointer */
224 ioctl(-1, DM_VERSION, dm_arg + 1);
225 printf("ioctl(-1, DM_VERSION, %p) = -1 EBADF (%m)\n", dm_arg + 1);
227 /* Incorrect data_size */
228 init_s(dm_arg, 0, 0);
229 ioctl(-1, DM_VERSION, &s);
230 printf("ioctl(-1, DM_VERSION, %p) = -1 EBADF (%m)\n", &s);
232 /* Incorrect version */
233 init_s(dm_arg, min_sizeof_dm_ioctl, 0);
234 dm_arg->version[0] = 0xbadc0ded;
235 dm_arg->version[1] = 0xbadc0dee;
236 dm_arg->version[2] = 0xbadc0def;
237 ioctl(-1, DM_VERSION, dm_arg);
238 printf("ioctl(-1, DM_VERSION, {version=%u.%u.%u"
239 " /* unsupported device mapper ABI version */}) = "
240 "-1 EBADF (%m)\n", 0xbadc0ded, 0xbadc0dee, 0xbadc0def);
242 /* Incorrect data_size */
243 init_s(dm_arg, 14, 64);
244 ioctl(-1, DM_VERSION, dm_arg);
245 printf("ioctl(-1, DM_VERSION, {version=4.1.2, data_size=14"
246 " /* data_size too small */}) = -1 EBADF (%m)\n");
248 /* Unterminated name/uuid */
249 init_s(dm_arg, min_sizeof_dm_ioctl, 0);
250 strncpy(dm_arg->name, str129, sizeof(dm_arg->name));
251 strncpy(dm_arg->uuid, str129, sizeof(dm_arg->uuid));
252 ioctl(-1, DM_VERSION, dm_arg);
253 printf("ioctl(-1, DM_VERSION, {version=4.1.2, data_size=%zu, "
254 "dev=makedev(18, 52), name=\"%.127s\", uuid=\"%.128s\", "
255 "flags=0}) = -1 EBADF (%m)\n",
256 min_sizeof_dm_ioctl, str129, str129);
259 init_s(dm_arg, min_sizeof_dm_ioctl, 0);
260 ioctl(-1, DM_VERSION, dm_arg);
261 printf("ioctl(-1, DM_VERSION, "
262 "{version=4.1.2, data_size=%zu, "
263 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = "
264 "-1 EBADF (%m)\n", min_sizeof_dm_ioctl);
266 /* Zero dev, name, uuid */
267 init_s(dm_arg, min_sizeof_dm_ioctl, 0);
268 dm_arg->data_size = 0xfacefeed;
270 dm_arg->name[0] = '\0';
271 dm_arg->uuid[0] = '\0';
272 ioctl(-1, DM_VERSION, dm_arg);
273 printf("ioctl(-1, DM_VERSION, "
274 "{version=4.1.2, data_size=%u, flags=0}) = "
275 "-1 EBADF (%m)\n", 0xfacefeed);
278 init_s(dm_arg, min_sizeof_dm_ioctl, 0);
279 dm_arg->flags = 0xffffffff;
280 ioctl(-1, DM_VERSION, dm_arg);
281 printf("ioctl(-1, DM_VERSION, "
282 "{version=4.1.2, data_size=%zu, "
283 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags="
284 "DM_READONLY_FLAG|DM_SUSPEND_FLAG|DM_EXISTS_FLAG|"
285 "DM_PERSISTENT_DEV_FLAG|DM_STATUS_TABLE_FLAG|"
286 "DM_ACTIVE_PRESENT_FLAG|DM_INACTIVE_PRESENT_FLAG|"
287 "DM_BUFFER_FULL_FLAG|DM_SKIP_BDGET_FLAG|DM_SKIP_LOCKFS_FLAG|"
288 "DM_NOFLUSH_FLAG|DM_QUERY_INACTIVE_TABLE_FLAG|"
289 "DM_UEVENT_GENERATED_FLAG|DM_UUID_FLAG|DM_SECURE_DATA_FLAG|"
290 "DM_DATA_OUT_FLAG|DM_DEFERRED_REMOVE|DM_INTERNAL_SUSPEND_FLAG|"
291 "0xfff80080}) = -1 EBADF (%m)\n",
292 min_sizeof_dm_ioctl);
295 init_s(&s.ioc, sizeof(s.ioc), 0);
296 ioctl(-1, DM_VERSION, &s);
297 printf("ioctl(-1, DM_VERSION, "
298 "{version=4.1.2, data_size=%zu, "
299 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = "
300 "-1 EBADF (%m)\n", sizeof(s.ioc));
304 /* DM_LIST_DEVICES */
305 /* DM_LIST_VERSIONS */
306 for (i = 0; i < ARRAY_SIZE(dummy_check_cmds_nodev); i++) {
307 init_s(dm_arg, min_sizeof_dm_ioctl, 0);
308 ioctl(-1, dummy_check_cmds_nodev[i].arg, dm_arg);
309 printf("ioctl(-1, %s, {version=4.1.2, data_size=%zu%s, "
310 "flags=0}) = -1 EBADF (%m)\n",
311 dummy_check_cmds_nodev[i].str,
313 dummy_check_cmds_nodev[i].has_params ?
314 ", data_start=0" : "");
324 /* DM_TABLE_STATUS */
325 for (i = 0; i < ARRAY_SIZE(dummy_check_cmds); i++) {
326 init_s(dm_arg, min_sizeof_dm_ioctl, 0);
327 ioctl(-1, dummy_check_cmds[i].arg, dm_arg);
328 printf("ioctl(-1, %s, {version=4.1.2, data_size=%zu%s, "
329 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\"%s, "
330 "flags=0}) = -1 EBADF (%m)\n",
331 dummy_check_cmds[i].str, min_sizeof_dm_ioctl,
332 dummy_check_cmds[i].has_params ? ", data_start=0" : "",
333 dummy_check_cmds[i].has_event_nr ? ", event_nr=0" : "");
338 init_s(&s.ioc, sizeof(s.ioc), 0);
339 s.ioc.flags = DM_SUSPEND_FLAG;
340 s.ioc.event_nr = 0xbadc0ded;
341 ioctl(-1, DM_DEV_SUSPEND, &s);
342 printf("ioctl(-1, DM_DEV_SUSPEND, "
343 "{version=4.1.2, data_size=%zu, "
344 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
345 "flags=DM_SUSPEND_FLAG}) = -1 EBADF (%m)\n", sizeof(s.ioc));
347 init_s(&s.ioc, sizeof(s.ioc), 0);
348 s.ioc.event_nr = 0xbadc0ded;
349 ioctl(-1, DM_DEV_SUSPEND, &s);
350 printf("ioctl(-1, DM_DEV_SUSPEND, "
351 "{version=4.1.2, data_size=%zu, dev=makedev(18, 52), "
352 "name=\"nnn\", uuid=\"uuu\", event_nr=3134983661, "
353 "flags=0}) = -1 EBADF (%m)\n", sizeof(s.ioc));
357 init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
358 s.ioc.target_count = 1;
359 s.u.ts.target_spec.sector_start = 0x10;
360 s.u.ts.target_spec.length = 0x20;
361 s.u.ts.target_spec.next =
362 sizeof(s.u.ts.target_spec) + sizeof(s.u.ts.target_params);
363 strcpy(s.u.ts.target_spec.target_type, "tgt");
364 strcpy(s.u.ts.target_params, "tparams");
365 ioctl(-1, DM_TABLE_LOAD, &s);
366 printf("ioctl(-1, DM_TABLE_LOAD, "
367 "{version=4.1.2, data_size=%u, data_start=%u, "
368 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
369 "target_count=1, flags=0, "
371 "{sector_start=16, length=32, target_type=\"tgt\", "
372 "string=\"tparams\"}"
373 # else /* !VERBOSE */
375 # endif /* VERBOSE */
376 "}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start);
379 init_s(dm_arg, min_sizeof_dm_ioctl, min_sizeof_dm_ioctl);
380 dm_arg->data_size = sizeof(*dm_arg);
381 dm_arg->target_count = 0;
382 ioctl(-1, DM_TABLE_LOAD, dm_arg);
383 printf("ioctl(-1, DM_TABLE_LOAD, "
384 "{version=4.1.2, data_size=%zu, data_start=%zu, "
385 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
386 "target_count=0, flags=0}) = -1 EBADF (%m)\n",
387 sizeof(*dm_arg), min_sizeof_dm_ioctl);
389 /* Invalid data_start */
390 init_s(dm_arg, min_sizeof_dm_ioctl, 0xfffffff8);
391 dm_arg->data_size = sizeof(*dm_arg);
392 dm_arg->target_count = 1234;
393 ioctl(-1, DM_TABLE_LOAD, dm_arg);
394 printf("ioctl(-1, DM_TABLE_LOAD, "
395 "{version=4.1.2, data_size=%zu, data_start=%u, "
396 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
397 "target_count=1234, flags=0, "
399 "??? /* misplaced struct dm_target_spec */"
402 # endif /* VERBOSE */
403 "}) = -1 EBADF (%m)\n", sizeof(*dm_arg), 0xfffffff8);
405 /* Inaccessible pointer */
406 init_s(&dm_arg_open1->ioc, offsetof(struct dm_table_open_test, target1),
407 offsetof(struct dm_table_open_test, target1));
408 dm_arg_open1->ioc.data_size = sizeof(*dm_arg_open1);
409 dm_arg_open1->ioc.target_count = 0xdeaddea1;
410 ioctl(-1, DM_TABLE_LOAD, dm_arg_open1);
411 printf("ioctl(-1, DM_TABLE_LOAD, "
412 "{version=4.1.2, data_size=%zu, data_start=%zu, "
413 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
414 "target_count=3735936673, flags=0, "
417 # else /* !VERBOSE */
419 # endif /* VERBOSE */
420 "}) = -1 EBADF (%m)\n", sizeof(*dm_arg_open1),
421 offsetof(struct dm_table_open_test, target1)
423 , (char *) dm_arg_open1 +
424 offsetof(struct dm_table_open_test, target1)
425 # endif /* VERBOSE */
428 /* Inaccessible string */
429 init_s(&dm_arg_open2->ioc, offsetof(struct dm_table_open_test, param1),
430 offsetof(struct dm_table_open_test, target1));
431 dm_arg_open2->ioc.data_size = sizeof(*dm_arg_open2);
432 dm_arg_open2->ioc.target_count = 2;
433 init_dm_target_spec(&dm_arg_open2->target1, 7);
434 dm_arg_open2->target1.next =
435 offsetof(struct dm_table_open_test, target3) -
436 offsetof(struct dm_table_open_test, target1);
437 rc = ioctl(-1, DM_TABLE_LOAD, dm_arg_open2);
438 errstr = sprintrc(rc);
439 printf("ioctl(-1, DM_TABLE_LOAD, "
440 "{version=4.1.2, data_size=%zu, data_start=%zu, "
441 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
442 "target_count=2, flags=0, ",
443 sizeof(*dm_arg_open2),
444 offsetof(struct dm_table_open_test, target1));
446 print_dm_target_spec(&dm_arg_open2->target1, 7);
448 (char *) dm_arg_open2 +
449 offsetof(struct dm_table_open_test, param1),
450 (char *) dm_arg_open2 +
451 offsetof(struct dm_table_open_test, target3));
452 # else /* !VERBOSE */
454 # endif /* VERBOSE */
455 printf("}) = %s\n", errstr);
458 init_s(&dm_arg_open3->ioc, offsetof(struct dm_table_open_test, target5),
459 offsetof(struct dm_table_open_test, target0));
460 dm_arg_open3->ioc.target_count = 4;
462 init_dm_target_spec(&dm_arg_open3->target0, 9);
463 dm_arg_open3->target0.next =
464 offsetof(struct dm_table_open_test, target1) -
465 offsetof(struct dm_table_open_test, target0);
466 dm_arg_open3->param0[0] = '\0';
468 init_dm_target_spec(&dm_arg_open3->target1, 15);
469 dm_arg_open3->target1.next =
470 offsetof(struct dm_table_open_test, target3) -
471 offsetof(struct dm_table_open_test, target1);
472 dm_arg_open3->param1[0] = '\377';
473 dm_arg_open3->param1[1] = '\0';
475 init_dm_target_spec(&dm_arg_open3->target3, 42);
476 dm_arg_open3->target3.next = 0xdeadbeef;
477 dm_arg_open3->param3[0] = '\1';
478 dm_arg_open3->param3[1] = '\2';
479 dm_arg_open3->param3[2] = '\0';
481 rc = ioctl(-1, DM_TABLE_LOAD, dm_arg_open3);
482 errstr = sprintrc(rc);
483 printf("ioctl(-1, DM_TABLE_LOAD, "
484 "{version=4.1.2, data_size=%zu, data_start=%zu, "
485 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
486 "target_count=4, flags=0, ",
487 offsetof(struct dm_table_open_test, target5),
488 offsetof(struct dm_table_open_test, target0));
490 print_dm_target_spec(&dm_arg_open3->target0, 9);
492 print_dm_target_spec(&dm_arg_open3->target1, 15);
493 printf("\"\\377\"}, ");
494 print_dm_target_spec(&dm_arg_open3->target1, 42);
495 printf("\"\\1\\2\"}, ??? /* misplaced struct dm_target_spec */");
496 # else /* !VERBOSE */
498 # endif /* VERBOSE */
499 printf("}) = %s\n", errstr);
501 #define FILL_DM_TARGET(id, id_next) \
503 init_dm_target_spec(&dm_arg_open3->target##id, id); \
504 dm_arg_open3->target##id.next = \
505 offsetof(struct dm_table_open_test, \
507 offsetof(struct dm_table_open_test, \
509 strncpy(dm_arg_open3->param##id, str129 + id * 2, id); \
510 dm_arg_open3->param##id[id] = '\0'; \
512 #define PRINT_DM_TARGET(id) \
514 print_dm_target_spec(&dm_arg_open3->target##id, id); \
515 printf("\"%.*s\"}, ", id, str129 + id * 2); \
518 /* max_strlen limit */
519 init_s(&dm_arg_open3->ioc, offsetof(struct dm_table_open_test, target9),
520 offsetof(struct dm_table_open_test, target0));
521 dm_arg_open3->ioc.data_size = sizeof(*dm_arg_open3);
522 dm_arg_open3->ioc.target_count = 0xbadc0ded;
523 FILL_DM_TARGET(0, 1);
524 FILL_DM_TARGET(1, 2);
525 FILL_DM_TARGET(2, 3);
526 FILL_DM_TARGET(3, 4);
527 FILL_DM_TARGET(4, 5);
528 FILL_DM_TARGET(5, 6);
529 FILL_DM_TARGET(6, 7);
530 FILL_DM_TARGET(7, 8);
531 FILL_DM_TARGET(8, 9);
532 rc = ioctl(-1, DM_TABLE_LOAD, dm_arg_open3);
533 errstr = sprintrc(rc);
534 printf("ioctl(-1, DM_TABLE_LOAD, "
535 "{version=4.1.2, data_size=%zu, data_start=%zu, "
536 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
537 "target_count=3134983661, flags=0, ",
538 sizeof(*dm_arg_open3),
539 offsetof(struct dm_table_open_test, target0));
550 # endif /* VERBOSE */
551 printf("...}) = %s\n", errstr);
555 init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
556 s.u.tm.target_msg.sector = 0x1234;
557 strcpy(s.u.string + offsetof(struct dm_target_msg, message),
559 ioctl(-1, DM_TARGET_MSG, &s);
560 printf("ioctl(-1, DM_TARGET_MSG, "
561 "{version=4.1.2, data_size=%u, data_start=%u, "
562 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
564 "{sector=4660, message=\"long targ\"...}"
565 # else /* !VERBOSE */
567 # endif /* VERBOSE */
568 "}) = -1 EBADF (%m)\n",
569 s.ioc.data_size, s.ioc.data_start);
571 /* Invalid data_start */
572 init_s(dm_arg, min_sizeof_dm_ioctl, min_sizeof_dm_ioctl);
573 dm_arg->data_size = sizeof(*dm_arg);
574 ioctl(-1, DM_TARGET_MSG, dm_arg);
575 printf("ioctl(-1, DM_TARGET_MSG, "
576 "{version=4.1.2, data_size=%zu, data_start=%zu, "
577 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
579 "??? /* misplaced struct dm_target_msg */"
580 # else /* !VERBOSE */
582 # endif /* VERBOSE */
583 "}) = -1 EBADF (%m)\n",
584 sizeof(*dm_arg), min_sizeof_dm_ioctl);
586 /* Invalid data_start */
587 init_s(dm_arg, min_sizeof_dm_ioctl, 0xffffffff);
588 dm_arg->data_size = sizeof(*dm_arg);
589 ioctl(-1, DM_TARGET_MSG, dm_arg);
590 printf("ioctl(-1, DM_TARGET_MSG, "
591 "{version=4.1.2, data_size=%zu, data_start=%u, "
592 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
594 "??? /* misplaced struct dm_target_msg */"
595 # else /* !VERBOSE */
597 # endif /* VERBOSE */
598 "}) = -1 EBADF (%m)\n",
599 sizeof(*dm_arg), 0xffffffff);
601 /* Inaccessible pointer */
602 init_s(dm_arg, min_sizeof_dm_ioctl, 0);
603 dm_arg->data_size = sizeof(*dm_arg) + sizeof(struct dm_target_msg);
604 dm_arg->data_start = sizeof(*dm_arg);
605 ioctl(-1, DM_TARGET_MSG, dm_arg);
606 printf("ioctl(-1, DM_TARGET_MSG, "
607 "{version=4.1.2, data_size=%zu, data_start=%zu, "
608 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
611 # else /* !VERBOSE */
613 # endif /* VERBOSE */
614 "}) = -1 EBADF (%m)\n",
615 sizeof(*dm_arg) + sizeof(struct dm_target_msg),
618 , (char *) dm_arg + sizeof(*dm_arg)
619 # endif /* VERBOSE */
622 /* Inaccessible string */
623 init_s(&dm_arg_msg->ioc, sizeof(*dm_arg_msg),
624 offsetof(struct dm_target_msg_test, msg));
625 dm_arg_msg->ioc.data_size = sizeof(*dm_arg_msg) + 1;
626 dm_arg_msg->msg.sector = (__u64) 0xdeadbeeffacef157ULL;
627 rc = ioctl(-1, DM_TARGET_MSG, dm_arg_msg);
628 errstr = sprintrc(rc);
629 printf("ioctl(-1, DM_TARGET_MSG, "
630 "{version=4.1.2, data_size=%zu, data_start=%zu, "
631 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, ",
632 sizeof(*dm_arg_msg) + 1,
633 offsetof(struct dm_target_msg_test, msg));
635 printf("{sector=%" PRI__u64 ", message=%p}",
636 (__u64) 0xdeadbeeffacef157ULL,
637 (char *) dm_arg_msg +
638 offsetof(struct dm_target_msg_test, msg.message));
639 # else /* !VERBOSE */
641 # endif /* VERBOSE */
642 printf("}) = %s\n", errstr);
644 /* Zero-sied string */
645 init_s(&dm_arg_msg->ioc, sizeof(*dm_arg_msg),
646 offsetof(struct dm_target_msg_test, msg));
647 dm_arg_msg->msg.sector = (__u64) 0xdeadbeeffacef157ULL;
648 rc = ioctl(-1, DM_TARGET_MSG, dm_arg_msg);
649 errstr = sprintrc(rc);
650 printf("ioctl(-1, DM_TARGET_MSG, "
651 "{version=4.1.2, data_size=%zu, data_start=%zu, "
652 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, ",
653 sizeof(*dm_arg_msg), offsetof(struct dm_target_msg_test, msg));
655 printf("{sector=%" PRI__u64 ", message=\"\"}",
656 (__u64) 0xdeadbeeffacef157ULL);
657 # else /* !VERBOSE */
659 # endif /* VERBOSE */
660 printf("}) = %s\n", errstr);
663 /* DM_DEV_SET_GEOMETRY */
664 init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
665 strcpy(s.u.string, "10 20 30 40");
666 ioctl(-1, DM_DEV_SET_GEOMETRY, &s);
667 printf("ioctl(-1, DM_DEV_SET_GEOMETRY, "
668 "{version=4.1.2, data_size=%u, data_start=%u, "
669 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
671 "string=\"10 20 30 \"..."
672 # else /* !VERBOSE */
674 # endif /* VERBOSE */
675 "}) = -1 EBADF (%m)\n",
676 s.ioc.data_size, s.ioc.data_start);
680 /* Inaccessible data */
681 init_s(dm_arg, min_sizeof_dm_ioctl, min_sizeof_dm_ioctl);
682 dm_arg->data_size = sizeof(*dm_arg);
683 memcpy(unaligned_dm_arg, dm_arg, offsetof(struct dm_ioctl, data));
684 ioctl(-1, DM_DEV_RENAME, unaligned_dm_arg);
685 printf("ioctl(-1, DM_DEV_RENAME, "
686 "{version=4.1.2, data_size=%zu, data_start=%zu, "
687 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, "
691 # else /* !VERBOSE */
693 # endif /* VERBOSE */
694 "}) = -1 EBADF (%m)\n",
695 sizeof(*unaligned_dm_arg), min_sizeof_dm_ioctl
697 , (char *) unaligned_dm_arg + min_sizeof_dm_ioctl
698 # endif /* VERBOSE */
701 /* Incorrect data_start data */
702 init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
703 s.ioc.data_start = 0xdeadbeef;
704 ioctl(-1, DM_DEV_RENAME, &s);
705 printf("ioctl(-1, DM_DEV_RENAME, "
706 "{version=4.1.2, data_size=%u, data_start=3735928559, "
707 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, "
710 "??? /* misplaced string */"
711 # else /* !VERBOSE */
713 # endif /* VERBOSE */
714 "}) = -1 EBADF (%m)\n",
717 /* Strange but still valid data_start */
718 init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
719 /* Curiously, this is a valid structure */
720 s.ioc.data_start = offsetof(struct dm_ioctl, name) + 1;
721 ioctl(-1, DM_DEV_RENAME, &s);
722 printf("ioctl(-1, DM_DEV_RENAME, "
723 "{version=4.1.2, data_size=%u, data_start=%zu, "
724 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, "
728 # else /* !VERBOSE */
730 # endif /* VERBOSE */
731 "}) = -1 EBADF (%m)\n",
733 offsetof(struct dm_ioctl, name) + 1);
736 init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
737 strcpy(s.u.string, "new long name");
738 ioctl(-1, DM_DEV_RENAME, &s);
739 printf("ioctl(-1, DM_DEV_RENAME, "
740 "{version=4.1.2, data_size=%u, data_start=%u, "
741 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, "
744 "string=\"new long \"..."
745 # else /* !VERBOSE */
747 # endif /* VERBOSE */
748 "}) = -1 EBADF (%m)\n",
749 s.ioc.data_size, s.ioc.data_start);
753 init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
754 s.ioc.target_count = -1U;
755 ioctl(-1, DM_TABLE_LOAD, &s);
756 printf("ioctl(-1, DM_TABLE_LOAD, "
757 "{version=4.1.2, data_size=%u, data_start=%u, "
758 "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
759 "target_count=4294967295, flags=0, "
761 "{sector_start=0, length=0, target_type=\"\", string=\"\"}"
762 ", ??? /* misplaced struct dm_target_spec */"
765 # endif /* VERBOSE */
766 "}) = -1 EBADF (%m)\n",
767 s.ioc.data_size, s.ioc.data_start);
769 puts("+++ exited with 0 +++");
773 #else /* !HAVE_LINUX_DM_IOCTL_H */
775 SKIP_MAIN_UNDEFINED("HAVE_LINUX_DM_IOCTL_H")
777 #endif /* HAVE_LINUX_DM_IOCTL_H */