Re: [dm-devel] [PATCH] device mapper ioctl
On Wed, Oct 19, 2016 at 8:31 PM, Mikulas Patockawrote: > > Hi > > Here I'm sending the device mapper ioctl patch with these changes merged. Hello. Thank you for your contribution. The implementation of DM_* ioctl decoding is now in strace's master, you can check it out at https://github.com/strace/strace/commit/a507a0bb777c552e43e1e45f302703a09ffea1b8 Could you please review it and let us know if there are any issues? > In this piece of code: > + dm_arg_open3->target3.next = 0xdeadbeef; > + dm_arg_open3->param3[0] = '\1'; > + dm_arg_open3->param3[1] = '\2'; > + dm_arg_open3->param1[2] = '\0'; > there should be "dm_arg_open3->param3[2]" instead of > "dm_arg_open3->param1[2]". "dm_arg_open3->param1[2]" produces a warning > about access beyond the end of array. Thank you for noticing, it was an oversight on my part. > Mikulas -- Eugene "eSyr" Syromyatnikov mailto:evg...@gmail.com xmpp:eSyr@jabber.{ru|org} -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 7/9] tests: Some additional checks for ioctl_dm test
--- tests/ioctl_dm.c | 505 ++ 1 file changed, 505 insertions(+) diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 24232b7..0b2c5a7 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -2,13 +2,26 @@ #ifdef HAVE_LINUX_DM_IOCTL_H +# include # include +# include # include # include # include # include # include +# define STR32 "AbCdEfGhIjKlMnOpQrStUvWxYz012345" + +static const char str129[] = STR32 STR32 STR32 STR32 "6"; + +static const __u64 dts_sector_base = (__u64) 0xdeadca75facef157ULL; +static const __u64 dts_sector_step = (__u64) 0x10001ULL; +static const __u64 dts_length_base = (__u64) 0xbadc0dedda7a1057ULL; +static const __u64 dts_length_step = (__u64) 0x70007ULL; +static const __s32 dts_status_base = (__s32) 3141592653U; +static const __s32 dts_status_step = 0x1234; + static struct s { struct dm_ioctl ioc; union { @@ -24,6 +37,43 @@ static struct s { } u; } s; +struct dm_table_open_test { + struct dm_ioctl ioc; + struct dm_target_spec target0; + char param0[1]; + struct dm_target_spec target1; + char param1[2]; + struct dm_target_spec target2; + char param2[3]; + struct dm_target_spec target3; + char param3[4]; + struct dm_target_spec target4; + char param4[5]; + struct dm_target_spec target5; + char param5[6]; + struct dm_target_spec target6; + char param6[7]; + struct dm_target_spec target7; + char param7[8]; + struct dm_target_spec target8; + char param8[9]; + struct dm_target_spec target9; + char param9[10]; +}; + +struct dm_target_msg_test { + struct dm_ioctl ioc; + struct dm_target_msg msg; +}; + +struct args { + unsigned int arg; + const char *str; + bool has_params; + bool has_event_nr; +}; + + static void init_s(struct dm_ioctl *s, size_t size, size_t offs) { @@ -38,9 +88,147 @@ init_s(struct dm_ioctl *s, size_t size, size_t offs) strcpy(s->uuid, "uuu"); } +static void +init_dm_target_spec(struct dm_target_spec *ptr, uint32_t id) +{ + ptr->sector_start = dts_sector_base + dts_sector_step * id; + ptr->length = dts_length_base + dts_length_step * id; + ptr->status = dts_status_base + dts_status_step * id; + + strncpy(ptr->target_type, str129 + + id % (sizeof(str129) - sizeof(ptr->target_type)), + id % (sizeof(ptr->target_type) + 1)); + if (id % (sizeof(ptr->target_type) + 1) < sizeof(ptr->target_type)) + ptr->target_type[id % (sizeof(ptr->target_type) + 1)] = '\0'; +} + +static void +print_dm_target_spec(struct dm_target_spec *ptr, uint32_t id) +{ + printf("{sector_start=%" PRI__u64 ", length=%" PRI__u64 ", " + "target_type=\"%.*s\", string=", + dts_sector_base + dts_sector_step * id, + dts_length_base + dts_length_step * id, + (int) (id % (sizeof(ptr->target_type) + 1)), + str129 + id % (sizeof(str129) - sizeof(ptr->target_type))); +} + +# define ARG_STR(_arg) (_arg), #_arg + int main(void) { + /* We can't check these properly for now */ + static struct args dummy_check_cmds_nodev[] = { + { ARG_STR(DM_REMOVE_ALL),false }, + { ARG_STR(DM_LIST_DEVICES), true }, + { ARG_STR(DM_LIST_VERSIONS), true }, + }; + static struct args dummy_check_cmds[] = { + { ARG_STR(DM_DEV_CREATE),false }, + { ARG_STR(DM_DEV_REMOVE),false, true }, + { ARG_STR(DM_DEV_STATUS),false }, + { ARG_STR(DM_DEV_WAIT), true, true }, + { ARG_STR(DM_TABLE_CLEAR), false }, + { ARG_STR(DM_TABLE_DEPS),true }, + { ARG_STR(DM_TABLE_STATUS), true }, + }; + + struct dm_ioctl *dm_arg = + tail_alloc(sizeof(*dm_arg) - sizeof(dm_arg->data)); + struct dm_table_open_test *dm_arg_open1 = + tail_alloc(offsetof(struct dm_table_open_test, target1)); + struct dm_table_open_test *dm_arg_open2 = + tail_alloc(offsetof(struct dm_table_open_test, param1)); + struct dm_table_open_test *dm_arg_open3 = + tail_alloc(offsetof(struct dm_table_open_test, target9)); + struct dm_target_msg_test *dm_arg_msg = + tail_alloc(sizeof(*dm_arg_msg)); + + int saved_errno; + unsigned int i; + + + /* Incorrect operation */ + ioctl(-1, _IOW(DM_IOCTL, 0xde, int), dm_arg); + printf("ioctl(-1, _IOC(_IOC_WRITE, %#04x, 0xde, %#04zx), %p) = " + "-1 EBADF (%m)\n", + DM_IOCTL, sizeof(int), dm_arg); + + + /* DM_VERSION */ + /* Incorrect pointer */ + ioctl(-1, DM_VERSION, dm_arg + 1); + printf("ioctl(-1, DM_VERSION, %p) = -1 EBADF (%m)\n", dm_arg + 1); + +
[dm-devel] [PATCH 2/9] tests: Add check for printing of overlength strings to ioctl_dm test
--- tests/ioctl_dm.c|2 +- tests/ioctl_dm.test |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 6ad4ea9..0a3bbf4 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -77,7 +77,7 @@ main(void) printf("ioctl(-1, DM_DEV_SET_GEOMETRY, " "{version=4.1.2, data_size=%u, data_start=%u, " "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, " - "string=\"10 20 30 40\"}) = -1 EBADF (%m)\n", + "string=\"10 20 30 \"...}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); init_s(, sizeof(s), offsetof(struct s, u)); diff --git a/tests/ioctl_dm.test b/tests/ioctl_dm.test index db77616..78866d3 100755 --- a/tests/ioctl_dm.test +++ b/tests/ioctl_dm.test @@ -5,7 +5,7 @@ . "${srcdir=.}/init.sh" run_prog > /dev/null -run_strace -a16 -veioctl $args > "$EXP" +run_strace -a16 -s9 -veioctl $args > "$EXP" check_prog grep grep -v '^ioctl([012],' < "$LOG" > "$OUT" match_diff "$OUT" "$EXP" -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 8/9] tests: Add ioctl_dm to .gitignore
--- tests/.gitignore |1 + 1 file changed, 1 insertion(+) diff --git a/tests/.gitignore b/tests/.gitignore index a6d014d..9045117 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -103,6 +103,7 @@ getxxid inet-cmsg ioctl ioctl_block +ioctl_dm ioctl_evdev ioctl_evdev-v ioctl_mtd -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 4/9] tests/ioctl_dm: whitespace
--- tests/ioctl_dm.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 5f2689c..261983c 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -24,7 +24,8 @@ static struct s { } u; } s; -static void init_s(struct dm_ioctl *s, size_t size, size_t offs) +static void +init_s(struct dm_ioctl *s, size_t size, size_t offs) { memset(s, 0, size); s->version[0] = DM_VERSION_MAJOR; -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 0/9] Additional checks for strace DM ioctl decoder test
Hello. Aside from additional checks themselves, this patchset also contains two notable changes: * Fix for the previous patchset - misplaced comma printing ("dm: Fix comma printing for the case when dm_target_msg structure is inaccessible"). * Update of printstr_ex call, which enables proper handling of QUOTE_0_TERMINATED user style (it prints cropped string without ellipsis otherwise). Eugene Syromyatnikov (9): util: Add support for QUOTE_0_TERMINATED in user_style to ptrintstr_ex tests: Add check for printing of overlength strings to ioctl_dm test tests: Add check for presence of HAVE_LINUX_DM_IOCTL_H macro definition to ioctl_dm test tests/ioctl_dm: whitespace dm: Fix comma printing for the case when dm_target_msg structure is inaccessible tests/ioctl_dm: overly long string printing checks tests: Some additional checks for ioctl_dm test tests: Add ioctl_dm to .gitignore tests: Add checks for abbreviated DM ioctl output dm.c |4 +- tests/.gitignore |2 + tests/Makefile.am |2 + tests/ioctl_dm-v.c|2 + tests/ioctl_dm-v.test | 12 + tests/ioctl_dm.c | 653 +++-- tests/ioctl_dm.test |2 +- util.c| 18 +- 8 files changed, 674 insertions(+), 21 deletions(-) create mode 100644 tests/ioctl_dm-v.c create mode 100755 tests/ioctl_dm-v.test -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 5/9] dm: Fix comma printing for the case when dm_target_msg structure is inaccessible
--- dm.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dm.c b/dm.c index d846233..b1d455c 100644 --- a/dm.c +++ b/dm.c @@ -342,10 +342,12 @@ dm_decode_dm_target_msg(struct tcb *tcp, unsigned long addr, offset + target_msg_message_offs <= ioc->data_size) { struct dm_target_msg s; + tprints(", "); + if (umove_or_printaddr(tcp, addr + offset, )) return; - tprintf(", {sector=%" PRI__u64 ", message=", s.sector); + tprintf("{sector=%" PRI__u64 ", message=", s.sector); printstr_ex(tcp, addr + offset + target_msg_message_offs, ioc->data_size - offset - target_msg_message_offs, QUOTE_0_TERMINATED); -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 9/9] tests: Add checks for abbreviated DM ioctl output
--- tests/.gitignore |1 + tests/Makefile.am |2 + tests/ioctl_dm-v.c|2 + tests/ioctl_dm-v.test | 12 tests/ioctl_dm.c | 178 +++-- tests/ioctl_dm.test |2 +- 6 files changed, 160 insertions(+), 37 deletions(-) create mode 100644 tests/ioctl_dm-v.c create mode 100755 tests/ioctl_dm-v.test diff --git a/tests/.gitignore b/tests/.gitignore index 9045117..b2c5434 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -104,6 +104,7 @@ inet-cmsg ioctl ioctl_block ioctl_dm +ioctl_dm-v ioctl_evdev ioctl_evdev-v ioctl_mtd diff --git a/tests/Makefile.am b/tests/Makefile.am index 2405415..61b6db7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -164,6 +164,7 @@ check_PROGRAMS = \ ioctl \ ioctl_block \ ioctl_dm \ + ioctl_dm-v \ ioctl_evdev \ ioctl_evdev-v \ ioctl_mtd \ @@ -513,6 +514,7 @@ DECODER_TESTS = \ ioctl.test \ ioctl_block.test \ ioctl_dm.test \ + ioctl_dm-v.test \ ioctl_evdev.test \ ioctl_evdev-v.test \ ioctl_mtd.test \ diff --git a/tests/ioctl_dm-v.c b/tests/ioctl_dm-v.c new file mode 100644 index 000..d95058f --- /dev/null +++ b/tests/ioctl_dm-v.c @@ -0,0 +1,2 @@ +#define VERBOSE 1 +#include "ioctl_dm.c" diff --git a/tests/ioctl_dm-v.test b/tests/ioctl_dm-v.test new file mode 100755 index 000..4f6d64c --- /dev/null +++ b/tests/ioctl_dm-v.test @@ -0,0 +1,12 @@ +#!/bin/sh + +# Check abbreviated decoding of DM* ioctls. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +run_strace -a16 -s9 -veioctl $args > "$EXP" +check_prog grep +grep -v '^ioctl([012],' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" +rm -f "$EXP" "$OUT" diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 0b2c5a7..2fcd430 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -11,6 +11,10 @@ # include # include +# ifndef VERBOSE +# define VERBOSE 0 +# endif + # define STR32 "AbCdEfGhIjKlMnOpQrStUvWxYz012345" static const char str129[] = STR32 STR32 STR32 STR32 "6"; @@ -102,6 +106,7 @@ init_dm_target_spec(struct dm_target_spec *ptr, uint32_t id) ptr->target_type[id % (sizeof(ptr->target_type) + 1)] = '\0'; } +# if VERBOSE static void print_dm_target_spec(struct dm_target_spec *ptr, uint32_t id) { @@ -112,6 +117,7 @@ print_dm_target_spec(struct dm_target_spec *ptr, uint32_t id) (int) (id % (sizeof(ptr->target_type) + 1)), str129 + id % (sizeof(str129) - sizeof(ptr->target_type))); } +# endif /* VERBOSE */ # define ARG_STR(_arg) (_arg), #_arg @@ -303,9 +309,14 @@ main(void) printf("ioctl(-1, DM_TABLE_LOAD, " "{version=4.1.2, data_size=%u, data_start=%u, " "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", " - "target_count=1, flags=0, {sector_start=16, " - "length=32, target_type=\"tgt\", string=\"tparams\"}}) = " - "-1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); + "target_count=1, flags=0, " +# if VERBOSE + "{sector_start=16, length=32, target_type=\"tgt\", " + "string=\"tparams\"}" +# else /* !VERBOSE */ + "..." +# endif /* VERBOSE */ + "}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); /* No targets */ init_s(dm_arg, sizeof(*dm_arg) - sizeof(dm_arg->data), @@ -328,8 +339,12 @@ main(void) "{version=4.1.2, data_size=%zu, data_start=%u, " "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", " "target_count=1234, flags=0, " - "/* misplaced struct dm_target_spec */ ...}) = -1 EBADF (%m)\n", - sizeof(*dm_arg), 0xfff8); +# if VERBOSE + "/* misplaced struct dm_target_spec */ ..." +# else /* !VERBOSE */ + "..." +# endif /* VERBOSE */ + "}) = -1 EBADF (%m)\n", sizeof(*dm_arg), 0xfff8); /* Inaccessible pointer */ init_s(_arg_open1->ioc, offsetof(struct dm_table_open_test, target1), @@ -340,11 +355,19 @@ main(void) printf("ioctl(-1, DM_TABLE_LOAD, " "{version=4.1.2, data_size=%zu, data_start=%zu, " "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", " - "target_count=3735936673, flags=0, %p}) = -1 EBADF (%m)\n", - sizeof(*dm_arg_open1), - offsetof(struct dm_table_open_test, target1), - (char *) dm_arg_open1 + - offsetof(struct dm_table_open_test, target1)); + "target_count=3735936673, flags=0, " +# if VERBOSE + "%p" +# else /* !VERBOSE */ + "..." +# endif /* VERBOSE */ + "}) = -1 EBADF (%m)\n", sizeof(*dm_arg_open1), + offsetof(struct dm_table_open_test, target1) +# if VERBOSE + , (char *) dm_arg_open1 + + offsetof(struct dm_table_open_test, target1) +# endif /* VERBOSE */
[dm-devel] [PATCH 6/9] tests/ioctl_dm: overly long string printing checks
--- tests/ioctl_dm.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 261983c..24232b7 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -67,12 +67,12 @@ main(void) init_s(, sizeof(s), offsetof(struct s, u)); s.u.tm.target_msg.sector = 0x1234; strcpy(s.u.string + offsetof(struct dm_target_msg, message), - "tmsg"); + "long target msg"); ioctl(-1, DM_TARGET_MSG, ); printf("ioctl(-1, DM_TARGET_MSG, " "{version=4.1.2, data_size=%u, data_start=%u, " "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, " - "{sector=4660, message=\"tmsg\"}}) = -1 EBADF (%m)\n", + "{sector=4660, message=\"long targ\"...}}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); init_s(, sizeof(s), offsetof(struct s, u)); @@ -85,12 +85,12 @@ main(void) s.ioc.data_size, s.ioc.data_start); init_s(, sizeof(s), offsetof(struct s, u)); - strcpy(s.u.string, "new-name"); + strcpy(s.u.string, "new long name"); ioctl(-1, DM_DEV_RENAME, ); printf("ioctl(-1, DM_DEV_RENAME, " "{version=4.1.2, data_size=%u, data_start=%u, " "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, " - "flags=0, string=\"new-name\"}) = -1 EBADF (%m)\n", + "flags=0, string=\"new long \"...}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); init_s(, sizeof(s), offsetof(struct s, u)); -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 19/21] dm: Add check whether command uses parameters
--- dm.c | 25 ++--- tests/ioctl_dm.c |2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/dm.c b/dm.c index caffc55..a48aa72 100644 --- a/dm.c +++ b/dm.c @@ -281,6 +281,23 @@ dm_decode_string(const struct dm_ioctl *ioc, const char *extra, } } +static inline bool +dm_ioctl_has_params(const unsigned int code) +{ + switch (code) { + case DM_VERSION: + case DM_REMOVE_ALL: + case DM_DEV_CREATE: + case DM_DEV_REMOVE: + case DM_DEV_SUSPEND: + case DM_DEV_STATUS: + case DM_TABLE_CLEAR: + return false; + } + + return true; +} + static int dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) { @@ -336,8 +353,10 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) goto skip; } - tprintf(", data_size=%u, data_start=%u", - ioc->data_size, ioc->data_start); + tprintf(", data_size=%u", ioc->data_size); + + if (dm_ioctl_has_params(code)) + tprintf(", data_start=%u", ioc->data_start); if (ioc->data_size < (sizeof(*ioc) - sizeof(ioc->data))) { tprints(", /* Incorrect data_size */ ..."); @@ -348,7 +367,7 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) dm_decode_values(tcp, code, ioc); dm_decode_flags(ioc); - if (ioc->data_size > sizeof(ioc)) { + if (dm_ioctl_has_params(code) && (ioc->data_size > sizeof(ioc))) { extra = malloc(ioc->data_size); if (extra) { extra_size = ioc->data_size; diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index c120ed2..6ad4ea9 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -40,7 +40,7 @@ main(void) init_s(, sizeof(s.ioc), 0); ioctl(-1, DM_VERSION, ); printf("ioctl(-1, DM_VERSION, " - "{version=4.1.2, data_size=%zu, data_start=0, " + "{version=4.1.2, data_size=%zu, " "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = " "-1 EBADF (%m)\n", sizeof(s.ioc)); -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
Re: [dm-devel] [PATCH] Re: your dm patch for strace
Hello. While digging through your patch, looks like I've stumbled upon what looks like some minor out-of-bunds write in dm ioctl code: nl->dev = 0 write (drivers/md/dm-ioctl.c:533 @ b66484cd7) could be out of bounds in case userspace provided data_size of sizeof(struct dm_ioctl) and there are no device mapper devices present. Since data_size remains the same, this write does not make it to user space, and since this memory is kmalloc'ed, it's unlikely it overwrites any data since struct dm_ioctl size is not divisible by 32, but nevertheless. On Sun, Oct 2, 2016 at 9:59 PM, Mikulas Patockawrote: > > > On Mon, 12 Sep 2016, Dmitry V. Levin wrote: > >> > + tprintf("}"); >> > + if (entering(tcp)) >> > + offset = offset + s->next; >> > + else >> > + offset = ioc->data_start + s->next; >> >> This code trusts s->next; unfortunately, strace cannot trust syscall >> arguments, otherwise anything may happen, e.g. >> >> $ cat ioctl_dm.c >> #include >> #include >> int main(void) >> { >> struct { >> struct dm_ioctl ioc; >> struct dm_target_spec spec; >> int i; >> } s = { >> .spec = { 0 }, >> .ioc = { >> .version[0] = DM_VERSION_MAJOR, >> .data_size = sizeof(s), >> .data_start = sizeof(s.ioc), >> .target_count = -1U >> } >> }; >> return !ioctl(-1, DM_TABLE_LOAD, ); >> } >> $ strace -veioctl ./ioctl_dm >> >> btw, this parser lacks tests. How one can easily verify that it works >> correctly? For example how a test for strace ioctl parser may look like >> see tests/ioctl_* files. >> >> >> -- >> ldv > > Here I'm sending new patch. It fixes the possible loop with s->next and > adds tests: > > Makefile.am |1 > configure.ac|1 > defs.h |1 > dm.c| 356 > > ioctl.c |4 > tests/Makefile.am |2 > tests/ioctl_dm.c| 78 +++ > tests/ioctl_dm.test | 12 + > xlat/dm_flags.in| 17 ++ > 9 files changed, 472 insertions(+) > > Index: strace/Makefile.am > === > --- strace.orig/Makefile.am > +++ strace/Makefile.am > @@ -97,6 +97,7 @@ strace_SOURCES = \ > desc.c \ > dirent.c\ > dirent64.c \ > + dm.c\ > empty.h \ > epoll.c \ > evdev.c \ > Index: strace/configure.ac > === > --- strace.orig/configure.ac > +++ strace/configure.ac > @@ -354,6 +354,7 @@ AC_CHECK_HEADERS(m4_normalize([ > elf.h > inttypes.h > linux/bsg.h > + linux/dm-ioctl.h > linux/dqblk_xfs.h > linux/falloc.h > linux/fiemap.h > Index: strace/defs.h > === > --- strace.orig/defs.h > +++ strace/defs.h > @@ -640,6 +640,7 @@ extern void print_struct_statfs64(struct > > extern void print_ifindex(unsigned int); > > +extern int dm_ioctl(struct tcb *, const unsigned int, long); > extern int file_ioctl(struct tcb *, const unsigned int, long); > extern int fs_x_ioctl(struct tcb *, const unsigned int, long); > extern int loop_ioctl(struct tcb *, const unsigned int, long); > Index: strace/dm.c > === > --- /dev/null > +++ strace/dm.c > @@ -0,0 +1,356 @@ > +#include "defs.h" > + > +#ifdef HAVE_LINUX_DM_IOCTL_H > + > +#include > +#include > + > +static void > +dm_decode_device(const unsigned int code, const struct dm_ioctl *ioc) > +{ > + switch (code) { > + case DM_REMOVE_ALL: > + case DM_LIST_DEVICES: > + case DM_LIST_VERSIONS: > + break; > + default: > + if (ioc->dev) > + tprintf(", dev=makedev(%u, %u)", > + major(ioc->dev), minor(ioc->dev)); > + if (ioc->name[0]) { > + tprints(", name="); > + print_quoted_string(ioc->name, DM_NAME_LEN, > + QUOTE_0_TERMINATED); > + } > + if (ioc->uuid[0]) { > + tprints(", uuid="); > + print_quoted_string(ioc->uuid, DM_UUID_LEN, > + QUOTE_0_TERMINATED); > + } > + break; > + } > +} > + > +static void > +dm_decode_values(struct tcb *tcp, const unsigned int code, > +const struct dm_ioctl *ioc) > +{ > + if (entering(tcp)) { > + switch (code) { > + case
[dm-devel] [PATCH 11/21] dm: Compare entering field values with exiting ones
--- dm.c | 74 -- tests/ioctl_dm.c | 26 +++ 2 files changed, 64 insertions(+), 36 deletions(-) diff --git a/dm.c b/dm.c index f23a65d..b6fb11d 100644 --- a/dm.c +++ b/dm.c @@ -282,28 +282,62 @@ dm_decode_string(const struct dm_ioctl *ioc, const char *extra, static int dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) { - struct dm_ioctl ioc; + struct dm_ioctl *ioc; + struct dm_ioctl *entering_ioc = NULL; + bool ioc_changed = false; char *extra = NULL; uint32_t extra_size = 0; - if (umoven(tcp, arg, sizeof(ioc) - sizeof(ioc.data), ) < 0) + ioc = malloc(sizeof(* ioc)); + if (!ioc) return 0; + + if (umoven(tcp, arg, sizeof(*ioc) - sizeof(ioc->data), ioc) < 0) { + free(ioc); + return 0; + } + if (entering(tcp)) + set_tcb_priv_data(tcp, ioc, free); + else { + entering_ioc = get_tcb_priv_data(tcp); + + /* +* retrieve_status, __dev_status called only in case of success, +* so it looks like there's no need to check open_count, +* event_nr, target_count, dev fields for change (they are +* printed only in case of absence of errors). +*/ + if (!entering_ioc || + (ioc->version[0] != entering_ioc->version[0]) || + (ioc->version[1] != entering_ioc->version[1]) || + (ioc->version[2] != entering_ioc->version[2]) || + (ioc->data_size != entering_ioc->data_size) || + (ioc->data_start != entering_ioc->data_start) || + (ioc->flags != entering_ioc->flags)) + ioc_changed = true; + } + + if (exiting(tcp) && syserror(tcp) && !ioc_changed) { + free(ioc); + return 1; + } + tprintf("%s{version=%d.%d.%d", entering(tcp) ? ", " : " => ", - ioc.version[0], ioc.version[1], ioc.version[2]); + ioc->version[0], ioc->version[1], ioc->version[2]); /* * if we use a different version of ABI, do not attempt to decode * ioctl fields */ - if (ioc.version[0] != DM_VERSION_MAJOR) { + if (ioc->version[0] != DM_VERSION_MAJOR) { tprints(", /* Unsupported device mapper ABI version */ ..."); goto skip; } - if (ioc.data_size > sizeof(ioc)) { - extra = malloc(ioc.data_size); + if (ioc->data_size > sizeof(ioc)) { + extra = malloc(ioc->data_size); if (extra) { - extra_size = ioc.data_size; + extra_size = ioc->data_size; if (umoven(tcp, arg, extra_size, extra) < 0) { free(extra); extra = NULL; @@ -311,9 +345,9 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) } } } - dm_decode_device(code, ); - dm_decode_values(tcp, code, ); - dm_decode_flags(); + dm_decode_device(code, ioc); + dm_decode_values(tcp, code, ioc); + dm_decode_flags(ioc); if (abbrev(tcp)) tprints(", ..."); else @@ -322,42 +356,42 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) case DM_TABLE_STATUS: if (entering(tcp) || syserror(tcp)) break; - dm_decode_dm_target_spec(tcp, , extra, extra_size); + dm_decode_dm_target_spec(tcp, ioc, extra, extra_size); break; case DM_TABLE_LOAD: if (!entering(tcp)) break; - dm_decode_dm_target_spec(tcp, , extra, extra_size); + dm_decode_dm_target_spec(tcp, ioc, extra, extra_size); break; case DM_TABLE_DEPS: if (entering(tcp) || syserror(tcp)) break; - dm_decode_dm_target_deps(, extra, extra_size); + dm_decode_dm_target_deps(ioc, extra, extra_size); break; case DM_LIST_DEVICES: if (entering(tcp) || syserror(tcp)) break; - dm_decode_dm_name_list(, extra, extra_size); + dm_decode_dm_name_list(ioc, extra, extra_size); break; case DM_LIST_VERSIONS: if (entering(tcp) || syserror(tcp)) break; - dm_decode_dm_target_versions(,
[dm-devel] [PATCH 02/21] dm: whitespace fixes
--- dm.c | 87 +++--- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/dm.c b/dm.c index 33a3972..d81983d 100644 --- a/dm.c +++ b/dm.c @@ -2,8 +2,8 @@ #ifdef HAVE_LINUX_DM_IOCTL_H -#include -#include +# include +# include static void dm_decode_device(const unsigned int code, const struct dm_ioctl *ioc) @@ -38,7 +38,7 @@ dm_decode_values(struct tcb *tcp, const unsigned int code, if (entering(tcp)) { switch (code) { case DM_TABLE_LOAD: - tprintf(", target_count=%"PRIu32"", + tprintf(", target_count=%" PRIu32, ioc->target_count); break; case DM_DEV_SUSPEND: @@ -47,7 +47,7 @@ dm_decode_values(struct tcb *tcp, const unsigned int code, case DM_DEV_RENAME: case DM_DEV_REMOVE: case DM_DEV_WAIT: - tprintf(", event_nr=%"PRIu32"", + tprintf(", event_nr=%" PRIu32, ioc->event_nr); break; } @@ -63,11 +63,11 @@ dm_decode_values(struct tcb *tcp, const unsigned int code, case DM_TABLE_DEPS: case DM_TABLE_STATUS: case DM_TARGET_MSG: - tprintf(", target_count=%"PRIu32"", + tprintf(", target_count=%" PRIu32, ioc->target_count); - tprintf(", open_count=%"PRIu32"", + tprintf(", open_count=%" PRIu32, ioc->open_count); - tprintf(", event_nr=%"PRIu32"", + tprintf(", event_nr=%" PRIu32, ioc->event_nr); break; } @@ -89,21 +89,23 @@ dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc, { uint32_t i; uint32_t offset = ioc->data_start; + for (i = 0; i < ioc->target_count; i++) { - if (offset + (uint32_t)sizeof(struct dm_target_spec) >= offset && - offset + (uint32_t)sizeof(struct dm_target_spec) < extra_size) { + if (offset + (uint32_t) sizeof(struct dm_target_spec) >= offset && + offset + (uint32_t) sizeof(struct dm_target_spec) < extra_size) { uint32_t new_offset; const struct dm_target_spec *s = - (const struct dm_target_spec *)(extra + offset); - tprintf(", {sector_start=%"PRIu64", length=%"PRIu64"", - (uint64_t)s->sector_start, (uint64_t)s->length); + (const struct dm_target_spec *) (extra + offset); + tprintf(", {sector_start=%" PRIu64 ", length=%" PRIu64, + (uint64_t) s->sector_start, + (uint64_t) s->length); if (!entering(tcp)) - tprintf(", status=%"PRId32"", s->status); + tprintf(", status=%" PRId32, s->status); tprints(", target_type="); print_quoted_string(s->target_type, DM_MAX_TYPE_NAME, QUOTE_0_TERMINATED); tprints(", string="); - print_quoted_string((const char *)(s + 1), extra_size - + print_quoted_string((const char *) (s + 1), extra_size - (offset + sizeof(struct dm_target_spec)), QUOTE_0_TERMINATED); @@ -112,7 +114,8 @@ dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc, new_offset = offset + s->next; else new_offset = ioc->data_start + s->next; - if (new_offset <= offset + (uint32_t)sizeof(struct dm_target_spec)) + if (new_offset <= offset + + (uint32_t) sizeof(struct dm_target_spec)) goto misplaced; offset = new_offset; } else { @@ -128,13 +131,15 @@ dm_decode_dm_target_deps(const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) { uint32_t offset = ioc->data_start; - if (offset + (uint32_t)offsetof(struct dm_target_deps, dev) >= offset && - offset + (uint32_t)offsetof(struct dm_target_deps, dev) <= extra_size) { + if (offset + (uint32_t) offsetof(struct dm_target_deps, dev) >= offset && + offset + (uint32_t) offsetof(struct dm_target_deps, dev) <= extra_size)
[dm-devel] [PATCH 14/21] dm: replace abbrev branching with goto
--- dm.c | 78 ++ 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/dm.c b/dm.c index 73a9b57..814d7d2 100644 --- a/dm.c +++ b/dm.c @@ -350,52 +350,54 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) } } } - if (abbrev(tcp)) + + if (abbrev(tcp)) { tprints(", ..."); - else - switch (code) { - case DM_DEV_WAIT: - case DM_TABLE_STATUS: - if (entering(tcp) || syserror(tcp)) - break; - dm_decode_dm_target_spec(tcp, ioc, extra, extra_size); - break; - case DM_TABLE_LOAD: - if (!entering(tcp)) - break; - dm_decode_dm_target_spec(tcp, ioc, extra, extra_size); + goto skip; + } + + switch (code) { + case DM_DEV_WAIT: + case DM_TABLE_STATUS: + if (entering(tcp) || syserror(tcp)) break; - case DM_TABLE_DEPS: - if (entering(tcp) || syserror(tcp)) - break; - dm_decode_dm_target_deps(ioc, extra, extra_size); + dm_decode_dm_target_spec(tcp, ioc, extra, extra_size); + break; + case DM_TABLE_LOAD: + if (!entering(tcp)) break; - case DM_LIST_DEVICES: - if (entering(tcp) || syserror(tcp)) - break; - dm_decode_dm_name_list(ioc, extra, extra_size); + dm_decode_dm_target_spec(tcp, ioc, extra, extra_size); + break; + case DM_TABLE_DEPS: + if (entering(tcp) || syserror(tcp)) break; - case DM_LIST_VERSIONS: - if (entering(tcp) || syserror(tcp)) - break; - dm_decode_dm_target_versions(ioc, extra, extra_size); + dm_decode_dm_target_deps(ioc, extra, extra_size); + break; + case DM_LIST_DEVICES: + if (entering(tcp) || syserror(tcp)) break; - case DM_TARGET_MSG: - if (entering(tcp)) { - dm_decode_dm_target_msg(ioc, extra, - extra_size); - } else if (!syserror(tcp) && - ioc->flags & DM_DATA_OUT_FLAG) { - dm_decode_string(ioc, extra, extra_size); - } + dm_decode_dm_name_list(ioc, extra, extra_size); + break; + case DM_LIST_VERSIONS: + if (entering(tcp) || syserror(tcp)) break; - case DM_DEV_RENAME: - case DM_DEV_SET_GEOMETRY: - if (!entering(tcp)) - break; + dm_decode_dm_target_versions(ioc, extra, extra_size); + break; + case DM_TARGET_MSG: + if (entering(tcp)) { + dm_decode_dm_target_msg(ioc, extra, + extra_size); + } else if (!syserror(tcp) && ioc->flags & DM_DATA_OUT_FLAG) { dm_decode_string(ioc, extra, extra_size); - break; } + break; + case DM_DEV_RENAME: + case DM_DEV_SET_GEOMETRY: + if (!entering(tcp)) + break; + dm_decode_string(ioc, extra, extra_size); + break; + } skip: tprints("}"); -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 05/21] xlat: Add values for dm_flags
Otherwise build fails on some old distros which lack DM_DATA_OUT_FLAG and other flags (excerpt from RHEL 5 build log): [ 66s] dm.c: In function 'dm_known_ioctl': [ 66s] dm.c:311: error: 'DM_DATA_OUT_FLAG' undeclared (first use in this function) [ 66s] dm.c:311: error: (Each undeclared identifier is reported only once [ 66s] dm.c:311: error: for each function it appears in.) Curiously, EXISTS flags had been present in v1 of DM interface, but was removed in v4. * xlat/dm_flags.in: Add values for DM_*_FLAG constants (obtained from ). --- xlat/dm_flags.in | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/xlat/dm_flags.in b/xlat/dm_flags.in index 1e7132b..fa734c8 100644 --- a/xlat/dm_flags.in +++ b/xlat/dm_flags.in @@ -1,19 +1,19 @@ -DM_READONLY_FLAG -DM_SUSPEND_FLAG +DM_READONLY_FLAG (1 << 0) +DM_SUSPEND_FLAG (1 << 1) /* Defined in lvm2/libdm/ioctl/libdm-iface.c */ -DM_EXISTS_FLAG 0x0004 -DM_PERSISTENT_DEV_FLAG -DM_STATUS_TABLE_FLAG -DM_ACTIVE_PRESENT_FLAG -DM_INACTIVE_PRESENT_FLAG -DM_BUFFER_FULL_FLAG -DM_SKIP_BDGET_FLAG -DM_SKIP_LOCKFS_FLAG -DM_NOFLUSH_FLAG -DM_QUERY_INACTIVE_TABLE_FLAG -DM_UEVENT_GENERATED_FLAG -DM_UUID_FLAG -DM_SECURE_DATA_FLAG -DM_DATA_OUT_FLAG -DM_DEFERRED_REMOVE -DM_INTERNAL_SUSPEND_FLAG +DM_EXISTS_FLAG (1 << 2) +DM_PERSISTENT_DEV_FLAG (1 << 3) +DM_STATUS_TABLE_FLAG (1 << 4) +DM_ACTIVE_PRESENT_FLAG (1 << 5) +DM_INACTIVE_PRESENT_FLAG (1 << 6) +DM_BUFFER_FULL_FLAG (1 << 8) +DM_SKIP_BDGET_FLAG (1 << 9) +DM_SKIP_LOCKFS_FLAG (1 << 10) +DM_NOFLUSH_FLAG (1 << 11) +DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) +DM_UEVENT_GENERATED_FLAG (1 << 13) +DM_UUID_FLAG (1 << 14) +DM_SECURE_DATA_FLAG (1 << 15) +DM_DATA_OUT_FLAG (1 << 16) +DM_DEFERRED_REMOVE (1 << 17) +DM_INTERNAL_SUSPEND_FLAG (1 << 18) -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 07/21] dm: Add definitions for ioctl commands not implemented initially
dm.c [!DM_LIST_VERSIONS] (DM_LIST_VERSIONS): New definition. [!DM_TARGET_MSG] (DM_TARGET_MSG): Likewise. [!DM_DEV_SET_GEOMETRY] (DM_DEV_SET_GEOMETRY): Likewise. --- dm.c | 13 + 1 file changed, 13 insertions(+) diff --git a/dm.c b/dm.c index 79bb7c7..66b615d 100644 --- a/dm.c +++ b/dm.c @@ -7,6 +7,19 @@ # if DM_VERSION_MAJOR == 4 +/* Definitions for command which have been added later */ + +# ifndef DM_LIST_VERSIONS +# define DM_LIST_VERSIONS_IOWR(DM_IOCTL, 0xd, struct dm_ioctl) +# endif +# ifndef DM_TARGET_MSG +# define DM_TARGET_MSG _IOWR(DM_IOCTL, 0xe, struct dm_ioctl) +# endif +# ifndef DM_DEV_SET_GEOMETRY +# define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, 0xf, struct dm_ioctl) +# endif + + static void dm_decode_device(const unsigned int code, const struct dm_ioctl *ioc) { -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 06/21] dm: Some future-proofing by means of compile-time DM_VERSION_MAJOR check
* dm.c: Add check whether DM_VERSION_MAJOR equals to 4, provide empty dm_ioctl if check fails. --- dm.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dm.c b/dm.c index ebdfc44..79bb7c7 100644 --- a/dm.c +++ b/dm.c @@ -5,6 +5,8 @@ # include # include +# if DM_VERSION_MAJOR == 4 + static void dm_decode_device(const unsigned int code, const struct dm_ioctl *ioc) { @@ -375,4 +377,13 @@ dm_ioctl(struct tcb *tcp, const unsigned int code, long arg) } } -#endif +# else /* !(DM_VERSION_MAJOR == 4) */ + +int +dm_ioctl(struct tcb *tcp, const unsigned int code, long arg) +{ + return 0; +} + +# endif /* DM_VERSION_MAJOR == 4 */ +#endif /* HAVE_LINUX_DM_IOCTL_H */ -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 01/21] tests/ioctl_dm: Formatting
--- tests/ioctl_dm.c | 42 +++--- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index f4c3c8b..a5945ae 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -40,38 +40,66 @@ main(void) s.ioc.data_size = sizeof(s.ioc); s.ioc.data_start = 0; ioctl(-1, DM_VERSION, ); - printf("ioctl(-1, DM_VERSION, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); + printf("ioctl(-1, DM_VERSION, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0}, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); init_s(); s.ioc.target_count = 1; s.u.ts.target_spec.sector_start = 0x10; s.u.ts.target_spec.length = 0x20; - s.u.ts.target_spec.next = sizeof(s.u.ts.target_spec) + sizeof(s.u.ts.target_params); + s.u.ts.target_spec.next = + sizeof(s.u.ts.target_spec) + sizeof(s.u.ts.target_params); strcpy(s.u.ts.target_spec.target_type, "tgt"); strcpy(s.u.ts.target_params, "tparams"); ioctl(-1, DM_TABLE_LOAD, ); - printf("ioctl(-1, DM_TABLE_LOAD, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", target_count=1, flags=0, {sector_start=16, length=32, target_type=\"tgt\", string=\"tparams\"}}, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); + printf("ioctl(-1, DM_TABLE_LOAD, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", target_count=1, flags=0, {sector_start=16, " + "length=32, target_type=\"tgt\", string=\"tparams\"}}, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); init_s(); s.u.tm.target_msg.sector = 0x1234; strcpy(s.u.tm.target_msg.message, "tmsg"); ioctl(-1, DM_TARGET_MSG, ); - printf("ioctl(-1, DM_TARGET_MSG, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, {sector=4660, message=\"tmsg\"}}, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); + printf("ioctl(-1, DM_TARGET_MSG, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0, {sector=4660, message=\"tmsg\"}}, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); init_s(); strcpy(s.u.string, "10 20 30 40"); ioctl(-1, DM_DEV_SET_GEOMETRY, ); - printf("ioctl(-1, DM_DEV_SET_GEOMETRY, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, string=\"10 20 30 40\"}, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); + printf("ioctl(-1, DM_DEV_SET_GEOMETRY, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0, string=\"10 20 30 40\"}, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); init_s(); strcpy(s.u.string, "new-name"); ioctl(-1, DM_DEV_RENAME, ); - printf("ioctl(-1, DM_DEV_RENAME, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, flags=0, string=\"new-name\"}, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); + printf("ioctl(-1, DM_DEV_RENAME, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", event_nr=0, flags=0, string=\"new-name\"}, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); init_s(); s.ioc.target_count = -1U; ioctl(-1, DM_TABLE_LOAD, ); - printf("ioctl(-1, DM_TABLE_LOAD, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", target_count=4294967295, flags=0, {sector_start=0, length=0, target_type=\"\", string=\"\"}, misplaced struct dm_target_spec}, {version=4.1.2, dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); + printf("ioctl(-1, DM_TABLE_LOAD, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", target_count=4294967295, flags=0, " + "{sector_start=0, length=0, target_type=\"\", string=\"\"}, " + "misplaced struct dm_target_spec}, " + "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " + "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); puts("+++ exited with 0 +++");
[dm-devel] [PATCH 16/21] dm: Add comment regarding intended fall-through in switch statement
--- dm.c |1 + 1 file changed, 1 insertion(+) diff --git a/dm.c b/dm.c index 289bc0d..5c908c9 100644 --- a/dm.c +++ b/dm.c @@ -60,6 +60,7 @@ dm_decode_values(struct tcb *tcp, const unsigned int code, case DM_DEV_SUSPEND: if (ioc->flags & DM_SUSPEND_FLAG) break; + /* Fall through */ case DM_DEV_RENAME: case DM_DEV_REMOVE: case DM_DEV_WAIT: -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 17/21] dm: Add data_size and data_offset fields to output
--- dm.c |4 +++- tests/ioctl_dm.c | 41 - 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/dm.c b/dm.c index 5c908c9..caffc55 100644 --- a/dm.c +++ b/dm.c @@ -327,7 +327,6 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) tprintf("%s{version=%d.%d.%d", entering(tcp) ? ", " : " => ", ioc->version[0], ioc->version[1], ioc->version[2]); - /* * if we use a different version of ABI, do not attempt to decode * ioctl fields @@ -337,6 +336,9 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) goto skip; } + tprintf(", data_size=%u, data_start=%u", + ioc->data_size, ioc->data_start); + if (ioc->data_size < (sizeof(*ioc) - sizeof(ioc->data))) { tprints(", /* Incorrect data_size */ ..."); goto skip; diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 94dbe93..6967ca2 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -42,8 +42,9 @@ main(void) s.ioc.data_start = 0; ioctl(-1, DM_VERSION, ); printf("ioctl(-1, DM_VERSION, " - "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); + "{version=4.1.2, data_size=%zu, data_start=0, " + "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = " + "-1 EBADF (%m)\n", sizeof(s.ioc)); init_s(); s.ioc.target_count = 1; @@ -55,10 +56,11 @@ main(void) strcpy(s.u.ts.target_params, "tparams"); ioctl(-1, DM_TABLE_LOAD, ); printf("ioctl(-1, DM_TABLE_LOAD, " - "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", target_count=1, flags=0, {sector_start=16, " + "{version=4.1.2, data_size=%u, data_start=%u, " + "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", " + "target_count=1, flags=0, {sector_start=16, " "length=32, target_type=\"tgt\", string=\"tparams\"}}) = " - "-1 EBADF (%m)\n"); + "-1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); init_s(); s.u.tm.target_msg.sector = 0x1234; @@ -66,34 +68,39 @@ main(void) "tmsg"); ioctl(-1, DM_TARGET_MSG, ); printf("ioctl(-1, DM_TARGET_MSG, " - "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", flags=0, {sector=4660, message=\"tmsg\"}}) = " - "-1 EBADF (%m)\n"); + "{version=4.1.2, data_size=%u, data_start=%u, " + "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, " + "{sector=4660, message=\"tmsg\"}}) = -1 EBADF (%m)\n", + s.ioc.data_size, s.ioc.data_start); init_s(); strcpy(s.u.string, "10 20 30 40"); ioctl(-1, DM_DEV_SET_GEOMETRY, ); printf("ioctl(-1, DM_DEV_SET_GEOMETRY, " - "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", flags=0, string=\"10 20 30 40\"}) = " - "-1 EBADF (%m)\n"); + "{version=4.1.2, data_size=%u, data_start=%u, " + "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, " + "string=\"10 20 30 40\"}) = -1 EBADF (%m)\n", + s.ioc.data_size, s.ioc.data_start); init_s(); strcpy(s.u.string, "new-name"); ioctl(-1, DM_DEV_RENAME, ); printf("ioctl(-1, DM_DEV_RENAME, " - "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", event_nr=0, flags=0, string=\"new-name\"}) = " - "-1 EBADF (%m)\n"); + "{version=4.1.2, data_size=%u, data_start=%u, " + "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, " + "flags=0, string=\"new-name\"}) = -1 EBADF (%m)\n", + s.ioc.data_size, s.ioc.data_start); init_s(); s.ioc.target_count = -1U; ioctl(-1, DM_TABLE_LOAD, ); printf("ioctl(-1, DM_TABLE_LOAD, " - "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", target_count=4294967295, flags=0, " + "{version=4.1.2, data_size=%u, data_start=%u, " + "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", " + "target_count=4294967295, flags=0, " "{sector_start=0, length=0, target_type=\"\", string=\"\"}, " - "/* misplaced struct dm_target_spec */ ...}) = -1 EBADF (%m)\n"); + "/* misplaced struct dm_target_spec */ ...}) = -1 EBADF (%m)\n", + s.ioc.data_size, s.ioc.data_start); puts("+++ exited with 0 +++"); return 0; -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 10/21] dm: use => instead of , for splitting output structure from input
--- dm.c |4 ++-- tests/ioctl_dm.c | 12 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dm.c b/dm.c index 3ee74c3..f23a65d 100644 --- a/dm.c +++ b/dm.c @@ -288,8 +288,8 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) if (umoven(tcp, arg, sizeof(ioc) - sizeof(ioc.data), ) < 0) return 0; - tprintf(", {version=%d.%d.%d", ioc.version[0], ioc.version[1], - ioc.version[2]); + tprintf("%s{version=%d.%d.%d", entering(tcp) ? ", " : " => ", + ioc.version[0], ioc.version[1], ioc.version[2]); /* * if we use a different version of ABI, do not attempt to decode diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index ba484ee..3c43913 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -42,7 +42,7 @@ main(void) ioctl(-1, DM_VERSION, ); printf("ioctl(-1, DM_VERSION, " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", flags=0}, " + "uuid=\"uuu\", flags=0} => " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); @@ -58,7 +58,7 @@ main(void) printf("ioctl(-1, DM_TABLE_LOAD, " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", target_count=1, flags=0, {sector_start=16, " - "length=32, target_type=\"tgt\", string=\"tparams\"}}, " + "length=32, target_type=\"tgt\", string=\"tparams\"}} => " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); @@ -69,7 +69,7 @@ main(void) ioctl(-1, DM_TARGET_MSG, ); printf("ioctl(-1, DM_TARGET_MSG, " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", flags=0, {sector=4660, message=\"tmsg\"}}, " + "uuid=\"uuu\", flags=0, {sector=4660, message=\"tmsg\"}} => " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); @@ -78,7 +78,7 @@ main(void) ioctl(-1, DM_DEV_SET_GEOMETRY, ); printf("ioctl(-1, DM_DEV_SET_GEOMETRY, " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", flags=0, string=\"10 20 30 40\"}, " + "uuid=\"uuu\", flags=0, string=\"10 20 30 40\"} => " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); @@ -87,7 +87,7 @@ main(void) ioctl(-1, DM_DEV_RENAME, ); printf("ioctl(-1, DM_DEV_RENAME, " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", event_nr=0, flags=0, string=\"new-name\"}, " + "uuid=\"uuu\", event_nr=0, flags=0, string=\"new-name\"} => " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); @@ -98,7 +98,7 @@ main(void) "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", target_count=4294967295, flags=0, " "{sector_start=0, length=0, target_type=\"\", string=\"\"}, " - "/* misplaced struct dm_target_spec */ ...}, " + "/* misplaced struct dm_target_spec */ ...} => " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 13/21] dm: Move printing of dm_ioctl fields before allocation of extra data
--- dm.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dm.c b/dm.c index a11196f..73a9b57 100644 --- a/dm.c +++ b/dm.c @@ -335,6 +335,10 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) goto skip; } + dm_decode_device(code, ioc); + dm_decode_values(tcp, code, ioc); + dm_decode_flags(ioc); + if (ioc->data_size > sizeof(ioc)) { extra = malloc(ioc->data_size); if (extra) { @@ -346,9 +350,6 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) } } } - dm_decode_device(code, ioc); - dm_decode_values(tcp, code, ioc); - dm_decode_flags(ioc); if (abbrev(tcp)) tprints(", ..."); else -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 21/21] dm: rewrite structure decoding
Rewrite structure decoding in attempt to make it more in line with how structures and arrays are decoded in strace. * Replace single structure retrieval with on-demand retrieval. It allows limiting amount of memory being allocated (suppose ioctl with data_size = -1) * Check for abbrev in structure decoders itself. It allows distinguishing cases when we want to decode some additional data from cases when we are not. --- dm.c | 363 +++--- 1 file changed, 217 insertions(+), 146 deletions(-) diff --git a/dm.c b/dm.c index ff9e8ad..d846233 100644 --- a/dm.c +++ b/dm.c @@ -101,165 +101,254 @@ dm_decode_flags(const struct dm_ioctl *ioc) } static void -dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc, -const char *extra, uint32_t extra_size) +dm_decode_dm_target_spec(struct tcb *tcp, unsigned long addr, +const struct dm_ioctl *ioc) { static const uint32_t target_spec_size = sizeof(struct dm_target_spec); uint32_t i; uint32_t offset = ioc->data_start; + if (abbrev(tcp)) { + if (ioc->target_count) + tprints(", ..."); + + return; + } + for (i = 0; i < ioc->target_count; i++) { - if (offset + target_spec_size >= offset && - offset + target_spec_size < extra_size) { - uint32_t new_offset; - const struct dm_target_spec *s = - (const struct dm_target_spec *) (extra + offset); - tprintf(", {sector_start=%" PRIu64 ", length=%" PRIu64, - (uint64_t) s->sector_start, - (uint64_t) s->length); - if (!entering(tcp)) - tprintf(", status=%" PRId32, s->status); - tprints(", target_type="); - print_quoted_string(s->target_type, DM_MAX_TYPE_NAME, - QUOTE_0_TERMINATED); - tprints(", string="); - print_quoted_string((const char *) (s + 1), extra_size - - (offset + target_spec_size), - QUOTE_0_TERMINATED); - tprintf("}"); - if (entering(tcp)) - new_offset = offset + s->next; - else - new_offset = ioc->data_start + s->next; - if (new_offset <= offset + target_spec_size) - goto misplaced; - offset = new_offset; - } else { -misplaced: - tprints(", /* misplaced struct dm_target_spec */ ..."); + struct dm_target_spec s; + uint32_t new_offset; + + if ((offset + target_spec_size) <= offset || + (offset + target_spec_size) > ioc->data_size) + goto misplaced; + + tprints(", "); + + if (i >= max_strlen) { + tprints("..."); break; } + + if (umove_or_printaddr(tcp, addr + offset, )) + break; + + tprintf("{sector_start=%" PRI__u64 ", length=%" PRI__u64, + s.sector_start, s.length); + + if (!entering(tcp)) + tprintf(", status=%" PRId32, s.status); + + tprints(", target_type="); + print_quoted_string(s.target_type, DM_MAX_TYPE_NAME, + QUOTE_0_TERMINATED); + + tprints(", string="); + printstr_ex(tcp, addr + offset + target_spec_size, +ioc->data_size - (offset + target_spec_size), +QUOTE_0_TERMINATED); + tprintf("}"); + + if (entering(tcp)) + new_offset = offset + s.next; + else + new_offset = ioc->data_start + s.next; + + if (new_offset <= offset + target_spec_size) + goto misplaced; + + offset = new_offset; } + + return; + +misplaced: + tprints(", /* misplaced struct dm_target_spec */ ..."); +} + +bool +dm_print_dev(struct tcb *tcp, void *dev_ptr, size_t dev_size, void *dummy) +{ + uint64_t *dev = (uint64_t *) dev_ptr; + + tprintf("makedev(%u, %u)", major(*dev), minor(*dev)); + + return 1; } static void -dm_decode_dm_target_deps(const struct dm_ioctl *ioc, const char *extra, -uint32_t extra_size) +dm_decode_dm_target_deps(struct tcb *tcp, unsigned long addr, +const struct
[dm-devel] [PATCH 15/21] dm: Additional data_size/data_start checks
--- dm.c |8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dm.c b/dm.c index 814d7d2..289bc0d 100644 --- a/dm.c +++ b/dm.c @@ -293,7 +293,8 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) if (!ioc) return 0; - if (umoven(tcp, arg, sizeof(*ioc) - sizeof(ioc->data), ioc) < 0) { + if ((umoven(tcp, arg, sizeof(*ioc) - sizeof(ioc->data), ioc) < 0) || + (ioc->data_size < offsetof(struct dm_ioctl, data_size))) { free(ioc); return 0; } @@ -335,6 +336,11 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) goto skip; } + if (ioc->data_size < (sizeof(*ioc) - sizeof(ioc->data))) { + tprints(", /* Incorrect data_size */ ..."); + goto skip; + } + dm_decode_device(code, ioc); dm_decode_values(tcp, code, ioc); dm_decode_flags(ioc); -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 04/21] dm: Minor output tweaks
Trying to make it more C-like and in line with common practices regarding structure printing. --- dm.c | 21 + tests/ioctl_dm.c |2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/dm.c b/dm.c index d81983d..ebdfc44 100644 --- a/dm.c +++ b/dm.c @@ -120,7 +120,7 @@ dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc, offset = new_offset; } else { misplaced: - tprints(", misplaced struct dm_target_spec"); + tprints(", /* misplaced struct dm_target_spec */ ..."); break; } } @@ -150,7 +150,7 @@ dm_decode_dm_target_deps(const struct dm_ioctl *ioc, const char *extra, tprints("}"); } else { misplaced: - tprints(", misplaced struct dm_target_deps"); + tprints(", /* misplaced struct dm_target_deps */ ..."); } } @@ -182,7 +182,7 @@ dm_decode_dm_name_list(const struct dm_ioctl *ioc, const char *extra, offset = offset + s->next; } else { misplaced: - tprints(", misplaced struct dm_name_list"); + tprints(", /* misplaced struct dm_name_list */ ..."); break; } } @@ -216,7 +216,8 @@ dm_decode_dm_target_versions(const struct dm_ioctl *ioc, const char *extra, offset = offset + s->next; } else { misplaced: - tprints(", misplaced struct dm_target_versions"); + tprints(", /* misplaced struct dm_target_versions */ " + "..."); break; } } @@ -240,7 +241,7 @@ dm_decode_dm_target_msg(const struct dm_ioctl *ioc, const char *extra, QUOTE_0_TERMINATED); tprints("}"); } else { - tprints(", misplaced struct dm_target_msg"); + tprints(", /* misplaced struct dm_target_msg */"); } } @@ -255,7 +256,7 @@ dm_decode_string(const struct dm_ioctl *ioc, const char *extra, print_quoted_string(extra + offset, extra_size - offset, QUOTE_0_TERMINATED); } else { - tprints(", misplaced string"); + tprints(", /* misplaced string */"); } } @@ -275,8 +276,10 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) * if we use a different version of ABI, do not attempt to decode * ioctl fields */ - if (ioc.version[0] != DM_VERSION_MAJOR) + if (ioc.version[0] != DM_VERSION_MAJOR) { + tprints(", /* Unsupported device mapper ABI version */ ..."); goto skip; + } if (ioc.data_size > sizeof(ioc)) { extra = malloc(ioc.data_size); @@ -292,7 +295,9 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) dm_decode_device(code, ); dm_decode_values(tcp, code, ); dm_decode_flags(); - if (!abbrev(tcp)) + if (abbrev(tcp)) + tprints(", ..."); + else switch (code) { case DM_DEV_WAIT: case DM_TABLE_STATUS: diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index cb6dd97..ba484ee 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -98,7 +98,7 @@ main(void) "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", target_count=4294967295, flags=0, " "{sector_start=0, length=0, target_type=\"\", string=\"\"}, " - "misplaced struct dm_target_spec}, " + "/* misplaced struct dm_target_spec */ ...}, " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 20/21] dm: Fix printing of version field
--- dm.c |6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dm.c b/dm.c index a48aa72..ff9e8ad 100644 --- a/dm.c +++ b/dm.c @@ -342,7 +342,11 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg) return 1; } - tprintf("%s{version=%d.%d.%d", entering(tcp) ? ", " : " => ", + /* +* device mapper code uses %d in some places and %u in another, but +* fields themselves are declared as __u32. +*/ + tprintf("%s{version=%u.%u.%u", entering(tcp) ? ", " : " => ", ioc->version[0], ioc->version[1], ioc->version[2]); /* * if we use a different version of ABI, do not attempt to decode -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 12/21] dm: Add inttypes.h, include reorder
Build failed otherwise on RHEL 5. --- dm.c |3 ++- tests/ioctl_dm.c |1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dm.c b/dm.c index b6fb11d..a11196f 100644 --- a/dm.c +++ b/dm.c @@ -2,8 +2,9 @@ #ifdef HAVE_LINUX_DM_IOCTL_H -# include +# include # include +# include # if DM_VERSION_MAJOR == 4 diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 31f474c..94dbe93 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -1,4 +1,5 @@ #include "tests.h" +#include #include #include #include -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 18/21] tests/ioctl_dm: Allow passing size and data_start to init_s
--- tests/ioctl_dm.c | 34 -- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 6967ca2..c120ed2 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -21,32 +21,30 @@ static struct s { } u; } s; -static void init_s(void) +static void init_s(struct dm_ioctl *s, size_t size, size_t offs) { - memset(, 0, sizeof s); - s.ioc.version[0] = DM_VERSION_MAJOR; - s.ioc.version[1] = 1; - s.ioc.version[2] = 2; - s.ioc.data_size = sizeof(s); - s.ioc.data_start = offsetof(struct s, u); - s.ioc.dev = 0x1234; - strcpy(s.ioc.name, "nnn"); - strcpy(s.ioc.uuid, "uuu"); + memset(s, 0, size); + s->version[0] = DM_VERSION_MAJOR; + s->version[1] = 1; + s->version[2] = 2; + s->data_size = size; + s->data_start = offs; + s->dev = 0x1234; + strcpy(s->name, "nnn"); + strcpy(s->uuid, "uuu"); } int main(void) { - init_s(); - s.ioc.data_size = sizeof(s.ioc); - s.ioc.data_start = 0; + init_s(, sizeof(s.ioc), 0); ioctl(-1, DM_VERSION, ); printf("ioctl(-1, DM_VERSION, " "{version=4.1.2, data_size=%zu, data_start=0, " "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = " "-1 EBADF (%m)\n", sizeof(s.ioc)); - init_s(); + init_s(, sizeof(s), offsetof(struct s, u)); s.ioc.target_count = 1; s.u.ts.target_spec.sector_start = 0x10; s.u.ts.target_spec.length = 0x20; @@ -62,7 +60,7 @@ main(void) "length=32, target_type=\"tgt\", string=\"tparams\"}}) = " "-1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); - init_s(); + init_s(, sizeof(s), offsetof(struct s, u)); s.u.tm.target_msg.sector = 0x1234; strcpy(s.u.string + offsetof(struct dm_target_msg, message), "tmsg"); @@ -73,7 +71,7 @@ main(void) "{sector=4660, message=\"tmsg\"}}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); - init_s(); + init_s(, sizeof(s), offsetof(struct s, u)); strcpy(s.u.string, "10 20 30 40"); ioctl(-1, DM_DEV_SET_GEOMETRY, ); printf("ioctl(-1, DM_DEV_SET_GEOMETRY, " @@ -82,7 +80,7 @@ main(void) "string=\"10 20 30 40\"}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); - init_s(); + init_s(, sizeof(s), offsetof(struct s, u)); strcpy(s.u.string, "new-name"); ioctl(-1, DM_DEV_RENAME, ); printf("ioctl(-1, DM_DEV_RENAME, " @@ -91,7 +89,7 @@ main(void) "flags=0, string=\"new-name\"}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start); - init_s(); + init_s(, sizeof(s), offsetof(struct s, u)); s.ioc.target_count = -1U; ioctl(-1, DM_TABLE_LOAD, ); printf("ioctl(-1, DM_TABLE_LOAD, " -- 1.7.10.4 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
[dm-devel] [PATCH 08/21] dm: Use static constants for offset sizes
This may improve readability an leads to more compact code. --- dm.c | 58 +++--- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/dm.c b/dm.c index 66b615d..adfa97e 100644 --- a/dm.c +++ b/dm.c @@ -102,12 +102,14 @@ static void dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) { + static const uint32_t target_spec_size = + sizeof(struct dm_target_spec); uint32_t i; uint32_t offset = ioc->data_start; for (i = 0; i < ioc->target_count; i++) { - if (offset + (uint32_t) sizeof(struct dm_target_spec) >= offset && - offset + (uint32_t) sizeof(struct dm_target_spec) < extra_size) { + if (offset + target_spec_size >= offset && + offset + target_spec_size < extra_size) { uint32_t new_offset; const struct dm_target_spec *s = (const struct dm_target_spec *) (extra + offset); @@ -121,16 +123,14 @@ dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc, QUOTE_0_TERMINATED); tprints(", string="); print_quoted_string((const char *) (s + 1), extra_size - - (offset + - sizeof(struct dm_target_spec)), + (offset + target_spec_size), QUOTE_0_TERMINATED); tprintf("}"); if (entering(tcp)) new_offset = offset + s->next; else new_offset = ioc->data_start + s->next; - if (new_offset <= offset + - (uint32_t) sizeof(struct dm_target_spec)) + if (new_offset <= offset + target_spec_size) goto misplaced; offset = new_offset; } else { @@ -145,13 +145,15 @@ static void dm_decode_dm_target_deps(const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) { + static const uint32_t target_deps_dev_offs = + offsetof(struct dm_target_deps, dev); uint32_t offset = ioc->data_start; - if (offset + (uint32_t) offsetof(struct dm_target_deps, dev) >= offset && - offset + (uint32_t) offsetof(struct dm_target_deps, dev) <= extra_size) { + if (offset + target_deps_dev_offs >= offset && + offset + target_deps_dev_offs <= extra_size) { uint32_t i; - uint32_t space = (extra_size - (offset + - offsetof(struct dm_target_deps, dev))) / sizeof(__u64); + uint32_t space = (extra_size - offset - target_deps_dev_offs) / + sizeof(__u64); const struct dm_target_deps *s = (const struct dm_target_deps *) (extra + offset); @@ -173,11 +175,13 @@ static void dm_decode_dm_name_list(const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) { + static const uint32_t name_list_name_offs = + offsetof(struct dm_name_list, name); uint32_t offset = ioc->data_start; while (1) { - if (offset + (uint32_t) offsetof(struct dm_name_list, name) >= offset && - offset + (uint32_t) offsetof(struct dm_name_list, name) < extra_size) { + if (offset + name_list_name_offs >= offset && + offset + name_list_name_offs < extra_size) { const struct dm_name_list *s = (const struct dm_name_list *) (extra + offset); @@ -186,13 +190,12 @@ dm_decode_dm_name_list(const struct dm_ioctl *ioc, const char *extra, tprintf(", {dev=makedev(%u, %u), name=", major(s->dev), minor(s->dev)); print_quoted_string(s->name, extra_size - (offset + - offsetof(struct dm_name_list, - name)), QUOTE_0_TERMINATED); + name_list_name_offs), + QUOTE_0_TERMINATED); tprints("}"); if (!s->next) break; - if (offset + s->next <= offset + - (uint32_t) offsetof(struct dm_name_list, name)) + if (offset + s->next <= offset + name_list_name_offs) goto misplaced; offset = offset +