your dm patch for strace
Subsystems (2)
A message that is not in the archive (sent off-list or not yet received): alpine.LRH.2.02.1608221155410.17400@file01.intranet.prod.int.rdu2.redhat.com
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): alpine.LRH.2.02.1608231303510.7049@file01.intranet.prod.int.rdu2.redhat.com
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): 20160824.233543.198328104871315294.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
Quoted 4 lines · Masatake YAMATO
Quoted 4 lines
Quoted 1 line
Are you talking about https://sourceforge.net/p/strace/mailman/message/34370586/ ?
Yes.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
The thread has apparently died without any follow-up from your side.
I didn't receive that last message, it was probably sent only to the mailing list address, not to my address.
Can I expect you will submit updated version of the patch?
Masatake YAMATO
Here I'm sending the updated device mapper strace patch with the comments addressed. (please send replies to my email address, I'm not on the strace mailing list)
Mikulas
configure.ac +1 -0
@@ -363,6 +363,7 @@ AC_CHECK_HEADERS(m4_normalize([ elf.h inttypes.h linux/bsg.h + linux/dm-ioctl.h linux/falloc.h linux/fiemap.h linux/filter.h
dm.c new file +351 -0
351 lines not on this page · raw message
ioctl.c +4 -0
@@ -282,6 +282,10 @@ ioctl_decode(struct tcb *tcp)case 0x94 :return btrfs_ioctl (tcp, code, arg);#endif +#ifdef HAVE_LINUX_DM_IOCTL_H +case 0xfd : +return dm_ioctl (tcp, code, arg); +#endif default :break ; }
Makefile.am +1 -0
@@ -97,6 +97,7 @@ strace_SOURCES = \ desc.c \ dirent.c \ dirent64.c \ + dm.c \ empty.h \ epoll.c \ evdev.c \
defs.h +1 -0
@@ -640,6 +640,7 @@ extern void print_struct_statfs64(structextern 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 );
xlat/dm_flags.in new file +17 -0
@@ -0,0 +1,17 @@ +DM_READONLY_FLAG +DM_SUSPEND_FLAG +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
------------------------------------------------------------------------------
A message that is not in the archive (sent off-list or not yet received): alpine.LRH.2.02.1608250823130.24332-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/[email protected]
Quoted 141 lines · Mikulas Patocka
Quoted 4 lines · Masatake YAMATO
Quoted 4 lines
Quoted 1 line
Are you talking about https://sourceforge.net/p/strace/mailman/message/34370586/ ?
Yes.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
The thread has apparently died without any follow-up from your side.
I didn't receive that last message, it was probably sent only to the mailing list address, not to my address.
Can I expect you will submit updated version of the patch?
Masatake YAMATO
Here I'm sending the updated device mapper strace patch with the comments addressed. (please send replies to my email address, I'm not on the strace mailing list)
Mikulas
Index: strace/configure.ac
===================================================================configure.ac +1
-0@@ -363,6 +363,7 @@ AC_CHECK_HEADERS(m4_normalize([ elf.h inttypes.h linux/bsg.h + linux/dm-ioctl.h linux/falloc.h linux/fiemap.h linux/filter.hIndex:
strace/dm.c
===================================================================dm.c new file +103
-0@@ -0,0 +1,351 @@ +#include "defs.h" + +#ifdef HAVE_LINUX_DM_IOCTL_H + +#include <sys/ioctl.h> +#include <linux/dm-ioctl.h> + +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_TABLE_LOAD : +tprintf (", target_count=%" PRIu32"" , + ioc->target_count); +break ; +case DM_DEV_SUSPEND : +if (ioc->flags &DM_SUSPEND_FLAG ) +break ; +case DM_DEV_RENAME : +case DM_DEV_REMOVE : +case DM_DEV_WAIT : +tprintf (", event_nr=%" PRIu32"" , + ioc->event_nr); +break ; + } + }else if (!syserror (tcp)) { +switch (code) { +case DM_DEV_CREATE : +case DM_DEV_RENAME : +case DM_DEV_SUSPEND : +case DM_DEV_STATUS : +case DM_DEV_WAIT : +case DM_TABLE_LOAD : +case DM_TABLE_CLEAR : +case DM_TABLE_DEPS : +case DM_TABLE_STATUS : +case DM_TARGET_MSG : +tprintf (", target_count=%" PRIu32"" , + ioc->target_count); +tprintf (", open_count=%" PRIu32"" , + ioc->open_count); +tprintf (", event_nr=%" PRIu32"" , + ioc->event_nr); +break ; + } + } +} + +#include "xlat/dm_flags.h" + +static void +dm_decode_flags (const struct dm_ioctl *ioc) +{ +tprints (", flags=" ); +printflags (dm_flags, ioc->flags,"DM_???" ); +} + +static void +dm_decode_dm_target_spec (struct tcb *tcp,const struct dm_ioctl *ioc, +const char *extra,uint32_t extra_size) +{ +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) { +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 );
dm.c line 113
Quoted 10 lines
dm.c new file +10
-0+tprints (", string=" ); +print_quoted_string ((const char *)(s +1 ), extra_size - + (offset + +sizeof (struct dm_target_spec )), +QUOTE_0_TERMINATED ); +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 <sys/ioctl.h>
#include <linux/dm-ioctl.h>
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, &s);
}
$ strace -veioctl ./ioctl_dmbtw, 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.
Signature · 1 line
ldv
------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports. http://sdm.link/zohodev2dev
_______________________________________________
Strace-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel
A message that is not in the archive (sent off-list or not yet received): 20160912171029.GA5263-u2l5PoMzF/[email protected]
Quoted 31 lines · Dmitry V. Levin
Review
Quoted 5 lines
(quoted diff) +5
-0+ 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 <sys/ioctl.h> #include <linux/dm-ioctl.h> 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, &s); } $ strace -veioctl ./ioctl_dm
Quoted 7 lines
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.
Signature · 1 line
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(+)
Makefile.am +1 -0
@@ -97,6 +97,7 @@ strace_SOURCES = \ desc.c \ dirent.c \ dirent64.c \ + dm.c \ empty.h \ epoll.c \ evdev.c \
configure.ac +1 -0
@@ -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
defs.h +1 -0
@@ -640,6 +640,7 @@ extern void print_struct_statfs64(structextern 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 );
dm.c new file +356 -0
356 lines not on this page · raw message
ioctl.c +4 -0
@@ -282,6 +282,10 @@ ioctl_decode(struct tcb *tcp)case 0x94 :return btrfs_ioctl (tcp, code, arg);#endif +#ifdef HAVE_LINUX_DM_IOCTL_H +case 0xfd : +return dm_ioctl (tcp, code, arg); +#endif default :break ; }
tests/Makefile.am +2 -0
@@ -161,6 +161,7 @@ check_PROGRAMS = \ inet-cmsg \ ioctl \ ioctl_block \ + ioctl_dm \ ioctl_evdev \ ioctl_evdev-v \ ioctl_mtd \
@@ -503,6 +504,7 @@ DECODER_TESTS = \ inet-cmsg.test \ ioctl.test \ ioctl_block.test \ + ioctl_dm.test \ ioctl_evdev.test \ ioctl_evdev-v.test \ ioctl_mtd.test \
tests/ioctl_dm.c new file +78 -0
78 lines not on this page · raw message
tests/ioctl_dm.test new file +12 -0
@@ -0,0 +1,12 @@ +#!/bin/sh + +# Check decoding of DM* ioctls. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +run_strace -a16 -veioctl $args > "$EXP" +check_prog grep +grep -v '^ioctl([012],' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" +rm -f "$EXP" "$OUT"
xlat/dm_flags.in new file +17 -0
@@ -0,0 +1,17 @@ +DM_READONLY_FLAG +DM_SUSPEND_FLAG +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
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
A message that is not in the archive (sent off-list or not yet received): alpine.LRH.2.02.1610021751280.29417-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/[email protected]
I tested the patch and it works fine.
Could you add following patch if you approve?
commit bae7528fa92283726caac1ec7a6c306274f8899d
Author: Masatake YAMATO <[email protected]> Date: Mon Aug 22 17:44:55 2016 +0900
dm-ioctl: add a lvm private flag
When I run "dmsetup ls" under dm-ioctl patched strace, "strange DM_???" are found in its output.
# ./strace -e ioctl dmsetup ls > /dev/null
ioctl(3, DM_VERSION, {version=4.0.0, flags=0x4 /* DM_??? */}, ... ioctl(3, DM_LIST_DEVICES, {version=4.0.0, flags=0x4 /* DM_??? */}, ...
...
Associated definion for DM_??? is in lvm2 source tree. This commit imports the definion to dm-ioctl list.
xlat/dm_flags.in +2 -0
@@ -1,5 +1,7 @@ DM_READONLY_FLAG DM_SUSPEND_FLAG +/* Defined in lvm2/libdm/ioctl/libdm-iface.c */ +DM_EXISTS_FLAG 0x00000004 DM_PERSISTENT_DEV_FLAG DM_STATUS_TABLE_FLAG DM_ACTIVE_PRESENT_FLAG
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
A message that is not in the archive (sent off-list or not yet received): 20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
cover Some possible additions to the DM ioctl patch for strace
Hello.
I've took the liberty to look at the patch and I'd like to propose some changes to it. Can you please review them from the DM side of things? I'm not quite sure I've understood all the specifics of the interface correctly, it's quite peculiar.
I'm also preparing a patch for the DM ioctl decoder test, but it's not ready yet.
Eugene Syromyatnikov (21):
tests/ioctl_dm: Formatting
dm: whitespace fixes
tests: Working around bounds check
dm: Minor output tweaks
xlat: Add values for dm_flags
dm: Some future-proofing by means of compile-time DM_VERSION_MAJOR
check
dm: Add definitions for ioctl commands not implemented initially
dm: Use static constants for offset sizes
dm: Remove char * cast
dm: use => instead of , for splitting output structure from input
dm: Compare entering field values with exiting ones
dm: Add inttypes.h, include reorder
dm: Move printing of dm_ioctl fields before allocation of extra data
dm: replace abbrev branching with goto
dm: Additional data_size/data_start checks
dm: Add comment regarding intended fall-through in switch statement
dm: Add data_size and data_offset fields to output tests/ioctl_dm: Allow passing size and data_start to init_s
dm: Add check whether command uses parameters
dm: Fix printing of version field
dm: rewrite structure decoding
dm.c | 549 ++++++++++++++++++++++++++++++++++++------------------ tests/ioctl_dm.c | 79 +++++--- xlat/dm_flags.in | 36 ++-- 3 files changed, 442 insertions(+), 222 deletions(-)
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 1/21 tests/ioctl_dm: Formatting
In reply to a message not in the archive--- tests/ioctl_dm.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-)
tests/ioctl_dm.c +35 -7
@@ -40,38 +40,66 @@ main(void) s.ioc.data_size =sizeof (s.ioc); s.ioc.data_start =0 ;ioctl (-1 ,DM_VERSION , &s); -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 , &s); -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 , &s); -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 , &s); -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 , &s); -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 , &s); -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 +++" );return 0 ;
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 2/21 dm: whitespace fixes
In reply to a message not in the archive--- dm.c | 87 +++++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 35 deletions(-)
dm.c +52 -35
@@ -2,8 +2,8 @@#ifdef HAVE_LINUX_DM_IOCTL_H -#include <sys/ioctl.h> -#include <linux/dm-ioctl.h> +# include <sys/ioctl.h> +# include <linux/dm-ioctl.h> 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) { +uint32_t i;uint32_t space = (extra_size - (offset + offsetof(struct dm_target_deps , dev))) /sizeof (__u64);const struct dm_target_deps *s = - (const struct dm_target_deps *)(extra + offset); + (const struct dm_target_deps *) (extra + offset); +if (s->count > space) goto misplaced;tprints (", deps={" );
@@ -154,21 +159,25 @@ dm_decode_dm_name_list(const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) {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 + (uint32_t ) offsetof(struct dm_name_list , name) >= offset && + offset + (uint32_t ) offsetof(struct dm_name_list , name) < extra_size) {const struct dm_name_list *s = - (const struct dm_name_list *)(extra + offset); + (const struct dm_name_list *) (extra + offset); +if (!s->dev)break ; -tprintf (", {dev=makedev(%u, %u), name=" ,major (s->dev),minor (s->dev)); +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 );tprints ("}" );if (!s->next)break ; -if (offset + s->next <= offset + (uint32_t )offsetof(struct dm_name_list , name)) +if (offset + s->next <= offset + + (uint32_t ) offsetof(struct dm_name_list , name)) goto misplaced; offset = offset + s->next; }else {
@@ -184,22 +193,25 @@ dm_decode_dm_target_versions(const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) {uint32_t offset = ioc->data_start; +while (1 ) { -if (offset + (uint32_t )offsetof(struct dm_target_versions , name) >= +if (offset + (uint32_t ) offsetof(struct dm_target_versions , name) >= offset && - offset + (uint32_t )offsetof(struct dm_target_versions , name) < + offset + (uint32_t ) offsetof(struct dm_target_versions , name) < extra_size) {const struct dm_target_versions *s = (const struct dm_target_versions *)(extra + offset); +tprints (", {name=" );print_quoted_string (s->name, extra_size - (offset + offsetof(struct dm_target_versions , name)),QUOTE_0_TERMINATED ); -tprintf (", version=%" PRIu32".%" PRIu32".%" PRIu32"}" , +tprintf (", version=%" PRIu32".%" PRIu32".%" PRIu32"}" , s->version[0 ], s->version[1 ], s->version[2 ]);if (!s->next)break ; -if (offset + s->next <= offset + (uint32_t )offsetof(struct dm_target_versions , name)) +if (offset + s->next <= offset + + (uint32_t ) offsetof(struct dm_target_versions , name)) goto misplaced; offset = offset + s->next; }else {
@@ -215,11 +227,14 @@ dm_decode_dm_target_msg(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_msg , message) >= offset && - offset + (uint32_t )offsetof(struct dm_target_msg , message) < extra_size) { + +if (offset + (uint32_t ) offsetof(struct dm_target_msg , message) >= offset && + offset + (uint32_t ) offsetof(struct dm_target_msg , message) < extra_size) {const struct dm_target_msg *s = - (const struct dm_target_msg *)(extra + offset); -tprintf (", {sector=%" PRIu64", message=" , (uint64_t )s->sector); + (const struct dm_target_msg *) (extra + offset); + +tprintf (", {sector=%" PRIu64", message=" , + (uint64_t ) s->sector);print_quoted_string (s->message, extra_size - offsetof(struct dm_target_msg , message),QUOTE_0_TERMINATED );
@@ -234,6 +249,7 @@ dm_decode_string(const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) {uint32_t offset = ioc->data_start; +if (offset < extra_size) {tprints (", string=" ); print_quoted_string(extra + offset, extra_size - offset,
@@ -250,7 +266,7 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)char *extra =NULL ;uint32_t extra_size =0 ; -if (umoven (tcp, arg,sizeof (ioc) -sizeof (ioc.data), (char *)&ioc) <0 ) +if (umoven (tcp, arg,sizeof (ioc) -sizeof (ioc.data), (char *) &ioc) <0 )return 0 ;tprintf (", {version=%d.%d.%d" , ioc.version[0 ], ioc.version[1 ], ioc.version[2 ]);
@@ -276,7 +292,8 @@ 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))switch (code) { +if (!abbrev (tcp)) +switch (code) {case DM_DEV_WAIT :case DM_TABLE_STATUS :if (entering (tcp) ||syserror (tcp))
@@ -308,7 +325,7 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)dm_decode_dm_target_msg (&ioc, extra, extra_size); }else if (!syserror (tcp) && - ioc.flags &DM_DATA_OUT_FLAG ) { + ioc.flags &DM_DATA_OUT_FLAG ) {dm_decode_string (&ioc, extra, extra_size); }break ;
@@ -318,7 +335,7 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)break ;dm_decode_string (&ioc, extra, extra_size);break ; - } + } skip:tprints ("}" );
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 3/21 tests: Working around bounds check
In reply to a message not in the archiveWhen building with -Wp,-D_FORTIFY_SOURCE=2, dompiler produces the following warning:
In file included from /usr/include/string.h:638:0,
from ioctl_dm.c:4:
In function ‘strcpy’,
inlined from ‘main’ at ioctl_dm.c:57:8:/usr/include/bits/string3.h:104:3: warning: call to __builtin___strcpy_chk will always overflow destination buffer [enabled by default]
return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
^
And later it aborts:
[ 200s] FAIL: ioctl_dm [ 200s] ============== [ 200s] [ 200s] + ../strace -V [ 200s] + TIMEOUT='timeout -s 9 60' [ 200s] + timeout -s 9 60 true [ 200s] + exec timeout -s 9 60 ./ioctl_dm.test [ 200s] + run_prog [ 200s] + '[' 0 -eq 0 ']' [ 200s] + set -- ./ioctl_dm [ 200s] + args=./ioctl_dm [ 200s] + ./ioctl_dm [ 200s] *** buffer overflow detected ***: ./ioctl_dm terminated [ 200s] ======= Backtrace: ========= [ 200s] /lib64/libc.so.6(__fortify_fail+0x37)[0x7fbc8fa1acb7] [ 200s] /lib64/libc.so.6(+0x10be80)[0x7fbc8fa18e80] [ 200s] ./ioctl_dm[0x400616] [ 200s] /lib64/libc.so.6(__libc_start_main+0xf5)[0x7fbc8f92eaf5] [ 200s] ./ioctl_dm[0x400739] [ 200s] ======= Memory map: ======== [ 200s] 00400000-00401000 r-xp 00000000 08:00 84792 /home/abuild/rpmbuild/BUILD/strace-4.13.0.260.af086/tests/ioctl_dm [ 200s] 00601000-00602000 r--p 00001000 08:00 84792 /home/abuild/rpmbuild/BUILD/strace-4.13.0.260.af086/tests/ioctl_dm [ 200s] 00602000-00603000 rw-p 00002000 08:00 84792 /home/abuild/rpmbuild/BUILD/strace-4.13.0.260.af086/tests/ioctl_dm [ 200s] 02244000-02265000 rw-p 00000000 00:00 0 [heap] [ 200s] 7fbc8f6f5000-7fbc8f70a000 r-xp 00000000 08:00 131341 /usr/lib64/libgcc_s-4.8.2-20140120.so.1 [ 200s] 7fbc8f70a000-7fbc8f909000 ---p 00015000 08:00 131341 /usr/lib64/libgcc_s-4.8.2-20140120.so.1 [ 200s] 7fbc8f909000-7fbc8f90a000 r--p 00014000 08:00 131341 /usr/lib64/libgcc_s-4.8.2-20140120.so.1 [ 200s] 7fbc8f90a000-7fbc8f90b000 rw-p 00015000 08:00 131341 /usr/lib64/libgcc_s-4.8.2-20140120.so.1 [ 200s] 7fbc8f90d000-7fbc8fac3000 r-xp 00000000 08:00 131350 /usr/lib64/libc-2.17.so [ 200s] 7fbc8fac3000-7fbc8fcc3000 ---p 001b6000 08:00 131350 /usr/lib64/libc-2.17.so [ 200s] 7fbc8fcc3000-7fbc8fcc7000 r--p 001b6000 08:00 131350 /usr/lib64/libc-2.17.so [ 200s] 7fbc8fcc7000-7fbc8fcc9000 rw-p 001ba000 08:00 131350 /usr/lib64/libc-2.17.so [ 200s] 7fbc8fcc9000-7fbc8fcce000 rw-p 00000000 00:00 0 [ 200s] 7fbc8fcd5000-7fbc8fcf6000 r-xp 00000000 08:00 131343 /usr/lib64/ld-2.17.so [ 200s] 7fbc8fef1000-7fbc8fef5000 rw-p 00000000 00:00 0 [ 200s] 7fbc8fef5000-7fbc8fef6000 r--p 00020000 08:00 131343 /usr/lib64/ld-2.17.so [ 200s] 7fbc8fef6000-7fbc8fef7000 rw-p 00021000 08:00 131343 /usr/lib64/ld-2.17.so [ 200s] 7fbc8fef7000-7fbc8fef9000 rw-p 00000000 00:00 0 [ 200s] 7ffe9b7e3000-7ffe9b806000 rw-p 00000000 00:00 0 [stack] [ 200s] 7ffe9b84d000-7ffe9b84f000 r--p 00000000 00:00 0 [vvar] [ 200s] 7ffe9b84f000-7ffe9b851000 r-xp 00000000 00:00 0 [vdso] [ 200s] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] [ 200s] ./init.sh: line 53: 15162 Aborted "$@" [ 200s] + rc=134 [ 200s] + '[' 134 -eq 77 ']' [ 200s] + fail_ './ioctl_dm failed with code 134' [ 200s] + warn_ 'ioctl_dm.test: failed test: ./ioctl_dm failed with code 134' [ 200s] + printf '%s\n' 'ioctl_dm.test: failed test: ./ioctl_dm failed with code 134' [ 200s] ioctl_dm.test: failed test: ./ioctl_dm failed with code 134 [ 200s] + exit 1
It is due the fact that message field is 0-element array. Worked around by copying to string field with appropriate offset.
--- tests/ioctl_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tests/ioctl_dm.c +2 -1
@@ -64,7 +64,8 @@ main(void)init_s (); s.u.tm.target_msg.sector =0x1234 ; -strcpy (s.u.tm.target_msg.message,"tmsg" ); +strcpy (s.u.string + offsetof(struct dm_target_msg , message), +"tmsg" );ioctl (-1 ,DM_TARGET_MSG , &s);printf ("ioctl(-1, DM_TARGET_MSG, " "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", "
Signature · 10 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Strace-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/strace-devel
PATCH 4/21 dm: Minor output tweaks
In reply to a message not in the archiveTrying 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(-)
dm.c +13 -8
@@ -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, &ioc);dm_decode_values (tcp, code, &ioc);dm_decode_flags (&ioc); -if (!abbrev (tcp)) +if (abbrev (tcp)) +tprints (", ..." ); +else switch (code) {case DM_DEV_WAIT :case DM_TABLE_STATUS :
tests/ioctl_dm.c +1 -1
@@ -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");
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 5/21 xlat: Add values for dm_flags
In reply to a message not in the archiveOtherwise 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 <linux/dm-ioctl.h>).
--- xlat/dm_flags.in | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
xlat/dm_flags.in +18 -18
@@ -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 0x00000004 -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)
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 6/21 dm: Some future-proofing by means of compile-time DM_VERSION_MAJOR check
In reply to a message not in the archive* 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(-)
dm.c +12 -1
@@ -5,6 +5,8 @@# include <sys/ioctl.h> # include <linux/dm-ioctl.h> +# 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 */
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 7/21 dm: Add definitions for ioctl commands not implemented initially
In reply to a message not in the archivedm.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(+)
dm.c +13 -0
@@ -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) {
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 8/21 dm: Use static constants for offset sizes
In reply to a message not in the archiveThis may improve readability an leads to more compact code.
--- dm.c | 58 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 27 deletions(-)
dm.c +31 -27
@@ -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 + s->next; }else {
@@ -207,26 +210,25 @@ static void dm_decode_dm_target_versions(const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) { + static const uint32_t target_vers_name_offs = + offsetof(struct dm_target_versions , name);uint32_t offset = ioc->data_start;while (1 ) { -if (offset + (uint32_t ) offsetof(struct dm_target_versions , name) >= - offset && - offset + (uint32_t ) offsetof(struct dm_target_versions , name) < - extra_size) { +if (offset + target_vers_name_offs >= offset && + offset + target_vers_name_offs < extra_size) {const struct dm_target_versions *s = (const struct dm_target_versions *)(extra + offset);tprints (", {name=" );print_quoted_string (s->name, extra_size - (offset + - offsetof(struct dm_target_versions , - name)),QUOTE_0_TERMINATED ); + target_vers_name_offs), +QUOTE_0_TERMINATED );tprintf (", version=%" PRIu32".%" PRIu32".%" PRIu32"}" , s->version[0 ], s->version[1 ], s->version[2 ]);if (!s->next)break ; -if (offset + s->next <= offset + - (uint32_t ) offsetof(struct dm_target_versions , name)) +if (offset + s->next <= offset + target_vers_name_offs) goto misplaced; offset = offset + s->next; }else {
@@ -242,17 +244,19 @@ static void dm_decode_dm_target_msg(const struct dm_ioctl *ioc, const char *extra, uint32_t extra_size) { + static const uint32_t target_msg_message_offs = + offsetof(struct dm_target_msg , message);uint32_t offset = ioc->data_start; -if (offset + (uint32_t ) offsetof(struct dm_target_msg , message) >= offset && - offset + (uint32_t ) offsetof(struct dm_target_msg , message) < extra_size) { +if (offset + target_msg_message_offs >= offset && + offset + target_msg_message_offs < extra_size) {const struct dm_target_msg *s = (const struct dm_target_msg *) (extra + offset);tprintf (", {sector=%" PRIu64", message=" , (uint64_t ) s->sector);print_quoted_string (s->message, extra_size - - offsetof(struct dm_target_msg , message), + target_msg_message_offs,QUOTE_0_TERMINATED );tprints ("}" ); }else {
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 9/21 dm: Remove char * cast
In reply to a message not in the archive--- dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
dm.c +1 -1
@@ -286,7 +286,7 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)char *extra =NULL ;uint32_t extra_size =0 ; -if (umoven (tcp, arg,sizeof (ioc) -sizeof (ioc.data), (char *) &ioc) <0 ) +if (umoven (tcp, arg,sizeof (ioc) -sizeof (ioc.data), &ioc) <0 )return 0 ;tprintf (", {version=%d.%d.%d" , ioc.version[0 ], ioc.version[1 ], ioc.version[2 ]);
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 10/21 dm: use => instead of , for splitting output structure from input
In reply to a message not in the archive--- dm.c | 4 ++-- tests/ioctl_dm.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-)
dm.c +2 -2
@@ -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), &ioc) <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
tests/ioctl_dm.c +6 -6
@@ -42,7 +42,7 @@ main(void)ioctl (-1 ,DM_VERSION , &s);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 , &s);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 , &s);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 , &s);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");
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 11/21 dm: Compare entering field values with exiting ones
In reply to a message not in the archive--- dm.c | 74 ++++++++++++++++++++++++++++++++++++++++-------------- tests/ioctl_dm.c | 26 +++++++------------ 2 files changed, 64 insertions(+), 36 deletions(-)
dm.c +55 -19
@@ -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), &ioc) <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, &ioc); -dm_decode_values (tcp, code, &ioc); -dm_decode_flags (&ioc); +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, &ioc, 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, &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 ; -dm_decode_dm_target_deps (&ioc, 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 (&ioc, 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 (&ioc, extra, extra_size); +dm_decode_dm_target_versions (ioc, extra, extra_size);break ;case DM_TARGET_MSG :if (entering (tcp)) { -dm_decode_dm_target_msg (&ioc, extra, +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); + ioc->flags &DM_DATA_OUT_FLAG ) { +dm_decode_string (ioc, extra, extra_size); }break ;case DM_DEV_RENAME :case DM_DEV_SET_GEOMETRY :if (!entering (tcp))break ; -dm_decode_string (&ioc, extra, extra_size); +dm_decode_string (ioc, extra, extra_size);break ; }
@@ -365,6 +399,8 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)tprints ("}" );if (extra)free (extra); +if (exiting (tcp)) +free (ioc);return 1 ; }
tests/ioctl_dm.c +9 -17
@@ -42,8 +42,6 @@ main(void)ioctl (-1 ,DM_VERSION , &s);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 ();
@@ -58,9 +56,8 @@ 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\"}} => " -"{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " -"uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n" ); +"length=32, target_type=\"tgt\", string=\"tparams\"}}) = " +"-1 EBADF (%m)\n" );init_s (); s.u.tm.target_msg.sector =0x1234 ;
@@ -69,27 +66,24 @@ main(void)ioctl (-1 ,DM_TARGET_MSG , &s);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" ); +"uuid=\"uuu\", flags=0, {sector=4660, message=\"tmsg\"}}) = " +"-1 EBADF (%m)\n" );init_s ();strcpy (s.u.string,"10 20 30 40" );ioctl (-1 ,DM_DEV_SET_GEOMETRY , &s);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" ); +"uuid=\"uuu\", flags=0, string=\"10 20 30 40\"}) = " +"-1 EBADF (%m)\n" );init_s ();strcpy (s.u.string,"new-name" );ioctl (-1 ,DM_DEV_RENAME , &s);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" ); +"uuid=\"uuu\", event_nr=0, flags=0, string=\"new-name\"}) = " +"-1 EBADF (%m)\n" );init_s (); s.ioc.target_count =-1U ;
@@ -98,9 +92,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 */ ...} => " -"{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", " - "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n"); + "/* misplaced struct dm_target_spec */ ...}) = -1 EBADF (%m)\n");puts ("+++ exited with 0 +++" );return 0 ;
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 12/21 dm: Add inttypes.h, include reorder
In reply to a message not in the archiveBuild failed otherwise on RHEL 5.
--- dm.c | 3 ++- tests/ioctl_dm.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
dm.c +2 -1
@@ -2,8 +2,9 @@#ifdef HAVE_LINUX_DM_IOCTL_H -# include <sys/ioctl.h> +# include <inttypes.h> # include <linux/dm-ioctl.h> +# include <sys/ioctl.h> # if DM_VERSION_MAJOR ==4
tests/ioctl_dm.c +1 -0
@@ -1,4 +1,5 @@#include "tests.h" +#include <inttypes.h> #include <stdio.h> #include <stddef.h> #include <string.h>
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 13/21 dm: Move printing of dm_ioctl fields before allocation of extra data
In reply to a message not in the archive--- dm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
dm.c +4 -3
@@ -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
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 14/21 dm: replace abbrev branching with goto
In reply to a message not in the archive--- dm.c | 78 ++++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 38 deletions(-)
dm.c +40 -38
@@ -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 ("}" );
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 15/21 dm: Additional data_size/data_start checks
In reply to a message not in the archive--- dm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
dm.c +7 -1
@@ -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);
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 16/21 dm: Add comment regarding intended fall-through in switch statement
In reply to a message not in the archive--- dm.c | 1 + 1 file changed, 1 insertion(+)
dm.c +1 -0
@@ -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 :
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 17/21 dm: Add data_size and data_offset fields to output
In reply to a message not in the archive--- dm.c | 4 +++- tests/ioctl_dm.c | 41 ++++++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 18 deletions(-)
dm.c +3 -1
@@ -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;
tests/ioctl_dm.c +24 -17
76 lines not on this page · raw message
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 18/21 tests/ioctl_dm: Allow passing size and data_start to init_s
In reply to a message not in the archive--- tests/ioctl_dm.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-)
tests/ioctl_dm.c +16 -18
@@ -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 (&s,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 (&s.ioc,sizeof (s.ioc),0 );ioctl (-1 ,DM_VERSION , &s);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 (&s.ioc,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 (&s.ioc,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 (&s.ioc,sizeof (s), offsetof(struct s , u));strcpy (s.u.string,"10 20 30 40" );ioctl (-1 ,DM_DEV_SET_GEOMETRY , &s); 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 (&s.ioc,sizeof (s), offsetof(struct s , u));strcpy (s.u.string,"new-name" );ioctl (-1 ,DM_DEV_RENAME , &s); 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 (&s.ioc,sizeof (s), offsetof(struct s , u)); s.ioc.target_count =-1U ;ioctl (-1 ,DM_TABLE_LOAD , &s); printf("ioctl(-1, DM_TABLE_LOAD, "
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 19/21 dm: Add check whether command uses parameters
In reply to a message not in the archive--- dm.c | 25 ++++++++++++++++++++++--- tests/ioctl_dm.c | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-)
dm.c +22 -3
@@ -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;
tests/ioctl_dm.c +1 -1
@@ -40,7 +40,7 @@ main(void)init_s (&s.ioc,sizeof (s.ioc),0 );ioctl (-1 ,DM_VERSION , &s);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));
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 20/21 dm: Fix printing of version field
In reply to a message not in the archive--- dm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
dm.c +5 -1
@@ -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
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 21/21 dm: rewrite structure decoding
In reply to a message not in the archiveRewrite 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(-)
dm.c +217 -146
@@ -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, &s)) +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_ioctl *ioc) {static const uint32_t target_deps_dev_offs = offsetof(struct dm_target_deps , dev); +uint64_t dev_buf; +struct dm_target_deps s;uint32_t offset = ioc->data_start; +uint32_t space; -if (offset + target_deps_dev_offs >= offset && - offset + target_deps_dev_offs <= extra_size) { -uint32_t i; -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); - -if (s->count > space) - goto misplaced; -tprints (", deps={" ); -for (i =0 ; i < s->count; i++) { -tprintf ("%smakedev(%u, %u)" , i ?", " :"" , -major (s->dev[i]),minor (s->dev[i])); - } -tprints ("}" ); - }else { - misplaced: -tprints (", /* misplaced struct dm_target_deps */ ..." ); +if (abbrev (tcp)) { +tprints (", ..." ); +return ; } + +tprints (", " ); + +if (offset + target_deps_dev_offs <= offset || + offset + target_deps_dev_offs > ioc->data_size) + goto misplaced; + +if (umove_or_printaddr (tcp, addr + offset, &s)) +return ; + + space = (ioc->data_size - offset - target_deps_dev_offs) /sizeof (__u64); + +if (s.count > space) + goto misplaced; + +tprintf ("{count=%u, deps=" , s.count); + +print_array (tcp, addr + offset + target_deps_dev_offs, s.count, + &dev_buf,sizeof (dev_buf), umoven_or_printaddr, + dm_print_dev,NULL ); + +tprints ("}" ); + +return ; + +misplaced: +tprints ("/* misplaced struct dm_target_deps */ ..." ); }static void -dm_decode_dm_name_list (const struct dm_ioctl *ioc,const char *extra, -uint32_t extra_size) +dm_decode_dm_name_list (struct tcb *tcp,unsigned long addr, +const struct dm_ioctl *ioc) {static const uint32_t name_list_name_offs = offsetof(struct dm_name_list , name); +struct dm_name_list s;uint32_t offset = ioc->data_start; +uint32_t count; -while (1 ) { -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); +if (abbrev (tcp)) { +tprints (", ..." ); +return ; + } -if (!s->dev) -break ; -tprintf (", {dev=makedev(%u, %u), name=" ,major (s->dev), -minor (s->dev)); -print_quoted_string (s->name, extra_size - (offset + - name_list_name_offs), -QUOTE_0_TERMINATED ); -tprints ("}" ); -if (!s->next) -break ; -if (offset + s->next <= offset + name_list_name_offs) - goto misplaced; - offset = offset + s->next; - }else { - misplaced: -tprints (", /* misplaced struct dm_name_list */ ..." ); +for (count =0 ;; count++) { +if (offset + name_list_name_offs <= offset || + offset + name_list_name_offs > ioc->data_size) + goto misplaced; + +tprints (", " ); + +if (count >= max_strlen) { +tprints ("..." ); +break ; + } + +if (umove_or_printaddr (tcp, addr + offset, &s)) +break ; +if (!count && !s.dev) { +tprints ("/* no devices present */" );break ; } + +tprintf ("{dev=makedev(%u, %u), name=" ,major (s.dev), +minor (s.dev)); +printstr_ex (tcp, addr + offset + name_list_name_offs, + ioc->data_size - (offset + name_list_name_offs), +QUOTE_0_TERMINATED ); +tprints ("}" ); + +if (!s.next) +break ; +if (offset + s.next <= offset + name_list_name_offs) + goto misplaced; + offset = offset + s.next; } + +return ; + +misplaced: +tprints (", /* misplaced struct dm_name_list */ ..." ); }static void -dm_decode_dm_target_versions (const struct dm_ioctl *ioc,const char *extra, -uint32_t extra_size) +dm_decode_dm_target_versions (struct tcb *tcp,unsigned long addr, +const struct dm_ioctl *ioc) {static const uint32_t target_vers_name_offs = offsetof(struct dm_target_versions , name); +struct dm_target_versions s;uint32_t offset = ioc->data_start; +uint32_t count; -while (1 ) { -if (offset + target_vers_name_offs >= offset && - offset + target_vers_name_offs < extra_size) { -const struct dm_target_versions *s = - (const struct dm_target_versions *)(extra + offset); +if (abbrev (tcp)) { +tprints (", ..." ); +return ; + } -tprints (", {name=" ); -print_quoted_string (s->name, extra_size - (offset + - target_vers_name_offs), -QUOTE_0_TERMINATED ); -tprintf (", version=%" PRIu32".%" PRIu32".%" PRIu32"}" , - s->version[0 ], s->version[1 ], s->version[2 ]); -if (!s->next) -break ; -if (offset + s->next <= offset + target_vers_name_offs) - goto misplaced; - offset = offset + s->next; - }else { - misplaced: -tprints (", /* misplaced struct dm_target_versions */ " -"..." ); +for (count =0 ;; count++) { +if (offset + target_vers_name_offs <= offset || + offset + target_vers_name_offs > ioc->data_size) + goto misplaced; + +tprints (", " ); + +if (count >= max_strlen) { +tprints ("..." );break ; } + +if (umove_or_printaddr (tcp, addr + offset, &s)) +break ; + +tprints ("{name=" ); +printstr_ex (tcp, addr + offset + target_vers_name_offs, + ioc->data_size - (offset + target_vers_name_offs), +QUOTE_0_TERMINATED ); +tprintf (", version=%" PRIu32".%" PRIu32".%" PRIu32"}" , + s.version[0 ], s.version[1 ], s.version[2 ]); + +if (!s.next) +break ; +if (offset + s.next <= offset + target_vers_name_offs) + goto misplaced; + offset = offset + s.next; } + +return ; + +misplaced: +tprints (", /* misplaced struct dm_target_versions */ ..." ); }static void -dm_decode_dm_target_msg (const struct dm_ioctl *ioc,const char *extra, -uint32_t extra_size) +dm_decode_dm_target_msg (struct tcb *tcp,unsigned long addr, +const struct dm_ioctl *ioc) {static const uint32_t target_msg_message_offs = offsetof(struct dm_target_msg , message);uint32_t offset = ioc->data_start; -if (offset + target_msg_message_offs >= offset && - offset + target_msg_message_offs < extra_size) { -const struct dm_target_msg *s = - (const struct dm_target_msg *) (extra + offset); +if (abbrev (tcp)) { +tprints (", ..." ); +return ; + } + +if (offset + target_msg_message_offs > offset && + offset + target_msg_message_offs <= ioc->data_size) { +struct dm_target_msg s; -tprintf (", {sector=%" PRIu64", message=" , - (uint64_t ) s->sector); -print_quoted_string (s->message, extra_size - - target_msg_message_offs, -QUOTE_0_TERMINATED ); +if (umove_or_printaddr (tcp, addr + offset, &s)) +return ; + +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 );tprints ("}" ); }else {tprints (", /* misplaced struct dm_target_msg */" );
@@ -267,15 +356,20 @@ dm_decode_dm_target_msg(const struct dm_ioctl *ioc, const char *extra, }static void -dm_decode_string (const struct dm_ioctl *ioc,const char *extra, -uint32_t extra_size) +dm_decode_string (struct tcb *tcp,unsigned long addr, +const struct dm_ioctl *ioc) {uint32_t offset = ioc->data_start; -if (offset < extra_size) { +if (abbrev (tcp)) { +tprints (", ..." ); +return ; + } + +if (offset < ioc->data_size) {tprints (", string=" ); -print_quoted_string (extra + offset, extra_size - offset, -QUOTE_0_TERMINATED ); +printstr_ex (tcp, addr + offset, ioc->data_size - offset, +QUOTE_0_TERMINATED ); }else {tprints (", /* misplaced string */" ); }
@@ -301,11 +395,9 @@ dm_ioctl_has_params(const unsigned int code)static int dm_known_ioctl (struct tcb *tcp,const unsigned int code,long arg) { -struct dm_ioctl *ioc; +struct dm_ioctl *ioc =NULL ;struct dm_ioctl *entering_ioc =NULL ;bool ioc_changed = false; -char *extra =NULL ; -uint32_t extra_size =0 ; ioc =malloc (sizeof (* ioc));if (!ioc)
@@ -371,70 +463,49 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)dm_decode_values (tcp, code, ioc);dm_decode_flags (ioc); -if (dm_ioctl_has_params (code) && (ioc->data_size >sizeof (ioc))) { - extra =malloc (ioc->data_size); -if (extra) { - extra_size = ioc->data_size; -if (umoven (tcp, arg, extra_size, extra) <0 ) { -free (extra); - extra =NULL ; - extra_size =0 ; - } - } - } - -if (abbrev (tcp)) { -tprints (", ..." ); - goto skip; - } -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); +dm_decode_dm_target_spec (tcp, arg, ioc);break ;case DM_TABLE_LOAD :if (!entering (tcp))break ; -dm_decode_dm_target_spec (tcp, ioc, extra, extra_size); +dm_decode_dm_target_spec (tcp, arg, ioc);break ;case DM_TABLE_DEPS :if (entering (tcp) ||syserror (tcp))break ; -dm_decode_dm_target_deps (ioc, extra, extra_size); +dm_decode_dm_target_deps (tcp, arg, ioc);break ;case DM_LIST_DEVICES :if (entering (tcp) ||syserror (tcp))break ; -dm_decode_dm_name_list (ioc, extra, extra_size); +dm_decode_dm_name_list (tcp, arg, ioc);break ;case DM_LIST_VERSIONS :if (entering (tcp) ||syserror (tcp))break ; -dm_decode_dm_target_versions (ioc, extra, extra_size); +dm_decode_dm_target_versions (tcp, arg, ioc);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); - } +if (entering (tcp)) +dm_decode_dm_target_msg (tcp, arg, ioc); +else if (!syserror (tcp) && ioc->flags &DM_DATA_OUT_FLAG ) +dm_decode_string (tcp, arg, ioc);break ;case DM_DEV_RENAME :case DM_DEV_SET_GEOMETRY :if (!entering (tcp))break ; -dm_decode_string (ioc, extra, extra_size); +dm_decode_string (tcp, arg, ioc);break ; } skip:tprints ("}" ); -if (extra) -free (extra);if (exiting (tcp))free (ioc);return 1 ;
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Quoted 27 lines · Masatake YAMATO
I tested the patch and it works fine.
Could you add following patch if you approve?commit
bae7528fa92283726caac1ec7a6c306274f8899dAuthor: Masatake YAMATO <[email protected]> Date: Mon Aug 22 17:44:55 2016 +0900dm-ioctl: add a lvm private flag
When I run "dmsetup ls" under dm-ioctl patched strace, "strange
DM_???" are found in its output.# ./strace -e ioctl dmsetup ls >
/dev/null
ioctl(3,DM_VERSION, {version=4.0.0, flags=0x4 /*DM_??? */}, ... ioctl(3,DM_LIST_DEVICES, {version=4.0.0, flags=0x4 /*DM_??? */}, ...
...Associated definion for
DM_??? is in lvm2 source tree. This commit imports the definion to dm-ioctl list.Signed-off-by Masatake YAMATO <[email protected]>xlat/dm_flags.in +0
-0
xlat/dm_flags.in line 7
Quoted 7 lines
xlat/dm_flags.in +2
-0@@ -1,5 +1,7 @@ DM_READONLY_FLAG DM_SUSPEND_FLAG +/* Defined in lvm2/libdm/ioctl/libdm-iface.c */ +DM_EXISTS_FLAG 0x00000004 DM_PERSISTENT_DEV_FLAG DM_STATUS_TABLE_FLAG DM_ACTIVE_PRESENT_FLAG
OK. This is the patch with the flag DM_EXISTS_FLAG added.
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 | 19 ++ 9 files changed, 474 insertions(+)
Makefile.am +1 -0
@@ -97,6 +97,7 @@ strace_SOURCES = \ desc.c \ dirent.c \ dirent64.c \ + dm.c \ empty.h \ epoll.c \ evdev.c \
configure.ac +1 -0
@@ -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
defs.h +1 -0
@@ -636,6 +636,7 @@ extern void print_struct_statfs64(structextern 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 );
dm.c new file +356 -0
356 lines not on this page · raw message
ioctl.c +4 -0
@@ -282,6 +282,10 @@ ioctl_decode(struct tcb *tcp)case 0x94 :return btrfs_ioctl (tcp, code, arg);#endif +#ifdef HAVE_LINUX_DM_IOCTL_H +case 0xfd : +return dm_ioctl (tcp, code, arg); +#endif default :break ; }
tests/Makefile.am +2 -0
@@ -162,6 +162,7 @@ check_PROGRAMS = \ inet-cmsg \ ioctl \ ioctl_block \ + ioctl_dm \ ioctl_evdev \ ioctl_evdev-v \ ioctl_mtd \
@@ -507,6 +508,7 @@ DECODER_TESTS = \ inet-cmsg.test \ ioctl.test \ ioctl_block.test \ + ioctl_dm.test \ ioctl_evdev.test \ ioctl_evdev-v.test \ ioctl_mtd.test \
tests/ioctl_dm.c new file +78 -0
78 lines not on this page · raw message
tests/ioctl_dm.test new file +12 -0
@@ -0,0 +1,12 @@ +#!/bin/sh + +# Check decoding of DM* ioctls. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +run_strace -a16 -veioctl $args > "$EXP" +check_prog grep +grep -v '^ioctl([012],' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" +rm -f "$EXP" "$OUT"
xlat/dm_flags.in new file +19 -0
@@ -0,0 +1,19 @@ +DM_READONLY_FLAG +DM_SUSPEND_FLAG +/* Defined in lvm2/libdm/ioctl/libdm-iface.c */ +DM_EXISTS_FLAG 0x00000004 +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
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
cover Additional checks for strace DM ioctl decoder test
In reply to a message not in the archiveHello.
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
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 1/1 device mapper ioctl
Quoted 9 lines · Eugene Syromyatnikov
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 whendm_target_msgstructure is inaccessible").
* Update ofprintstr_excall, which enables proper handling ofQUOTE_0_TERMINATEDuser style (it prints cropped string without ellipsis otherwise).
Hi
Here I'm sending the device mapper ioctl patch with these changes merged.
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.
Mikulas
Makefile.am | 1 configure.ac | 1 defs.h | 1 dm.c | 552 ++++++++++++++++++++++++++++++++++++++ ioctl.c | 4 tests/.gitignore | 2 tests/Makefile.am | 4 tests/ioctl_dm-v.c | 2 tests/ioctl_dm-v.test | 12 tests/ioctl_dm.c | 726 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/ioctl_dm.test | 12 util.c | 18 + xlat/dm_flags.in | 19 + 13 files changed, 1351 insertions(+), 3 deletions(-)
Makefile.am +1 -0
@@ -97,6 +97,7 @@ strace_SOURCES = \ desc.c \ dirent.c \ dirent64.c \ + dm.c \ empty.h \ epoll.c \ evdev.c \
configure.ac +1 -0
@@ -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
defs.h +1 -0
@@ -636,6 +636,7 @@ extern void print_struct_statfs64(structextern 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 );
dm.c new file +552 -0
552 lines not on this page · raw message
ioctl.c +4 -0
@@ -282,6 +282,10 @@ ioctl_decode(struct tcb *tcp)case 0x94 :return btrfs_ioctl (tcp, code, arg);#endif +#ifdef HAVE_LINUX_DM_IOCTL_H +case 0xfd : +return dm_ioctl (tcp, code, arg); +#endif default :break ; }
tests/Makefile.am +4 -0
@@ -162,6 +162,8 @@ check_PROGRAMS = \ inet-cmsg \ ioctl \ ioctl_block \ + ioctl_dm \ + ioctl_dm-v \ ioctl_evdev \ ioctl_evdev-v \ ioctl_mtd \
@@ -507,6 +509,8 @@ DECODER_TESTS = \ inet-cmsg.test \ ioctl.test \ ioctl_block.test \ + ioctl_dm.test \ + ioctl_dm-v.test \ ioctl_evdev.test \ ioctl_evdev-v.test \ ioctl_mtd.test \
tests/ioctl_dm.c new file +726 -0
726 lines not on this page · raw message
tests/ioctl_dm.test new file +12 -0
@@ -0,0 +1,12 @@ +#!/bin/sh + +# Check decoding of DM* ioctls. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +run_strace -a16 -s9 -eioctl $args > "$EXP" +check_prog grep +grep -v '^ioctl([012],' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" +rm -f "$EXP" "$OUT"
xlat/dm_flags.in new file +19 -0
@@ -0,0 +1,19 @@ +DM_READONLY_FLAG (1 << 0) +DM_SUSPEND_FLAG (1 << 1) +/* Defined in lvm2/libdm/ioctl/libdm-iface.c */ +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)
util.c +15 -3
@@ -820,13 +820,13 @@ printstr_ex(struct tcb *tcp, long addr, outstr =xmalloc (outstr_size); } - size = max_strlen; + size = max_strlen +1 ;if (len ==-1 ) {/* * Treat as a NUL-terminated string: fetch one byte more * because string_quote may look one byte ahead. */ -if (umovestr (tcp, addr, size +1 , str) <0 ) { +if (umovestr (tcp, addr, size, str) <0 ) {printaddr (addr);return ; }
@@ -844,11 +844,23 @@ printstr_ex(struct tcb *tcp, long addr, style |= user_style; +if (style "E_0_TERMINATED ) { +if (size) { + --size; + }else { +tprints ((len ==-1 ) || (len ==0 ) ?"\"\"" :"\"\"..." ); +return ; + } + } +if (size > max_strlen) + size = max_strlen; +/* If string_quote didn't see NUL and (it was supposed to be ASCIZ str * or we were requested to print more than -s NUM chars)... */ ellipsis = (string_quote (str, outstr, size, style) && - (len <0 || (unsigned long ) len > max_strlen)); + ((style "E_0_TERMINATED ) || + (unsigned long ) len > max_strlen));tprints (outstr);if (ellipsis)
tests/.gitignore +2 -0
@@ -103,6 +103,8 @@ getxxid inet-cmsg ioctl ioctl_block +ioctl_dm +ioctl_dm-v ioctl_evdev ioctl_evdev-v ioctl_mtd
tests/ioctl_dm-v.c new file +2 -0
@@ -0,0 +1,2 @@ +#define VERBOSE 1 +#include "ioctl_dm.c"
tests/ioctl_dm-v.test new file +12 -0
@@ -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"
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
A message that is not in the archive (sent off-list or not yet received): alpine.LRH.2.02.1610191626360.628-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/[email protected]
Re: [PATCH] device mapper ioctl
Quoted 4 lines · Mikulas Patocka
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?
Quoted 8 lines
In this piece of code:
tests/ioctl_dm.c new file +4
-0+ 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.
Quoted 1 line
Mikulas
Signature · 10 lines
Eugene "eSyr" Syromyatnikov mailto:[email protected] xmpp:eSyr@jabber.{ru|org} ------------------------------------------------------------------------------ Developer Access Program for Intel Xeon Phi Processors Access to Intel Xeon Phi processor-based developer platforms. With one year of Intel Parallel Studio XE. Training and support from Colfax. Order your platform today. http://sdm.link/xeonphi
A message that is not in the archive (sent off-list or not yet received): CACGkJdts9AKHnXb+b6J2kfpDNZJZW12WaNaYukrA11PHtAydag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Re: [PATCH] device mapper ioctl
Quoted 9 lines
Quoted 2 lines
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?
It works fine on my Fedora 24(x86_64).
"make check" says "PASS" about ioctl_dm.test and ioctl_dm-v.test.
Very useful. Thank you.
Masatake YAMATO
Quoted 9 lines
Quoted 9 lines
In this piece of code:
tests/ioctl_dm.c new file +4
-0+ 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.
Quoted 9 lines
Thank you for noticing, it was an oversight on my part.
Quoted 1 line
Mikulas
Signature · 3 lines
Eugene "eSyr" Syromyatnikov mailto:[email protected] xmpp:eSyr@jabber.{ru|org}
------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors Access to Intel Xeon Phi processor-based developer platforms. With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
PATCH 1/9 util: Add support for QUOTE_0_TERMINATED in user_style to ptrintstr_ex
In reply to a message not in the archiveThis enables printing size-limited (expectedly) ASCIZ strings.
--- util.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
util.c +15 -3
@@ -820,13 +820,13 @@ printstr_ex(struct tcb *tcp, long addr, long len, unsigned int user_style) outstr =xmalloc (outstr_size); } - size = max_strlen; + size = max_strlen +1 ;if (len ==-1 ) {/* * Treat as a NUL-terminated string: fetch one byte more * because string_quote may look one byte ahead. */ -if (umovestr (tcp, addr, size +1 , str) <0 ) { +if (umovestr (tcp, addr, size, str) <0 ) {printaddr (addr);return ; }
@@ -844,11 +844,23 @@ printstr_ex(struct tcb *tcp, long addr, long len, unsigned int user_style) style |= user_style; +if (style "E_0_TERMINATED ) { +if (size) { + --size; + }else { +tprints ((len ==-1 ) || (len ==0 ) ?"\"\"" :"\"\"..." ); +return ; + } + } +if (size > max_strlen) + size = max_strlen; +/* If string_quote didn't see NUL and (it was supposed to be ASCIZ str * or we were requested to print more than -s NUM chars)... */ ellipsis = (string_quote (str, outstr, size, style) && - (len <0 || (unsigned long ) len > max_strlen)); + ((style "E_0_TERMINATED ) || + (unsigned long ) len > max_strlen));tprints (outstr);if (ellipsis)
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 2/9 tests: Add check for printing of overlength strings to ioctl_dm test
In reply to a message not in the archive--- tests/ioctl_dm.c | 2 +- tests/ioctl_dm.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tests/ioctl_dm.c +1 -1
@@ -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 (&s.ioc,sizeof (s), offsetof(struct s , u));
tests/ioctl_dm.test +1 -1
@@ -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"
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 3/9 tests: Add check for presence of HAVE_LINUX_DM_IOCTL_H macro definition to ioctl_dm test
In reply to a message not in the archive--- tests/ioctl_dm.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
tests/ioctl_dm.c +15 -6
@@ -1,10 +1,13 @@#include "tests.h" -#include <inttypes.h> -#include <stdio.h> -#include <stddef.h> -#include <string.h> -#include <sys/ioctl.h> -#include <linux/dm-ioctl.h> + +#ifdef HAVE_LINUX_DM_IOCTL_H + +# include <inttypes.h> +# include <stdio.h> +# include <stddef.h> +# include <string.h> +# include <sys/ioctl.h> +# include <linux/dm-ioctl.h> static struct s { struct dm_ioctl ioc;
@@ -103,3 +106,9 @@ main(void)puts ("+++ exited with 0 +++" );return 0 ; } + +#else /* !HAVE_LINUX_DM_IOCTL_H */ + +SKIP_MAIN_UNDEFINED("HAVE_LINUX_DM_IOCTL_H") + +#endif /* HAVE_LINUX_DM_IOCTL_H */
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 4/9 tests/ioctl_dm: whitespace
In reply to a message not in the archive--- tests/ioctl_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tests/ioctl_dm.c +2 -1
@@ -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 ;
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 5/9 dm: Fix comma printing for the case when dm_target_msg structure is inaccessible
In reply to a message not in the archive--- dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
dm.c +3 -1
@@ -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, &s))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 );
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 6/9 tests/ioctl_dm: overly long string printing checks
In reply to a message not in the archive--- tests/ioctl_dm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tests/ioctl_dm.c +4 -4
@@ -67,12 +67,12 @@ main(void)init_s (&s.ioc,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 , &s);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 (&s.ioc,sizeof (s), offsetof(struct s , u));
@@ -85,12 +85,12 @@ main(void) s.ioc.data_size, s.ioc.data_start);init_s (&s.ioc,sizeof (s), offsetof(struct s , u)); -strcpy (s.u.string,"new-name" ); +strcpy (s.u.string,"new long name" );ioctl (-1 ,DM_DEV_RENAME , &s);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 (&s.ioc,sizeof (s), offsetof(struct s , u));
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 7/9 tests: Some additional checks for ioctl_dm test
In reply to a message not in the archive--- tests/ioctl_dm.c | 505 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 505 insertions(+)
tests/ioctl_dm.c +505 -0
@@ -2,13 +2,26 @@ #ifdef HAVE_LINUX_DM_IOCTL_H +# include <errno.h> # include <inttypes.h> +# include <stdbool.h> # include <stdio.h> # include <stddef.h> # include <string.h> # include <sys/ioctl.h> # include <linux/dm-ioctl.h> +# 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) 0x100000001ULL; +static const __u64 dts_length_base = (__u64) 0xbadc0dedda7a1057ULL; +static const __u64 dts_length_step = (__u64) 0x700000007ULL; +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 ); + +/* Incorrect data_size */ +init_s (dm_arg,0 ,0 ); +ioctl (-1 ,DM_VERSION , &s); +printf ("ioctl(-1, DM_VERSION, %p) = -1 EBADF (%m)\n" , &s); + +/* Incorrect version */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0 ); + dm_arg->version[0 ] =0xbadc0ded ; + dm_arg->version[1 ] =0xbadc0dee ; + dm_arg->version[2 ] =0xbadc0def ; +ioctl (-1 ,DM_VERSION , dm_arg); +printf ("ioctl(-1, DM_VERSION, {version=%u.%u.%u, " +"/* Unsupported device mapper ABI version */ ...}) = " +"-1 EBADF (%m)\n" ,0xbadc0ded ,0xbadc0dee ,0xbadc0def ); + +/* Incorrect data_size */ +init_s (dm_arg,14 ,64 ); +ioctl (-1 ,DM_VERSION , dm_arg); +printf ("ioctl(-1, DM_VERSION, {version=4.1.2, data_size=14, " +"/* Incorrect data_size */ ...}) = -1 EBADF (%m)\n" ); + +/* Unterminated name/uuid */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0 ); +strncpy (dm_arg->name, str129,sizeof (dm_arg->name)); +strncpy (dm_arg->uuid, str129,sizeof (dm_arg->uuid)); +ioctl (-1 ,DM_VERSION , dm_arg); +printf ("ioctl(-1, DM_VERSION, {version=4.1.2, data_size=%zu, " +"dev=makedev(18, 52), name=\"%.127s\", uuid=\"%.128s\", " +"flags=0}) = -1 EBADF (%m)\n" , +sizeof (*dm_arg) -sizeof (dm_arg->data), str129, str129); + +/* Normal call */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0 ); +ioctl (-1 ,DM_VERSION , dm_arg); +printf ("ioctl(-1, DM_VERSION, " +"{version=4.1.2, data_size=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = " +"-1 EBADF (%m)\n" ,sizeof (*dm_arg) -sizeof (dm_arg->data)); + +/* Zero dev, name, uuid */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0 ); + dm_arg->data_size =0xfacefeed ; + dm_arg->dev =0 ; + dm_arg->name[0 ] ='\0' ; + dm_arg->uuid[0 ] ='\0' ; +ioctl (-1 ,DM_VERSION , dm_arg); +printf ("ioctl(-1, DM_VERSION, " +"{version=4.1.2, data_size=%u, flags=0}) = " +"-1 EBADF (%m)\n" ,0xfacefeed ); + +/* Flag */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0 ); + dm_arg->flags =0xffffffff ; +ioctl (-1 ,DM_VERSION , dm_arg); +printf ("ioctl(-1, DM_VERSION, " +"{version=4.1.2, data_size=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=" +"DM_READONLY_FLAG|DM_SUSPEND_FLAG|DM_EXISTS_FLAG|" +"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|" +"0xfff80080}) = -1 EBADF (%m)\n" , +sizeof (*dm_arg) -sizeof (dm_arg->data)); + +/* Normal call */ init_s (&s.ioc,sizeof (s.ioc),0 );ioctl (-1 ,DM_VERSION , &s); printf("ioctl(-1, DM_VERSION, "
@@ -48,6 +236,61 @@ main(void)"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = " "-1 EBADF (%m)\n", sizeof(s.ioc)); + +/* DM_REMOVE_ALL */ +/* DM_LIST_DEVICES */ +/* DM_LIST_VERSIONS */ +for (i =0 ; i <ARRAY_SIZE (dummy_check_cmds_nodev); i++) { +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0 ); +ioctl (-1 , dummy_check_cmds_nodev[i].arg, dm_arg); +printf ("ioctl(-1, %s, {version=4.1.2, data_size=%zu%s, " +"flags=0}) = -1 EBADF (%m)\n" , + dummy_check_cmds_nodev[i].str, +sizeof (*dm_arg) -sizeof (dm_arg->data), + dummy_check_cmds_nodev[i].has_params ? +", data_start=0" :"" ); + } + + +/* DM_DEV_CREATE */ +/* DM_DEV_REMOVE */ +/* DM_DEV_STATUS */ +/* DM_DEV_WAIT */ +/* DM_TABLE_CLEAR */ +/* DM_TABLE_DEPS */ +/* DM_TABLE_STATUS */ +for (i =0 ; i <ARRAY_SIZE (dummy_check_cmds); i++) { +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0 ); +ioctl (-1 , dummy_check_cmds[i].arg, dm_arg); +printf ("ioctl(-1, %s, {version=4.1.2, data_size=%zu%s, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\"%s, " +"flags=0}) = -1 EBADF (%m)\n" , dummy_check_cmds[i].str, +sizeof (*dm_arg) -sizeof (dm_arg->data), + dummy_check_cmds[i].has_params ?", data_start=0" :"" , + dummy_check_cmds[i].has_event_nr ?", event_nr=0" :"" ); + } + + +/* DM_DEV_SUSPEND */ +init_s (&s.ioc,sizeof (s.ioc),0 ); + s.ioc.flags =DM_SUSPEND_FLAG ; + s.ioc.event_nr =0xbadc0ded ; +ioctl (-1 ,DM_DEV_SUSPEND , &s); +printf ("ioctl(-1, DM_DEV_SUSPEND, " +"{version=4.1.2, data_size=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", " +"flags=DM_SUSPEND_FLAG}) = -1 EBADF (%m)\n" ,sizeof (s.ioc)); + +init_s (&s.ioc,sizeof (s.ioc),0 ); + s.ioc.event_nr =0xbadc0ded ; +ioctl (-1 ,DM_DEV_SUSPEND , &s); +printf ("ioctl(-1, DM_DEV_SUSPEND, " +"{version=4.1.2, data_size=%zu, dev=makedev(18, 52), " +"name=\"nnn\", uuid=\"uuu\", event_nr=3134983661, " +"flags=0}) = -1 EBADF (%m)\n" ,sizeof (s.ioc)); + + +/* DM_TABLE_LOAD */ init_s (&s.ioc,sizeof (s), offsetof(struct s , u)); s.ioc.target_count =1 ; s.u.ts.target_spec.sector_start =0x10 ;
@@ -64,6 +307,164 @@ main(void)"length=32, target_type=\"tgt\", string=\"tparams\"}}) = " "-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), +sizeof (*dm_arg) -sizeof (dm_arg->data)); + dm_arg->data_size =sizeof (*dm_arg); + dm_arg->target_count =0 ; +ioctl (-1 ,DM_TABLE_LOAD , dm_arg); +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=0, flags=0}) = -1 EBADF (%m)\n" ,sizeof (*dm_arg), +sizeof (*dm_arg) -sizeof (dm_arg->data)); + +/* Invalid data_start */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0xfffffff8 ); + dm_arg->data_size =sizeof (*dm_arg); + dm_arg->target_count =1234 ; +ioctl (-1 ,DM_TABLE_LOAD , dm_arg); +printf ("ioctl(-1, DM_TABLE_LOAD, " +"{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),0xfffffff8 ); + +/* Inaccessible pointer */ +init_s (&dm_arg_open1->ioc, offsetof(struct dm_table_open_test , target1), + offsetof(struct dm_table_open_test , target1)); + dm_arg_open1->ioc.data_size =sizeof (*dm_arg_open1); + dm_arg_open1->ioc.target_count =0xdeaddea1 ; +ioctl (-1 ,DM_TABLE_LOAD , dm_arg_open1); +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)); + +/* Inaccessible string */ +init_s (&dm_arg_open2->ioc, offsetof(struct dm_table_open_test , param1), + offsetof(struct dm_table_open_test , target1)); + dm_arg_open2->ioc.data_size =sizeof (*dm_arg_open2); + dm_arg_open2->ioc.target_count =2 ; +init_dm_target_spec (&dm_arg_open2->target1,7 ); + dm_arg_open2->target1.next = + offsetof(struct dm_table_open_test , target3) - + offsetof(struct dm_table_open_test , target1); +ioctl (-1 ,DM_TABLE_LOAD , dm_arg_open2); + saved_errno = errno; +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=2, flags=0, " , +sizeof (*dm_arg_open2), + offsetof(struct dm_table_open_test , target1)); +print_dm_target_spec (&dm_arg_open2->target1,7 ); + errno = saved_errno; +printf ("%p}, %p}) = -1 EBADF (%m)\n" , + (char *) dm_arg_open2 + + offsetof(struct dm_table_open_test , param1), + (char *) dm_arg_open2 + + offsetof(struct dm_table_open_test , target3)); + +/* Incorrect next */ +init_s (&dm_arg_open3->ioc, offsetof(struct dm_table_open_test , target5), + offsetof(struct dm_table_open_test , target0)); + dm_arg_open3->ioc.target_count =4 ; + +init_dm_target_spec (&dm_arg_open3->target0,9 ); + dm_arg_open3->target0.next = + offsetof(struct dm_table_open_test , target1) - + offsetof(struct dm_table_open_test , target0); + dm_arg_open3->param0[0 ] ='\0' ; + +init_dm_target_spec (&dm_arg_open3->target1,15 ); + dm_arg_open3->target1.next = + offsetof(struct dm_table_open_test , target3) - + offsetof(struct dm_table_open_test , target1); + dm_arg_open3->param1[0 ] ='\377' ; + dm_arg_open3->param1[1 ] ='\0' ; + +init_dm_target_spec (&dm_arg_open3->target3,42 ); + dm_arg_open3->target3.next =0xdeadbeef ; + dm_arg_open3->param3[0 ] ='\1' ; + dm_arg_open3->param3[1 ] ='\2' ; + dm_arg_open3->param1[2 ] ='\0' ; + +ioctl (-1 ,DM_TABLE_LOAD , dm_arg_open3); + saved_errno = errno; +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=4, flags=0, " , + offsetof(struct dm_table_open_test , target5), + offsetof(struct dm_table_open_test , target0)); +print_dm_target_spec (&dm_arg_open3->target0,9 ); +printf ("\"\"}, " ); +print_dm_target_spec (&dm_arg_open3->target1,15 ); +printf ("\"\\377\"}, " ); +print_dm_target_spec (&dm_arg_open3->target1,42 ); + errno = saved_errno; +printf ("\"\\1\\2\"}, /* misplaced struct dm_target_spec */ ...}) = " +"-1 EBADF (%m)\n" ); + +#define FILL_DM_TARGET (id, id_next) \ + do { \ + init_dm_target_spec(&dm_arg_open3->target##id, id); \ + dm_arg_open3->target##id.next = \ + offsetof(struct dm_table_open_test, \ + target##id_next) - \ + offsetof(struct dm_table_open_test, \ + target##id); \ + strncpy(dm_arg_open3->param##id, str129 + id * 2, id); \ + dm_arg_open3->param##id[id] = '\0'; \ + } while (0) +#define PRINT_DM_TARGET (id) \ + do { \ + print_dm_target_spec(&dm_arg_open3->target##id, id); \ + printf("\"%.*s\"}, ", id, str129 + id * 2); \ + } while (0) + +/* max_strlen limit */ +init_s (&dm_arg_open3->ioc, offsetof(struct dm_table_open_test , target9), + offsetof(struct dm_table_open_test , target0)); + dm_arg_open3->ioc.data_size =sizeof (*dm_arg_open3); + dm_arg_open3->ioc.target_count =0xbadc0ded ; +FILL_DM_TARGET (0 ,1 ); +FILL_DM_TARGET (1 ,2 ); +FILL_DM_TARGET (2 ,3 ); +FILL_DM_TARGET (3 ,4 ); +FILL_DM_TARGET (4 ,5 ); +FILL_DM_TARGET (5 ,6 ); +FILL_DM_TARGET (6 ,7 ); +FILL_DM_TARGET (7 ,8 ); +FILL_DM_TARGET (8 ,9 ); +ioctl (-1 ,DM_TABLE_LOAD , dm_arg_open3); + saved_errno = errno; +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=3134983661, flags=0, " , +sizeof (*dm_arg_open3), + offsetof(struct dm_table_open_test , target0)); +PRINT_DM_TARGET (0 ); +PRINT_DM_TARGET (1 ); +PRINT_DM_TARGET (2 ); +PRINT_DM_TARGET (3 ); +PRINT_DM_TARGET (4 ); +PRINT_DM_TARGET (5 ); +PRINT_DM_TARGET (6 ); +PRINT_DM_TARGET (7 ); +PRINT_DM_TARGET (8 ); + errno = saved_errno; +printf ("...}) = -1 EBADF (%m)\n" ); + + +/* DM_TARGET_MSG */ init_s (&s.ioc,sizeof (s), offsetof(struct s , u)); s.u.tm.target_msg.sector =0x1234 ; strcpy(s.u.string + offsetof(struct dm_target_msg, message),
@@ -75,6 +476,71 @@ main(void)"{sector=4660, message=\"long targ\"...}}) = -1 EBADF (%m)\n" , s.ioc.data_size, s.ioc.data_start); +/* Invalid data_start */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data), +sizeof (*dm_arg) -sizeof (dm_arg->data)); + dm_arg->data_size =sizeof (*dm_arg); +ioctl (-1 ,DM_TARGET_MSG , dm_arg); +printf ("ioctl(-1, DM_TARGET_MSG, " +"{version=4.1.2, data_size=%zu, data_start=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, " +"/* misplaced struct dm_target_msg */}) = -1 EBADF (%m)\n" , +sizeof (*dm_arg),sizeof (*dm_arg) -sizeof (dm_arg->data)); + +/* Invalid data_start */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0xffffffff ); + dm_arg->data_size =sizeof (*dm_arg); +ioctl (-1 ,DM_TARGET_MSG , dm_arg); +printf ("ioctl(-1, DM_TARGET_MSG, " +"{version=4.1.2, data_size=%zu, data_start=%u, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, " +"/* misplaced struct dm_target_msg */}) = -1 EBADF (%m)\n" , +sizeof (*dm_arg),0xffffffff ); + +/* Inaccessible pointer */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data),0 ); + dm_arg->data_size =sizeof (*dm_arg) +sizeof (struct dm_target_msg ); + dm_arg->data_start =sizeof (*dm_arg); +ioctl (-1 ,DM_TARGET_MSG , dm_arg); +printf ("ioctl(-1, DM_TARGET_MSG, " +"{version=4.1.2, data_size=%zu, data_start=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, %p}) " +"= -1 EBADF (%m)\n" , +sizeof (*dm_arg) +sizeof (struct dm_target_msg ), +sizeof (*dm_arg), (char *) dm_arg +sizeof (*dm_arg)); + +/* Inaccessible string */ +init_s (&dm_arg_msg->ioc,sizeof (*dm_arg_msg), + offsetof(struct dm_target_msg_test , msg)); + dm_arg_msg->ioc.data_size =sizeof (*dm_arg_msg) +1 ; + dm_arg_msg->msg.sector = (__u64 )0xdeadbeeffacef157ULL ; +ioctl (-1 ,DM_TARGET_MSG , dm_arg_msg); +printf ("ioctl(-1, DM_TARGET_MSG, " +"{version=4.1.2, data_size=%zu, data_start=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, " +"{sector=%" PRI__u64", message=%p}}) " +"= -1 EBADF (%m)\n" , +sizeof (*dm_arg_msg) +1 , + offsetof(struct dm_target_msg_test , msg), + (__u64 )0xdeadbeeffacef157ULL , + (char *) dm_arg_msg + + offsetof(struct dm_target_msg_test, msg.message)); + +/* Zero-sied string */ +init_s (&dm_arg_msg->ioc,sizeof (*dm_arg_msg), + offsetof(struct dm_target_msg_test , msg)); + dm_arg_msg->msg.sector = (__u64 )0xdeadbeeffacef157ULL ; +ioctl (-1 ,DM_TARGET_MSG , dm_arg_msg); +printf ("ioctl(-1, DM_TARGET_MSG, " +"{version=4.1.2, data_size=%zu, data_start=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, " +"{sector=%" PRI__u64", message=\"\"}}) " +"= -1 EBADF (%m)\n" , +sizeof (*dm_arg_msg), offsetof(struct dm_target_msg_test , msg), + (__u64 )0xdeadbeeffacef157ULL ); + + +/* DM_DEV_SET_GEOMETRY */ init_s (&s.ioc,sizeof (s), offsetof(struct s , u));strcpy (s.u.string,"10 20 30 40" );ioctl (-1 ,DM_DEV_SET_GEOMETRY , &s);
@@ -84,6 +550,43 @@ main(void)"string=\"10 20 30 \"...}) = -1 EBADF (%m)\n" , s.ioc.data_size, s.ioc.data_start); + +/* DM_DEV_RENAME */ +/* Inaccessible data */ +init_s (dm_arg,sizeof (*dm_arg) -sizeof (dm_arg->data), +sizeof (*dm_arg) -sizeof (dm_arg->data)); + dm_arg->data_size =sizeof (*dm_arg); +ioctl (-1 ,DM_DEV_RENAME , dm_arg); +printf ("ioctl(-1, DM_DEV_RENAME, " +"{version=4.1.2, data_size=%zu, data_start=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, " +"flags=0, string=%p}) = -1 EBADF (%m)\n" , +sizeof (*dm_arg),sizeof (*dm_arg) -sizeof (dm_arg->data), + (char *) dm_arg +sizeof (*dm_arg) -sizeof (dm_arg->data)); + +/* Incorrect data_start data */ +init_s (&s.ioc,sizeof (s), offsetof(struct s , u)); + s.ioc.data_start =0xdeadbeef ; +ioctl (-1 ,DM_DEV_RENAME , &s); +printf ("ioctl(-1, DM_DEV_RENAME, " +"{version=4.1.2, data_size=%u, data_start=3735928559, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, " +"flags=0, /* misplaced string */}) = -1 EBADF (%m)\n" , + s.ioc.data_size); + +/* Strange but still valid data_start */ +init_s (&s.ioc,sizeof (s), offsetof(struct s , u)); +/* Curiously, this is a valid structure */ + s.ioc.data_start = offsetof(struct dm_ioctl , name) +1 ; +ioctl (-1 ,DM_DEV_RENAME , &s); +printf ("ioctl(-1, DM_DEV_RENAME, " +"{version=4.1.2, data_size=%u, data_start=%zu, " +"dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, " +"flags=0, string=\"nn\"}) = -1 EBADF (%m)\n" , + s.ioc.data_size, + offsetof(struct dm_ioctl , name) +1 ); + +/* Correct data */ init_s (&s.ioc,sizeof (s), offsetof(struct s , u));strcpy (s.u.string,"new long name" );ioctl (-1 ,DM_DEV_RENAME , &s);
@@ -93,6 +596,8 @@ main(void)"flags=0, string=\"new long \"...}) = -1 EBADF (%m)\n" , s.ioc.data_size, s.ioc.data_start); + +/* DM_TABLE_LOAD */ init_s (&s.ioc,sizeof (s), offsetof(struct s , u)); s.ioc.target_count =-1U ;ioctl (-1 ,DM_TABLE_LOAD , &s);
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 8/9 tests: Add ioctl_dm to .gitignore
In reply to a message not in the archive--- tests/.gitignore | 1 + 1 file changed, 1 insertion(+)
tests/.gitignore +1 -0
@@ -103,6 +103,7 @@ getxxid inet-cmsg ioctl ioctl_block +ioctl_dm ioctl_evdev ioctl_evdev-v ioctl_mtd
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
PATCH 9/9 tests: Add checks for abbreviated DM ioctl output
In reply to a message not in the archive--- 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
tests/.gitignore +1 -0
@@ -104,6 +104,7 @@ inet-cmsg ioctl ioctl_block ioctl_dm +ioctl_dm-v ioctl_evdev ioctl_evdev-v ioctl_mtd
tests/Makefile.am +2 -0
@@ -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 \
tests/ioctl_dm-v.c new file +2 -0
@@ -0,0 +1,2 @@ +#define VERBOSE 1 +#include "ioctl_dm.c"
tests/ioctl_dm-v.test new file +12 -0
@@ -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"
tests/ioctl_dm.c +142 -36
332 lines not on this page · raw message
tests/ioctl_dm.test +1 -1
@@ -5,7 +5,7 @@ . "${srcdir=.}/init.sh" run_prog > /dev/null -run_strace -a16 -s9 -veioctl $args > "$EXP" +run_strace -a16 -s9 -eioctl $args > "$EXP" check_prog grep grep -v '^ioctl([012],' < "$LOG" > "$OUT" match_diff "$OUT" "$EXP"
Signature · 6 lines
1.7.10.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
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.
Quoted 619 lines · Mikulas Patocka
Quoted 31 lines · Dmitry V. Levin
dm.c
Quoted 5 lines
dm.c new file +5
-0+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 <sys/ioctl.h> #include <linux/dm-ioctl.h> 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, &s); } $ strace -veioctl ./ioctl_dmQuoted 7 lines
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.
--
ldvHere I'm sending new patch. It fixes the possible loop with
s->nextand 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
===================================================================Makefile.am +1
-0@@ -97,6 +97,7 @@ strace_SOURCES = \ desc.c \ dirent.c \ dirent64.c \ + dm.c \ empty.h \ epoll.c \ evdev.c \Index: strace/configure.ac
===================================================================configure.ac +1
-0@@ -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.hIndex:
strace/defs.h
===================================================================defs.h +1
-0@@ -640,6 +640,7 @@ extern void print_struct_statfs64(structextern 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
===================================================================dm.c new file +356
-0@@ -0,0 +1,356 @@ +#include "defs.h" + +#ifdef HAVE_LINUX_DM_IOCTL_H + +#include <sys/ioctl.h> +#include <linux/dm-ioctl.h> + +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_TABLE_LOAD : +tprintf (", target_count=%" PRIu32"" , + ioc->target_count); +break ; +case DM_DEV_SUSPEND : +if (ioc->flags &DM_SUSPEND_FLAG ) +break ; +case DM_DEV_RENAME : +case DM_DEV_REMOVE : +case DM_DEV_WAIT : +tprintf (", event_nr=%" PRIu32"" , + ioc->event_nr); +break ; + } + }else if (!syserror (tcp)) { +switch (code) { +case DM_DEV_CREATE : +case DM_DEV_RENAME : +case DM_DEV_SUSPEND : +case DM_DEV_STATUS : +case DM_DEV_WAIT : +case DM_TABLE_LOAD : +case DM_TABLE_CLEAR : +case DM_TABLE_DEPS : +case DM_TABLE_STATUS : +case DM_TARGET_MSG : +tprintf (", target_count=%" PRIu32"" , + ioc->target_count); +tprintf (", open_count=%" PRIu32"" , + ioc->open_count); +tprintf (", event_nr=%" PRIu32"" , + ioc->event_nr); +break ; + } + } +} + +#include "xlat/dm_flags.h" + +static void +dm_decode_flags (const struct dm_ioctl *ioc) +{ +tprints (", flags=" ); +printflags (dm_flags, ioc->flags,"DM_???" ); +} + +static void +dm_decode_dm_target_spec (struct tcb *tcp,const struct dm_ioctl *ioc, +const char *extra,uint32_t extra_size) +{ +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) { +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 + +sizeof (struct dm_target_spec )), +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 )) + goto misplaced; + offset = new_offset; + }else { +misplaced: +tprints (", misplaced struct dm_target_spec" ); +break ; + } + } +} + +static void +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) { +uint32_t i; +uint32_t space = (extra_size - (offset + + offsetof(struct dm_target_deps , dev))) /sizeof (__u64); +const struct dm_target_deps *s = + (const struct dm_target_deps *)(extra + offset); +if (s->count > space) + goto misplaced; +tprints (", deps={" ); +for (i =0 ; i < s->count; i++) { +tprintf ("%smakedev(%u, %u)" , i ?", " :"" , +major (s->dev[i]),minor (s->dev[i])); + } +tprints ("}" ); + }else { + misplaced: +tprints (", misplaced struct dm_target_deps" ); + } +} + +static void +dm_decode_dm_name_list (const struct dm_ioctl *ioc,const char *extra, +uint32_t extra_size) +{ +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) { +const struct dm_name_list *s = + (const struct dm_name_list *)(extra + offset); +if (!s->dev) +break ; +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 ); +tprints ("}" ); +if (!s->next) +break ; +if (offset + s->next <= offset + (uint32_t )offsetof(struct dm_name_list , name)) + goto misplaced; + offset = offset + s->next; + }else { + misplaced: +tprints (", misplaced struct dm_name_list" ); +break ; + } + } +} + +static void +dm_decode_dm_target_versions (const struct dm_ioctl *ioc,const char *extra, +uint32_t extra_size) +{ +uint32_t offset = ioc->data_start; +while (1 ) { +if (offset + (uint32_t )offsetof(struct dm_target_versions , name) >= + offset && + offset + (uint32_t )offsetof(struct dm_target_versions , name) < + extra_size) { +const struct dm_target_versions *s = + (const struct dm_target_versions *)(extra + offset); +tprints (", {name=" ); +print_quoted_string (s->name, extra_size - (offset + + offsetof(struct dm_target_versions , + name)),QUOTE_0_TERMINATED ); +tprintf (", version=%" PRIu32".%" PRIu32".%" PRIu32"}" , + s->version[0 ], s->version[1 ], s->version[2 ]); +if (!s->next) +break ; +if (offset + s->next <= offset + (uint32_t )offsetof(struct dm_target_versions , name)) + goto misplaced; + offset = offset + s->next; + }else { + misplaced: +tprints (", misplaced struct dm_target_versions" ); +break ; + } + } +} + +static void +dm_decode_dm_target_msg (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_msg , message) >= offset && + offset + (uint32_t )offsetof(struct dm_target_msg , message) < extra_size) { +const struct dm_target_msg *s = + (const struct dm_target_msg *)(extra + offset); +tprintf (", {sector=%" PRIu64", message=" , (uint64_t )s->sector); +print_quoted_string (s->message, extra_size - + offsetof(struct dm_target_msg , message), +QUOTE_0_TERMINATED ); +tprints ("}" ); + }else { +tprints (", misplaced struct dm_target_msg" ); + } +} + +static void +dm_decode_string (const struct dm_ioctl *ioc,const char *extra, +uint32_t extra_size) +{ +uint32_t offset = ioc->data_start; +if (offset < extra_size) { +tprints (", string=" ); +print_quoted_string (extra + offset, extra_size - offset, +QUOTE_0_TERMINATED ); + }else { +tprints (", misplaced string" ); + } +} + +static int +dm_known_ioctl (struct tcb *tcp,const unsigned int code,long arg) +{ +struct dm_ioctl ioc; +char *extra =NULL ; +uint32_t extra_size =0 ; + +if (umoven (tcp, arg,sizeof (ioc) -sizeof (ioc.data), (char *)&ioc) <0 ) +return 0 ; +tprintf (", {version=%d.%d.%d" , 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 ) + goto skip; + +if (ioc.data_size >sizeof (ioc)) { + extra =malloc (ioc.data_size); +if (extra) { + extra_size = ioc.data_size; +if (umoven (tcp, arg, extra_size, extra) <0 ) { +free (extra); + extra =NULL ; + extra_size =0 ; + } + } + } +dm_decode_device (code, &ioc); +dm_decode_values (tcp, code, &ioc); +dm_decode_flags (&ioc); +if (!abbrev (tcp))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); +break ; +case DM_TABLE_DEPS : +if (entering (tcp) ||syserror (tcp)) +break ; +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 (&ioc, extra, extra_size); +break ; +case DM_LIST_VERSIONS : +if (entering (tcp) ||syserror (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 ; +case DM_DEV_RENAME : +case DM_DEV_SET_GEOMETRY : +if (!entering (tcp)) +break ; +dm_decode_string (&ioc, extra, extra_size); +break ; + } + + skip: +tprints ("}" ); +if (extra) +free (extra); +return 1 ; +} + +int +dm_ioctl (struct tcb *tcp,const unsigned int code,long arg) +{ +switch (code) { +case DM_VERSION : +case DM_REMOVE_ALL : +case DM_LIST_DEVICES : +case DM_DEV_CREATE : +case DM_DEV_REMOVE : +case DM_DEV_RENAME : +case DM_DEV_SUSPEND : +case DM_DEV_STATUS : +case DM_DEV_WAIT : +case DM_TABLE_LOAD : +case DM_TABLE_CLEAR : +case DM_TABLE_DEPS : +case DM_TABLE_STATUS : +case DM_LIST_VERSIONS : +case DM_TARGET_MSG : +case DM_DEV_SET_GEOMETRY : +return dm_known_ioctl (tcp, code, arg); +default : +return 0 ; + } +} + +#endif Index:
strace/ioctl.c
===================================================================ioctl.c +4
-0@@ -282,6 +282,10 @@ ioctl_decode(struct tcb *tcp)case 0x94 :return btrfs_ioctl (tcp, code, arg);#endif +#ifdef HAVE_LINUX_DM_IOCTL_H +case 0xfd : +return dm_ioctl (tcp, code, arg); +#endif default :break ; }Index: strace/tests/Makefile.am
===================================================================tests/Makefile.am +2
-0@@ -161,6 +161,7 @@ check_PROGRAMS = \ inet-cmsg \ ioctl \ ioctl_block \ + ioctl_dm \ ioctl_evdev \ ioctl_evdev-v \ ioctl_mtd \@@ -503,6 +504,7 @@ DECODER_TESTS = \ inet-cmsg.test \ ioctl.test \ ioctl_block.test \ + ioctl_dm.test \ ioctl_evdev.test \ ioctl_evdev-v.test \ ioctl_mtd.test \Index:
strace/tests/ioctl_dm.c
===================================================================tests/ioctl_dm.c new file +78
-0@@ -0,0 +1,78 @@ +#include "tests.h" +#include <stdio.h> +#include <stddef.h> +#include <string.h> +#include <sys/ioctl.h> +#include <linux/dm-ioctl.h> + +static struct s { +struct dm_ioctl ioc; +union { +struct { +struct dm_target_spec target_spec; +char target_params[256 ]; + } ts; +struct { +struct dm_target_msg target_msg; +char target_string[256 ]; + } tm; +char string[256 ]; + } u; +} s; + +static void init_s (void ) +{ +memset (&s,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" ); +} + +int +main (void ) +{ +init_s (); + s.ioc.data_size =sizeof (s.ioc); + s.ioc.data_start =0 ; +ioctl (-1 ,DM_VERSION , &s); +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); +strcpy (s.u.ts.target_spec.target_type,"tgt" ); +strcpy (s.u.ts.target_params,"tparams" ); +ioctl (-1 ,DM_TABLE_LOAD , &s); +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 , &s); +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 , &s); +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 , &s); +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 , &s); +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 +++" ); +return 0 ; +}Index: strace/tests/ioctl_dm.test
===================================================================tests/ioctl_dm.test new file +12
-0@@ -0,0 +1,12 @@ +#!/bin/sh + +# Check decoding of DM* ioctls. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +run_strace -a16 -veioctl $args > "$EXP" +check_prog grep +grep -v '^ioctl([012],' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" +rm -f "$EXP" "$OUT"Index: strace/xlat/dm_flags.in
===================================================================xlat/dm_flags.in new file +17
-1@@ -0,0 +1,17 @@ +DM_READONLY_FLAG +DM_SUSPEND_FLAG +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 ------------------------------------------------------------------------------Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Strace-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel
Signature · 3 lines
Eugene "eSyr" Syromyatnikov mailto:[email protected] xmpp:eSyr@jabber.{ru|org}