All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Re: your dm patch for strace
       [not found]       ` <20160824.233543.198328104871315294.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2016-08-25 12:27         ` Mikulas Patocka
       [not found]           ` <alpine.LRH.2.02.1608250823130.24332-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Mikulas Patocka @ 2016-08-25 12:27 UTC (permalink / raw)
  To: Masatake YAMATO
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f



On Wed, 24 Aug 2016, Masatake YAMATO wrote:

> >> Are you talking about https://sourceforge.net/p/strace/mailman/message/34370586/ ?
> > 
> > Yes.
> > 
> >> 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
===================================================================
--- strace.orig/configure.ac
+++ strace/configure.ac
@@ -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
Index: strace/dm.c
===================================================================
--- /dev/null
+++ strace/dm.c
@@ -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);
+			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;
+		} else {
+			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)
+				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)
+				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
===================================================================
--- strace.orig/ioctl.c
+++ strace/ioctl.c
@@ -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/Makefile.am
===================================================================
--- strace.orig/Makefile.am
+++ strace/Makefile.am
@@ -97,6 +97,7 @@ strace_SOURCES =	\
 	desc.c		\
 	dirent.c	\
 	dirent64.c	\
+	dm.c		\
 	empty.h		\
 	epoll.c		\
 	evdev.c		\
Index: strace/defs.h
===================================================================
--- strace.orig/defs.h
+++ strace/defs.h
@@ -640,6 +640,7 @@ extern void print_struct_statfs64(struct
 
 extern void print_ifindex(unsigned int);
 
+extern int dm_ioctl(struct tcb *, const unsigned int, long);
 extern int file_ioctl(struct tcb *, const unsigned int, long);
 extern int fs_x_ioctl(struct tcb *, const unsigned int, long);
 extern int loop_ioctl(struct tcb *, const unsigned int, long);
Index: strace/xlat/dm_flags.in
===================================================================
--- /dev/null
+++ strace/xlat/dm_flags.in
@@ -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

------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] Re: your dm patch for strace
       [not found]           ` <alpine.LRH.2.02.1608250823130.24332-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
@ 2016-09-12 17:10             ` Dmitry V. Levin
       [not found]               ` <20160912171029.GA5263-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Dmitry V. Levin @ 2016-09-12 17:10 UTC (permalink / raw)
  To: Mikulas Patocka
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 5153 bytes --]

On Thu, Aug 25, 2016 at 08:27:21AM -0400, Mikulas Patocka wrote:
> On Wed, 24 Aug 2016, Masatake YAMATO wrote:
> 
> > >> Are you talking about https://sourceforge.net/p/strace/mailman/message/34370586/ ?
> > > 
> > > Yes.
> > > 
> > >> 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
> ===================================================================
> --- strace.orig/configure.ac
> +++ strace/configure.ac
> @@ -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
> Index: strace/dm.c
> ===================================================================
> --- /dev/null
> +++ strace/dm.c
> @@ -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);
> +			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_dm

btw, this parser lacks tests.  How one can easily verify that it works
correctly?  For example how a test for strace ioctl parser may look like
see tests/ioctl_* files.


-- 
ldv

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 424 bytes --]

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

[-- Attachment #3: Type: text/plain, Size: 195 bytes --]

_______________________________________________
Strace-devel mailing list
Strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/strace-devel

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] Re: your dm patch for strace
       [not found]               ` <20160912171029.GA5263-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
@ 2016-10-02 21:59                 ` Mikulas Patocka
       [not found]                   ` <alpine.LRH.2.02.1610021751280.29417-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
  2016-10-08 17:45                   ` [PATCH] Re: your dm patch for strace Eugene Syromyatnikov
  0 siblings, 2 replies; 41+ messages in thread
From: Mikulas Patocka @ 2016-10-02 21:59 UTC (permalink / raw)
  To: Dmitry V. Levin
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f



On Mon, 12 Sep 2016, Dmitry V. Levin wrote:

> > +			tprintf("}");
> > +			if (entering(tcp))
> > +				offset = offset + s->next;
> > +			else
> > +				offset = ioc->data_start + s->next;
> 
> This code trusts s->next; unfortunately, strace cannot trust syscall
> arguments, otherwise anything may happen, e.g.
> 
> $ cat ioctl_dm.c
> #include <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
> 
> btw, this parser lacks tests.  How one can easily verify that it works
> correctly?  For example how a test for strace ioctl parser may look like
> see tests/ioctl_* files.
> 
> 
> -- 
> ldv

Here I'm sending new patch. It fixes the possible loop with s->next and 
adds tests:

 Makefile.am         |    1 
 configure.ac        |    1 
 defs.h              |    1 
 dm.c                |  356 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 ioctl.c             |    4 
 tests/Makefile.am   |    2 
 tests/ioctl_dm.c    |   78 +++++++++++
 tests/ioctl_dm.test |   12 +
 xlat/dm_flags.in    |   17 ++
 9 files changed, 472 insertions(+)

Index: strace/Makefile.am
===================================================================
--- strace.orig/Makefile.am
+++ strace/Makefile.am
@@ -97,6 +97,7 @@ strace_SOURCES =	\
 	desc.c		\
 	dirent.c	\
 	dirent64.c	\
+	dm.c		\
 	empty.h		\
 	epoll.c		\
 	evdev.c		\
Index: strace/configure.ac
===================================================================
--- strace.orig/configure.ac
+++ strace/configure.ac
@@ -354,6 +354,7 @@ AC_CHECK_HEADERS(m4_normalize([
 	elf.h
 	inttypes.h
 	linux/bsg.h
+	linux/dm-ioctl.h
 	linux/dqblk_xfs.h
 	linux/falloc.h
 	linux/fiemap.h
Index: strace/defs.h
===================================================================
--- strace.orig/defs.h
+++ strace/defs.h
@@ -640,6 +640,7 @@ extern void print_struct_statfs64(struct
 
 extern void print_ifindex(unsigned int);
 
+extern int dm_ioctl(struct tcb *, const unsigned int, long);
 extern int file_ioctl(struct tcb *, const unsigned int, long);
 extern int fs_x_ioctl(struct tcb *, const unsigned int, long);
 extern int loop_ioctl(struct tcb *, const unsigned int, long);
Index: strace/dm.c
===================================================================
--- /dev/null
+++ strace/dm.c
@@ -0,0 +1,356 @@
+#include "defs.h"
+
+#ifdef HAVE_LINUX_DM_IOCTL_H
+
+#include <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
===================================================================
--- strace.orig/ioctl.c
+++ strace/ioctl.c
@@ -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
===================================================================
--- strace.orig/tests/Makefile.am
+++ strace/tests/Makefile.am
@@ -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
===================================================================
--- /dev/null
+++ strace/tests/ioctl_dm.c
@@ -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
===================================================================
--- /dev/null
+++ strace/tests/ioctl_dm.test
@@ -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
===================================================================
--- /dev/null
+++ strace/xlat/dm_flags.in
@@ -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

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] Re: your dm patch for strace
       [not found]                   ` <alpine.LRH.2.02.1610021751280.29417-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
@ 2016-10-05 10:28                     ` Masatake YAMATO
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Masatake YAMATO @ 2016-10-05 10:28 UTC (permalink / raw)
  To: mpatocka-H+wXaHxf7aLQT0dZR+AlfA
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

I tested the patch and it works fine.
Could you add following patch if you approve?

commit bae7528fa92283726caac1ec7a6c306274f8899d
Author: Masatake YAMATO <yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
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.
    
    Signed-off-by: Masatake YAMATO <yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

diff --git a/xlat/dm_flags.in b/xlat/dm_flags.in
index ab4285c..1e7132b 100644
--- a/xlat/dm_flags.in
+++ b/xlat/dm_flags.in
@@ -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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH] Re: your dm patch for strace
  2016-10-02 21:59                 ` Mikulas Patocka
       [not found]                   ` <alpine.LRH.2.02.1610021751280.29417-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
@ 2016-10-08 17:45                   ` Eugene Syromyatnikov
  1 sibling, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-08 17:45 UTC (permalink / raw)
  To: dm-devel

Hello.

While digging through your patch, looks like I've stumbled upon what
looks like some minor out-of-bunds write in dm ioctl code: nl->dev = 0
write (drivers/md/dm-ioctl.c:533 @ b66484cd7) could be out of bounds
in case userspace provided data_size of sizeof(struct dm_ioctl) and
there are no device mapper devices present. Since data_size remains
the same, this write does not make it to user space, and since this
memory is kmalloc'ed, it's unlikely it overwrites any data since
struct dm_ioctl size is not divisible by 32, but nevertheless.

On Sun, Oct 2, 2016 at 9:59 PM, Mikulas Patocka <mpatocka@redhat.com> wrote:
>
>
> On Mon, 12 Sep 2016, Dmitry V. Levin wrote:
>
>> > +                   tprintf("}");
>> > +                   if (entering(tcp))
>> > +                           offset = offset + s->next;
>> > +                   else
>> > +                           offset = ioc->data_start + s->next;
>>
>> This code trusts s->next; unfortunately, strace cannot trust syscall
>> arguments, otherwise anything may happen, e.g.
>>
>> $ cat ioctl_dm.c
>> #include <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
>>
>> btw, this parser lacks tests.  How one can easily verify that it works
>> correctly?  For example how a test for strace ioctl parser may look like
>> see tests/ioctl_* files.
>>
>>
>> --
>> ldv
>
> Here I'm sending new patch. It fixes the possible loop with s->next and
> adds tests:
>
>  Makefile.am         |    1
>  configure.ac        |    1
>  defs.h              |    1
>  dm.c                |  356 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  ioctl.c             |    4
>  tests/Makefile.am   |    2
>  tests/ioctl_dm.c    |   78 +++++++++++
>  tests/ioctl_dm.test |   12 +
>  xlat/dm_flags.in    |   17 ++
>  9 files changed, 472 insertions(+)
>
> Index: strace/Makefile.am
> ===================================================================
> --- strace.orig/Makefile.am
> +++ strace/Makefile.am
> @@ -97,6 +97,7 @@ strace_SOURCES =      \
>         desc.c          \
>         dirent.c        \
>         dirent64.c      \
> +       dm.c            \
>         empty.h         \
>         epoll.c         \
>         evdev.c         \
> Index: strace/configure.ac
> ===================================================================
> --- strace.orig/configure.ac
> +++ strace/configure.ac
> @@ -354,6 +354,7 @@ AC_CHECK_HEADERS(m4_normalize([
>         elf.h
>         inttypes.h
>         linux/bsg.h
> +       linux/dm-ioctl.h
>         linux/dqblk_xfs.h
>         linux/falloc.h
>         linux/fiemap.h
> Index: strace/defs.h
> ===================================================================
> --- strace.orig/defs.h
> +++ strace/defs.h
> @@ -640,6 +640,7 @@ extern void print_struct_statfs64(struct
>
>  extern void print_ifindex(unsigned int);
>
> +extern int dm_ioctl(struct tcb *, const unsigned int, long);
>  extern int file_ioctl(struct tcb *, const unsigned int, long);
>  extern int fs_x_ioctl(struct tcb *, const unsigned int, long);
>  extern int loop_ioctl(struct tcb *, const unsigned int, long);
> Index: strace/dm.c
> ===================================================================
> --- /dev/null
> +++ strace/dm.c
> @@ -0,0 +1,356 @@
> +#include "defs.h"
> +
> +#ifdef HAVE_LINUX_DM_IOCTL_H
> +
> +#include <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
> ===================================================================
> --- strace.orig/ioctl.c
> +++ strace/ioctl.c
> @@ -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
> ===================================================================
> --- strace.orig/tests/Makefile.am
> +++ strace/tests/Makefile.am
> @@ -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
> ===================================================================
> --- /dev/null
> +++ strace/tests/ioctl_dm.c
> @@ -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
> ===================================================================
> --- /dev/null
> +++ strace/tests/ioctl_dm.test
> @@ -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
> ===================================================================
> --- /dev/null
> +++ strace/xlat/dm_flags.in
> @@ -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
> Strace-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/strace-devel



-- 
Eugene "eSyr" Syromyatnikov
mailto:evgSyr@gmail.com
xmpp:eSyr@jabber.{ru|org}

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 00/21] Some possible additions to the DM ioctl patch for strace
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2016-10-09 13:27                         ` Eugene Syromyatnikov
  2016-10-09 13:28                         ` [PATCH 01/21] tests/ioctl_dm: Formatting Eugene Syromyatnikov
                                           ` (31 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:27 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

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(-)

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

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/21] tests/ioctl_dm: Formatting
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2016-10-09 13:27                         ` [PATCH 00/21] Some possible additions to the DM ioctl " Eugene Syromyatnikov
@ 2016-10-09 13:28                         ` Eugene Syromyatnikov
  2016-10-09 13:28                         ` [PATCH 02/21] dm: whitespace fixes Eugene Syromyatnikov
                                           ` (30 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:28 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/ioctl_dm.c |   42 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index f4c3c8b..a5945ae 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -40,38 +40,66 @@ main(void)
 	s.ioc.data_size = sizeof(s.ioc);
 	s.ioc.data_start = 0;
 	ioctl(-1, DM_VERSION, &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;
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 02/21] dm: whitespace fixes
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2016-10-09 13:27                         ` [PATCH 00/21] Some possible additions to the DM ioctl " Eugene Syromyatnikov
  2016-10-09 13:28                         ` [PATCH 01/21] tests/ioctl_dm: Formatting Eugene Syromyatnikov
@ 2016-10-09 13:28                         ` Eugene Syromyatnikov
  2016-10-09 13:28                         ` [PATCH 03/21] tests: Working around bounds check Eugene Syromyatnikov
                                           ` (29 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:28 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c |   87 +++++++++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 52 insertions(+), 35 deletions(-)

diff --git a/dm.c b/dm.c
index 33a3972..d81983d 100644
--- a/dm.c
+++ b/dm.c
@@ -2,8 +2,8 @@
 
 #ifdef HAVE_LINUX_DM_IOCTL_H
 
-#include <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("}");
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 03/21] tests: Working around bounds check
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (2 preceding siblings ...)
  2016-10-09 13:28                         ` [PATCH 02/21] dm: whitespace fixes Eugene Syromyatnikov
@ 2016-10-09 13:28                         ` Eugene Syromyatnikov
  2016-10-09 13:28                         ` [PATCH 04/21] dm: Minor output tweaks Eugene Syromyatnikov
                                           ` (28 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:28 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

When 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(-)

diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index a5945ae..cb6dd97 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -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\", "
-- 
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
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 04/21] dm: Minor output tweaks
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (3 preceding siblings ...)
  2016-10-09 13:28                         ` [PATCH 03/21] tests: Working around bounds check Eugene Syromyatnikov
@ 2016-10-09 13:28                         ` Eugene Syromyatnikov
  2016-10-09 13:29                         ` [PATCH 05/21] xlat: Add values for dm_flags Eugene Syromyatnikov
                                           ` (27 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:28 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

Trying to make it more C-like and in line with common practices
regarding structure printing.
---
 dm.c             |   21 +++++++++++++--------
 tests/ioctl_dm.c |    2 +-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/dm.c b/dm.c
index d81983d..ebdfc44 100644
--- a/dm.c
+++ b/dm.c
@@ -120,7 +120,7 @@ dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc,
 			offset = new_offset;
 		} else {
 misplaced:
-			tprints(", misplaced struct dm_target_spec");
+			tprints(", /* misplaced struct dm_target_spec */ ...");
 			break;
 		}
 	}
@@ -150,7 +150,7 @@ dm_decode_dm_target_deps(const struct dm_ioctl *ioc, const char *extra,
 		tprints("}");
 	} else {
  misplaced:
-		tprints(", misplaced struct dm_target_deps");
+		tprints(", /* misplaced struct dm_target_deps */ ...");
 	}
 }
 
@@ -182,7 +182,7 @@ dm_decode_dm_name_list(const struct dm_ioctl *ioc, const char *extra,
 			offset = offset + s->next;
 		} else {
  misplaced:
-			tprints(", misplaced struct dm_name_list");
+			tprints(", /* misplaced struct dm_name_list */ ...");
 			break;
 		}
 	}
@@ -216,7 +216,8 @@ dm_decode_dm_target_versions(const struct dm_ioctl *ioc, const char *extra,
 			offset = offset + s->next;
 		} else {
  misplaced:
-			tprints(", misplaced struct dm_target_versions");
+			tprints(", /* misplaced struct dm_target_versions */ "
+				"...");
 			break;
 		}
 	}
@@ -240,7 +241,7 @@ dm_decode_dm_target_msg(const struct dm_ioctl *ioc, const char *extra,
 				    QUOTE_0_TERMINATED);
 		tprints("}");
 	} else {
-		tprints(", misplaced struct dm_target_msg");
+		tprints(", /* misplaced struct dm_target_msg */");
 	}
 }
 
@@ -255,7 +256,7 @@ dm_decode_string(const struct dm_ioctl *ioc, const char *extra,
 		print_quoted_string(extra + offset, extra_size - offset,
 				    QUOTE_0_TERMINATED);
 	} else {
-		tprints(", misplaced string");
+		tprints(", /* misplaced string */");
 	}
 }
 
@@ -275,8 +276,10 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 	 * if we use a different version of ABI, do not attempt to decode
 	 * ioctl fields
 	 */
-	if (ioc.version[0] != DM_VERSION_MAJOR)
+	if (ioc.version[0] != DM_VERSION_MAJOR) {
+		tprints(", /* Unsupported device mapper ABI version */ ...");
 		goto skip;
+	}
 
 	if (ioc.data_size > sizeof(ioc)) {
 		extra = malloc(ioc.data_size);
@@ -292,7 +295,9 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 	dm_decode_device(code, &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:
diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index cb6dd97..ba484ee 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -98,7 +98,7 @@ main(void)
 	       "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", "
 	       "uuid=\"uuu\", target_count=4294967295, flags=0, "
 	       "{sector_start=0, length=0, target_type=\"\", string=\"\"}, "
-	       "misplaced struct dm_target_spec}, "
+	       "/* misplaced struct dm_target_spec */ ...}, "
 	       "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", "
 	       "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n");
 
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 05/21] xlat: Add values for dm_flags
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (4 preceding siblings ...)
  2016-10-09 13:28                         ` [PATCH 04/21] dm: Minor output tweaks Eugene Syromyatnikov
@ 2016-10-09 13:29                         ` Eugene Syromyatnikov
  2016-10-09 13:29                         ` [PATCH 06/21] dm: Some future-proofing by means of compile-time DM_VERSION_MAJOR check Eugene Syromyatnikov
                                           ` (26 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:29 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

Otherwise build fails on some old distros which lack DM_DATA_OUT_FLAG
and other flags (excerpt from RHEL 5 build log):

[   66s] dm.c: In function 'dm_known_ioctl':
[   66s] dm.c:311: error: 'DM_DATA_OUT_FLAG' undeclared (first use in this function)
[   66s] dm.c:311: error: (Each undeclared identifier is reported only once
[   66s] dm.c:311: error: for each function it appears in.)

Curiously, EXISTS flags had been present in v1 of DM interface, but was
removed in v4.

* xlat/dm_flags.in: Add values for DM_*_FLAG constants (obtained from
<linux/dm-ioctl.h>).
---
 xlat/dm_flags.in |   36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/xlat/dm_flags.in b/xlat/dm_flags.in
index 1e7132b..fa734c8 100644
--- a/xlat/dm_flags.in
+++ b/xlat/dm_flags.in
@@ -1,19 +1,19 @@
-DM_READONLY_FLAG
-DM_SUSPEND_FLAG
+DM_READONLY_FLAG             (1 << 0)
+DM_SUSPEND_FLAG              (1 << 1)
 /* Defined in lvm2/libdm/ioctl/libdm-iface.c */
-DM_EXISTS_FLAG 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)
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 06/21] dm: Some future-proofing by means of compile-time DM_VERSION_MAJOR check
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (5 preceding siblings ...)
  2016-10-09 13:29                         ` [PATCH 05/21] xlat: Add values for dm_flags Eugene Syromyatnikov
@ 2016-10-09 13:29                         ` Eugene Syromyatnikov
  2016-10-09 13:29                         ` [PATCH 07/21] dm: Add definitions for ioctl commands not implemented initially Eugene Syromyatnikov
                                           ` (25 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:29 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

* dm.c: Add check whether DM_VERSION_MAJOR equals to 4, provide empty
dm_ioctl if check fails.
---
 dm.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/dm.c b/dm.c
index ebdfc44..79bb7c7 100644
--- a/dm.c
+++ b/dm.c
@@ -5,6 +5,8 @@
 # include <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 */
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 07/21] dm: Add definitions for ioctl commands not implemented initially
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (6 preceding siblings ...)
  2016-10-09 13:29                         ` [PATCH 06/21] dm: Some future-proofing by means of compile-time DM_VERSION_MAJOR check Eugene Syromyatnikov
@ 2016-10-09 13:29                         ` Eugene Syromyatnikov
  2016-10-09 13:30                         ` [PATCH 08/21] dm: Use static constants for offset sizes Eugene Syromyatnikov
                                           ` (24 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:29 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

dm.c [!DM_LIST_VERSIONS] (DM_LIST_VERSIONS): New definition.
[!DM_TARGET_MSG] (DM_TARGET_MSG): Likewise.
[!DM_DEV_SET_GEOMETRY] (DM_DEV_SET_GEOMETRY): Likewise.
---
 dm.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/dm.c b/dm.c
index 79bb7c7..66b615d 100644
--- a/dm.c
+++ b/dm.c
@@ -7,6 +7,19 @@
 
 # if DM_VERSION_MAJOR == 4
 
+/* Definitions for command which have been added later */
+
+#  ifndef DM_LIST_VERSIONS
+#   define DM_LIST_VERSIONS    _IOWR(DM_IOCTL, 0xd, struct dm_ioctl)
+#  endif
+#  ifndef DM_TARGET_MSG
+#   define DM_TARGET_MSG       _IOWR(DM_IOCTL, 0xe, struct dm_ioctl)
+#  endif
+#  ifndef DM_DEV_SET_GEOMETRY
+#   define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, 0xf, struct dm_ioctl)
+#  endif
+
+
 static void
 dm_decode_device(const unsigned int code, const struct dm_ioctl *ioc)
 {
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 08/21] dm: Use static constants for offset sizes
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (7 preceding siblings ...)
  2016-10-09 13:29                         ` [PATCH 07/21] dm: Add definitions for ioctl commands not implemented initially Eugene Syromyatnikov
@ 2016-10-09 13:30                         ` Eugene Syromyatnikov
  2016-10-09 13:30                         ` [PATCH 09/21] dm: Remove char * cast Eugene Syromyatnikov
                                           ` (23 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:30 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

This may improve readability an leads to more compact code.
---
 dm.c |   58 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/dm.c b/dm.c
index 66b615d..adfa97e 100644
--- a/dm.c
+++ b/dm.c
@@ -102,12 +102,14 @@ static void
 dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc,
 			 const char *extra, uint32_t extra_size)
 {
+	static const uint32_t target_spec_size =
+		sizeof(struct dm_target_spec);
 	uint32_t i;
 	uint32_t offset = ioc->data_start;
 
 	for (i = 0; i < ioc->target_count; i++) {
-		if (offset + (uint32_t) sizeof(struct dm_target_spec) >= offset &&
-		    offset + (uint32_t) sizeof(struct dm_target_spec) < extra_size) {
+		if (offset + target_spec_size >= offset &&
+		    offset + target_spec_size < extra_size) {
 			uint32_t new_offset;
 			const struct dm_target_spec *s =
 				(const struct dm_target_spec *) (extra + offset);
@@ -121,16 +123,14 @@ dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc,
 					    QUOTE_0_TERMINATED);
 			tprints(", string=");
 			print_quoted_string((const char *) (s + 1), extra_size -
-					    (offset +
-					    sizeof(struct dm_target_spec)),
+					    (offset + target_spec_size),
 					    QUOTE_0_TERMINATED);
 			tprintf("}");
 			if (entering(tcp))
 				new_offset = offset + s->next;
 			else
 				new_offset = ioc->data_start + s->next;
-			if (new_offset <= offset +
-			    (uint32_t) sizeof(struct dm_target_spec))
+			if (new_offset <= offset + target_spec_size)
 				goto misplaced;
 			offset = new_offset;
 		} else {
@@ -145,13 +145,15 @@ static void
 dm_decode_dm_target_deps(const struct dm_ioctl *ioc, const char *extra,
 			 uint32_t extra_size)
 {
+	static const uint32_t target_deps_dev_offs =
+		offsetof(struct dm_target_deps, dev);
 	uint32_t offset = ioc->data_start;
-	if (offset + (uint32_t) offsetof(struct dm_target_deps, dev) >= offset &&
-	    offset + (uint32_t) offsetof(struct dm_target_deps, dev) <= extra_size) {
 
+	if (offset + target_deps_dev_offs >= offset &&
+	    offset + target_deps_dev_offs <= extra_size) {
 		uint32_t i;
-		uint32_t space = (extra_size - (offset +
-			offsetof(struct dm_target_deps, dev))) / sizeof(__u64);
+		uint32_t space = (extra_size - offset - target_deps_dev_offs) /
+			sizeof(__u64);
 		const struct dm_target_deps *s =
 			(const struct dm_target_deps *) (extra + offset);
 
@@ -173,11 +175,13 @@ static void
 dm_decode_dm_name_list(const struct dm_ioctl *ioc, const char *extra,
 		       uint32_t extra_size)
 {
+	static const uint32_t name_list_name_offs =
+		offsetof(struct dm_name_list, name);
 	uint32_t offset = ioc->data_start;
 
 	while (1) {
-		if (offset + (uint32_t) offsetof(struct dm_name_list, name) >= offset &&
-		    offset + (uint32_t) offsetof(struct dm_name_list, name) < extra_size) {
+		if (offset + name_list_name_offs >= offset &&
+		    offset + name_list_name_offs < extra_size) {
 			const struct dm_name_list *s =
 				(const struct dm_name_list *) (extra + offset);
 
@@ -186,13 +190,12 @@ dm_decode_dm_name_list(const struct dm_ioctl *ioc, const char *extra,
 			tprintf(", {dev=makedev(%u, %u), name=", major(s->dev),
 				minor(s->dev));
 			print_quoted_string(s->name, extra_size - (offset +
-					    offsetof(struct dm_name_list,
-					    name)), QUOTE_0_TERMINATED);
+					    name_list_name_offs),
+					    QUOTE_0_TERMINATED);
 			tprints("}");
 			if (!s->next)
 				break;
-			if (offset + s->next <= offset +
-			    (uint32_t) offsetof(struct dm_name_list, name))
+			if (offset + s->next <= offset + name_list_name_offs)
 				goto misplaced;
 			offset = offset + 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 {
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 09/21] dm: Remove char * cast
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (8 preceding siblings ...)
  2016-10-09 13:30                         ` [PATCH 08/21] dm: Use static constants for offset sizes Eugene Syromyatnikov
@ 2016-10-09 13:30                         ` Eugene Syromyatnikov
  2016-10-09 13:30                         ` [PATCH 10/21] dm: use => instead of , for splitting output structure from input Eugene Syromyatnikov
                                           ` (22 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:30 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dm.c b/dm.c
index adfa97e..3ee74c3 100644
--- a/dm.c
+++ b/dm.c
@@ -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]);
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 10/21] dm: use => instead of , for splitting output structure from input
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (9 preceding siblings ...)
  2016-10-09 13:30                         ` [PATCH 09/21] dm: Remove char * cast Eugene Syromyatnikov
@ 2016-10-09 13:30                         ` Eugene Syromyatnikov
  2016-10-09 13:30                         ` [PATCH 11/21] dm: Compare entering field values with exiting ones Eugene Syromyatnikov
                                           ` (21 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:30 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c             |    4 ++--
 tests/ioctl_dm.c |   12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/dm.c b/dm.c
index 3ee74c3..f23a65d 100644
--- a/dm.c
+++ b/dm.c
@@ -288,8 +288,8 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 
 	if (umoven(tcp, arg, sizeof(ioc) - sizeof(ioc.data), &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
diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index ba484ee..3c43913 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -42,7 +42,7 @@ main(void)
 	ioctl(-1, DM_VERSION, &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");
 
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 11/21] dm: Compare entering field values with exiting ones
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (10 preceding siblings ...)
  2016-10-09 13:30                         ` [PATCH 10/21] dm: use => instead of , for splitting output structure from input Eugene Syromyatnikov
@ 2016-10-09 13:30                         ` Eugene Syromyatnikov
  2016-10-09 13:30                         ` [PATCH 12/21] dm: Add inttypes.h, include reorder Eugene Syromyatnikov
                                           ` (20 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:30 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c             |   74 ++++++++++++++++++++++++++++++++++++++++--------------
 tests/ioctl_dm.c |   26 +++++++------------
 2 files changed, 64 insertions(+), 36 deletions(-)

diff --git a/dm.c b/dm.c
index f23a65d..b6fb11d 100644
--- a/dm.c
+++ b/dm.c
@@ -282,28 +282,62 @@ dm_decode_string(const struct dm_ioctl *ioc, const char *extra,
 static int
 dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 {
-	struct dm_ioctl ioc;
+	struct dm_ioctl *ioc;
+	struct dm_ioctl *entering_ioc = NULL;
+	bool ioc_changed = false;
 	char *extra = NULL;
 	uint32_t extra_size = 0;
 
-	if (umoven(tcp, arg, sizeof(ioc) - sizeof(ioc.data), &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;
 }
 
diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 3c43913..31f474c 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -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;
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 12/21] dm: Add inttypes.h, include reorder
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (11 preceding siblings ...)
  2016-10-09 13:30                         ` [PATCH 11/21] dm: Compare entering field values with exiting ones Eugene Syromyatnikov
@ 2016-10-09 13:30                         ` Eugene Syromyatnikov
  2016-10-09 13:30                         ` [PATCH 13/21] dm: Move printing of dm_ioctl fields before allocation of extra data Eugene Syromyatnikov
                                           ` (19 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:30 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

Build failed otherwise on RHEL 5.
---
 dm.c             |    3 ++-
 tests/ioctl_dm.c |    1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/dm.c b/dm.c
index b6fb11d..a11196f 100644
--- a/dm.c
+++ b/dm.c
@@ -2,8 +2,9 @@
 
 #ifdef HAVE_LINUX_DM_IOCTL_H
 
-# include <sys/ioctl.h>
+# include <inttypes.h>
 # include <linux/dm-ioctl.h>
+# include <sys/ioctl.h>
 
 # if DM_VERSION_MAJOR == 4
 
diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 31f474c..94dbe93 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -1,4 +1,5 @@
 #include "tests.h"
+#include <inttypes.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <string.h>
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 13/21] dm: Move printing of dm_ioctl fields before allocation of extra data
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (12 preceding siblings ...)
  2016-10-09 13:30                         ` [PATCH 12/21] dm: Add inttypes.h, include reorder Eugene Syromyatnikov
@ 2016-10-09 13:30                         ` Eugene Syromyatnikov
  2016-10-09 13:30                         ` [PATCH 14/21] dm: replace abbrev branching with goto Eugene Syromyatnikov
                                           ` (18 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:30 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/dm.c b/dm.c
index a11196f..73a9b57 100644
--- a/dm.c
+++ b/dm.c
@@ -335,6 +335,10 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 		goto skip;
 	}
 
+	dm_decode_device(code, ioc);
+	dm_decode_values(tcp, code, ioc);
+	dm_decode_flags(ioc);
+
 	if (ioc->data_size > sizeof(ioc)) {
 		extra = malloc(ioc->data_size);
 		if (extra) {
@@ -346,9 +350,6 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 			}
 		}
 	}
-	dm_decode_device(code, ioc);
-	dm_decode_values(tcp, code, ioc);
-	dm_decode_flags(ioc);
 	if (abbrev(tcp))
 		tprints(", ...");
 	else
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 14/21] dm: replace abbrev branching with goto
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (13 preceding siblings ...)
  2016-10-09 13:30                         ` [PATCH 13/21] dm: Move printing of dm_ioctl fields before allocation of extra data Eugene Syromyatnikov
@ 2016-10-09 13:30                         ` Eugene Syromyatnikov
  2016-10-09 13:31                         ` [PATCH 15/21] dm: Additional data_size/data_start checks Eugene Syromyatnikov
                                           ` (17 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:30 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c |   78 ++++++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 40 insertions(+), 38 deletions(-)

diff --git a/dm.c b/dm.c
index 73a9b57..814d7d2 100644
--- a/dm.c
+++ b/dm.c
@@ -350,52 +350,54 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 			}
 		}
 	}
-	if (abbrev(tcp))
+
+	if (abbrev(tcp)) {
 		tprints(", ...");
-	else
-		switch (code) {
-		case DM_DEV_WAIT:
-		case DM_TABLE_STATUS:
-			if (entering(tcp) || syserror(tcp))
-				break;
-			dm_decode_dm_target_spec(tcp, ioc, extra, extra_size);
-			break;
-		case DM_TABLE_LOAD:
-			if (!entering(tcp))
-				break;
-			dm_decode_dm_target_spec(tcp, ioc, extra, extra_size);
+		goto skip;
+	}
+
+	switch (code) {
+	case DM_DEV_WAIT:
+	case DM_TABLE_STATUS:
+		if (entering(tcp) || syserror(tcp))
 			break;
-		case DM_TABLE_DEPS:
-			if (entering(tcp) || syserror(tcp))
-				break;
-			dm_decode_dm_target_deps(ioc, extra, extra_size);
+		dm_decode_dm_target_spec(tcp, ioc, extra, extra_size);
+		break;
+	case DM_TABLE_LOAD:
+		if (!entering(tcp))
 			break;
-		case DM_LIST_DEVICES:
-			if (entering(tcp) || syserror(tcp))
-				break;
-			dm_decode_dm_name_list(ioc, extra, extra_size);
+		dm_decode_dm_target_spec(tcp, ioc, extra, extra_size);
+		break;
+	case DM_TABLE_DEPS:
+		if (entering(tcp) || syserror(tcp))
 			break;
-		case DM_LIST_VERSIONS:
-			if (entering(tcp) || syserror(tcp))
-				break;
-			dm_decode_dm_target_versions(ioc, extra, extra_size);
+		dm_decode_dm_target_deps(ioc, extra, extra_size);
+		break;
+	case DM_LIST_DEVICES:
+		if (entering(tcp) || syserror(tcp))
 			break;
-		case DM_TARGET_MSG:
-			if (entering(tcp)) {
-				dm_decode_dm_target_msg(ioc, extra,
-							extra_size);
-			} else if (!syserror(tcp) &&
-			    ioc->flags & DM_DATA_OUT_FLAG) {
-				dm_decode_string(ioc, extra, extra_size);
-			}
+		dm_decode_dm_name_list(ioc, extra, extra_size);
+		break;
+	case DM_LIST_VERSIONS:
+		if (entering(tcp) || syserror(tcp))
 			break;
-		case DM_DEV_RENAME:
-		case DM_DEV_SET_GEOMETRY:
-			if (!entering(tcp))
-				break;
+		dm_decode_dm_target_versions(ioc, extra, extra_size);
+		break;
+	case DM_TARGET_MSG:
+		if (entering(tcp)) {
+			dm_decode_dm_target_msg(ioc, extra,
+						extra_size);
+		} else if (!syserror(tcp) && ioc->flags & DM_DATA_OUT_FLAG) {
 			dm_decode_string(ioc, extra, extra_size);
-			break;
 		}
+		break;
+	case DM_DEV_RENAME:
+	case DM_DEV_SET_GEOMETRY:
+		if (!entering(tcp))
+			break;
+		dm_decode_string(ioc, extra, extra_size);
+		break;
+	}
 
  skip:
 	tprints("}");
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 15/21] dm: Additional data_size/data_start checks
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (14 preceding siblings ...)
  2016-10-09 13:30                         ` [PATCH 14/21] dm: replace abbrev branching with goto Eugene Syromyatnikov
@ 2016-10-09 13:31                         ` Eugene Syromyatnikov
  2016-10-09 13:31                         ` [PATCH 16/21] dm: Add comment regarding intended fall-through in switch statement Eugene Syromyatnikov
                                           ` (16 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:31 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/dm.c b/dm.c
index 814d7d2..289bc0d 100644
--- a/dm.c
+++ b/dm.c
@@ -293,7 +293,8 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 	if (!ioc)
 		return 0;
 
-	if (umoven(tcp, arg, sizeof(*ioc) - sizeof(ioc->data), ioc) < 0) {
+	if ((umoven(tcp, arg, sizeof(*ioc) - sizeof(ioc->data), ioc) < 0) ||
+	    (ioc->data_size < offsetof(struct dm_ioctl, data_size))) {
 		free(ioc);
 		return 0;
 	}
@@ -335,6 +336,11 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 		goto skip;
 	}
 
+	if (ioc->data_size < (sizeof(*ioc) - sizeof(ioc->data))) {
+		tprints(", /* Incorrect data_size */ ...");
+		goto skip;
+	}
+
 	dm_decode_device(code, ioc);
 	dm_decode_values(tcp, code, ioc);
 	dm_decode_flags(ioc);
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 16/21] dm: Add comment regarding intended fall-through in switch statement
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (15 preceding siblings ...)
  2016-10-09 13:31                         ` [PATCH 15/21] dm: Additional data_size/data_start checks Eugene Syromyatnikov
@ 2016-10-09 13:31                         ` Eugene Syromyatnikov
  2016-10-09 13:31                         ` [PATCH 17/21] dm: Add data_size and data_offset fields to output Eugene Syromyatnikov
                                           ` (15 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:31 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/dm.c b/dm.c
index 289bc0d..5c908c9 100644
--- a/dm.c
+++ b/dm.c
@@ -60,6 +60,7 @@ dm_decode_values(struct tcb *tcp, const unsigned int code,
 		case DM_DEV_SUSPEND:
 			if (ioc->flags & DM_SUSPEND_FLAG)
 				break;
+			/* Fall through */
 		case DM_DEV_RENAME:
 		case DM_DEV_REMOVE:
 		case DM_DEV_WAIT:
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 17/21] dm: Add data_size and data_offset fields to output
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (16 preceding siblings ...)
  2016-10-09 13:31                         ` [PATCH 16/21] dm: Add comment regarding intended fall-through in switch statement Eugene Syromyatnikov
@ 2016-10-09 13:31                         ` Eugene Syromyatnikov
  2016-10-09 13:31                         ` [PATCH 18/21] tests/ioctl_dm: Allow passing size and data_start to init_s Eugene Syromyatnikov
                                           ` (14 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:31 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c             |    4 +++-
 tests/ioctl_dm.c |   41 ++++++++++++++++++++++++-----------------
 2 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/dm.c b/dm.c
index 5c908c9..caffc55 100644
--- a/dm.c
+++ b/dm.c
@@ -327,7 +327,6 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 
 	tprintf("%s{version=%d.%d.%d",  entering(tcp) ? ", " : " => ",
 		ioc->version[0], ioc->version[1], ioc->version[2]);
-
 	/*
 	 * if we use a different version of ABI, do not attempt to decode
 	 * ioctl fields
@@ -337,6 +336,9 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 		goto skip;
 	}
 
+	tprintf(", data_size=%u, data_start=%u",
+		ioc->data_size, ioc->data_start);
+
 	if (ioc->data_size < (sizeof(*ioc) - sizeof(ioc->data))) {
 		tprints(", /* Incorrect data_size */ ...");
 		goto skip;
diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 94dbe93..6967ca2 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -42,8 +42,9 @@ main(void)
 	s.ioc.data_start = 0;
 	ioctl(-1, DM_VERSION, &s);
 	printf("ioctl(-1, DM_VERSION, "
-	       "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", "
-	       "uuid=\"uuu\", flags=0}) = -1 EBADF (%m)\n");
+	       "{version=4.1.2, data_size=%zu, data_start=0, "
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0}) = "
+	       "-1 EBADF (%m)\n", sizeof(s.ioc));
 
 	init_s();
 	s.ioc.target_count = 1;
@@ -55,10 +56,11 @@ main(void)
 	strcpy(s.u.ts.target_params, "tparams");
 	ioctl(-1, DM_TABLE_LOAD, &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, "
+	       "{version=4.1.2, data_size=%u, data_start=%u, "
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
+	       "target_count=1, flags=0, {sector_start=16, "
 	       "length=32, target_type=\"tgt\", string=\"tparams\"}}) = "
-	       "-1 EBADF (%m)\n");
+	       "-1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start);
 
 	init_s();
 	s.u.tm.target_msg.sector = 0x1234;
@@ -66,34 +68,39 @@ main(void)
 		"tmsg");
 	ioctl(-1, DM_TARGET_MSG, &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\"}}) = "
-	       "-1 EBADF (%m)\n");
+	       "{version=4.1.2, data_size=%u, data_start=%u, "
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
+	       "{sector=4660, message=\"tmsg\"}}) = -1 EBADF (%m)\n",
+	       s.ioc.data_size, s.ioc.data_start);
 
 	init_s();
 	strcpy(s.u.string, "10 20 30 40");
 	ioctl(-1, DM_DEV_SET_GEOMETRY, &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\"}) = "
-	       "-1 EBADF (%m)\n");
+	       "{version=4.1.2, data_size=%u, data_start=%u, "
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
+	       "string=\"10 20 30 40\"}) = -1 EBADF (%m)\n",
+	       s.ioc.data_size, s.ioc.data_start);
 
 	init_s();
 	strcpy(s.u.string, "new-name");
 	ioctl(-1, DM_DEV_RENAME, &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\"}) = "
-	       "-1 EBADF (%m)\n");
+	       "{version=4.1.2, data_size=%u, data_start=%u, "
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", event_nr=0, "
+	       "flags=0, string=\"new-name\"}) = -1 EBADF (%m)\n",
+	       s.ioc.data_size, s.ioc.data_start);
 
 	init_s();
 	s.ioc.target_count = -1U;
 	ioctl(-1, DM_TABLE_LOAD, &s);
 	printf("ioctl(-1, DM_TABLE_LOAD, "
-	       "{version=4.1.2, dev=makedev(18, 52), name=\"nnn\", "
-	       "uuid=\"uuu\", target_count=4294967295, flags=0, "
+	       "{version=4.1.2, data_size=%u, data_start=%u, "
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
+	       "target_count=4294967295, flags=0, "
 	       "{sector_start=0, length=0, target_type=\"\", string=\"\"}, "
-	       "/* misplaced struct dm_target_spec */ ...}) = -1 EBADF (%m)\n");
+	       "/* misplaced struct dm_target_spec */ ...}) = -1 EBADF (%m)\n",
+	       s.ioc.data_size, s.ioc.data_start);
 
 	puts("+++ exited with 0 +++");
 	return 0;
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 18/21] tests/ioctl_dm: Allow passing size and data_start to init_s
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (17 preceding siblings ...)
  2016-10-09 13:31                         ` [PATCH 17/21] dm: Add data_size and data_offset fields to output Eugene Syromyatnikov
@ 2016-10-09 13:31                         ` Eugene Syromyatnikov
  2016-10-09 13:31                         ` [PATCH 19/21] dm: Add check whether command uses parameters Eugene Syromyatnikov
                                           ` (13 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:31 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/ioctl_dm.c |   34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 6967ca2..c120ed2 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -21,32 +21,30 @@ static struct s {
 	} u;
 } s;
 
-static void init_s(void)
+static void init_s(struct dm_ioctl *s, size_t size, size_t offs)
 {
-	memset(&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, "
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 19/21] dm: Add check whether command uses parameters
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (18 preceding siblings ...)
  2016-10-09 13:31                         ` [PATCH 18/21] tests/ioctl_dm: Allow passing size and data_start to init_s Eugene Syromyatnikov
@ 2016-10-09 13:31                         ` Eugene Syromyatnikov
  2016-10-09 13:31                         ` [PATCH 20/21] dm: Fix printing of version field Eugene Syromyatnikov
                                           ` (12 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:31 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c             |   25 ++++++++++++++++++++++---
 tests/ioctl_dm.c |    2 +-
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/dm.c b/dm.c
index caffc55..a48aa72 100644
--- a/dm.c
+++ b/dm.c
@@ -281,6 +281,23 @@ dm_decode_string(const struct dm_ioctl *ioc, const char *extra,
 	}
 }
 
+static inline bool
+dm_ioctl_has_params(const unsigned int code)
+{
+	switch (code) {
+	case DM_VERSION:
+	case DM_REMOVE_ALL:
+	case DM_DEV_CREATE:
+	case DM_DEV_REMOVE:
+	case DM_DEV_SUSPEND:
+	case DM_DEV_STATUS:
+	case DM_TABLE_CLEAR:
+		return false;
+	}
+
+	return true;
+}
+
 static int
 dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 {
@@ -336,8 +353,10 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 		goto skip;
 	}
 
-	tprintf(", data_size=%u, data_start=%u",
-		ioc->data_size, ioc->data_start);
+	tprintf(", data_size=%u", ioc->data_size);
+
+	if (dm_ioctl_has_params(code))
+		tprintf(", data_start=%u", ioc->data_start);
 
 	if (ioc->data_size < (sizeof(*ioc) - sizeof(ioc->data))) {
 		tprints(", /* Incorrect data_size */ ...");
@@ -348,7 +367,7 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 	dm_decode_values(tcp, code, ioc);
 	dm_decode_flags(ioc);
 
-	if (ioc->data_size > sizeof(ioc)) {
+	if (dm_ioctl_has_params(code) && (ioc->data_size > sizeof(ioc))) {
 		extra = malloc(ioc->data_size);
 		if (extra) {
 			extra_size = ioc->data_size;
diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index c120ed2..6ad4ea9 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -40,7 +40,7 @@ main(void)
 	init_s(&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));
 
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 20/21] dm: Fix printing of version field
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (19 preceding siblings ...)
  2016-10-09 13:31                         ` [PATCH 19/21] dm: Add check whether command uses parameters Eugene Syromyatnikov
@ 2016-10-09 13:31                         ` Eugene Syromyatnikov
  2016-10-09 13:31                         ` [PATCH 21/21] dm: rewrite structure decoding Eugene Syromyatnikov
                                           ` (11 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:31 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/dm.c b/dm.c
index a48aa72..ff9e8ad 100644
--- a/dm.c
+++ b/dm.c
@@ -342,7 +342,11 @@ dm_known_ioctl(struct tcb *tcp, const unsigned int code, long arg)
 		return 1;
 	}
 
-	tprintf("%s{version=%d.%d.%d",  entering(tcp) ? ", " : " => ",
+	/*
+	 * device mapper code uses %d in some places and %u in another, but
+	 * fields themselves are declared as __u32.
+	 */
+	tprintf("%s{version=%u.%u.%u",  entering(tcp) ? ", " : " => ",
 		ioc->version[0], ioc->version[1], ioc->version[2]);
 	/*
 	 * if we use a different version of ABI, do not attempt to decode
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 21/21] dm: rewrite structure decoding
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (20 preceding siblings ...)
  2016-10-09 13:31                         ` [PATCH 20/21] dm: Fix printing of version field Eugene Syromyatnikov
@ 2016-10-09 13:31                         ` Eugene Syromyatnikov
  2016-10-10 10:27                         ` [PATCH] Re: your dm patch for strace Mikulas Patocka
                                           ` (10 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-09 13:31 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

Rewrite structure decoding in attempt to make it more in line with how
structures and arrays are decoded in strace.
 * Replace single structure retrieval with on-demand retrieval. It
   allows limiting amount of memory being allocated (suppose ioctl with
   data_size = -1)
 * Check for abbrev in structure decoders itself. It allows
   distinguishing cases when we want to decode some additional data from
   cases when we are not.
---
 dm.c |  363 +++++++++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 217 insertions(+), 146 deletions(-)

diff --git a/dm.c b/dm.c
index ff9e8ad..d846233 100644
--- a/dm.c
+++ b/dm.c
@@ -101,165 +101,254 @@ dm_decode_flags(const struct dm_ioctl *ioc)
 }
 
 static void
-dm_decode_dm_target_spec(struct tcb *tcp, const struct dm_ioctl *ioc,
-			 const char *extra, uint32_t extra_size)
+dm_decode_dm_target_spec(struct tcb *tcp, unsigned long addr,
+			 const struct dm_ioctl *ioc)
 {
 	static const uint32_t target_spec_size =
 		sizeof(struct dm_target_spec);
 	uint32_t i;
 	uint32_t offset = ioc->data_start;
 
+	if (abbrev(tcp)) {
+		if (ioc->target_count)
+			tprints(", ...");
+
+		return;
+	}
+
 	for (i = 0; i < ioc->target_count; i++) {
-		if (offset + target_spec_size >= offset &&
-		    offset + target_spec_size < extra_size) {
-			uint32_t new_offset;
-			const struct dm_target_spec *s =
-				(const struct dm_target_spec *) (extra + offset);
-			tprintf(", {sector_start=%" PRIu64 ", length=%" PRIu64,
-				(uint64_t) s->sector_start,
-				(uint64_t) s->length);
-			if (!entering(tcp))
-				tprintf(", status=%" PRId32, s->status);
-			tprints(", target_type=");
-			print_quoted_string(s->target_type, DM_MAX_TYPE_NAME,
-					    QUOTE_0_TERMINATED);
-			tprints(", string=");
-			print_quoted_string((const char *) (s + 1), extra_size -
-					    (offset + target_spec_size),
-					    QUOTE_0_TERMINATED);
-			tprintf("}");
-			if (entering(tcp))
-				new_offset = offset + s->next;
-			else
-				new_offset = ioc->data_start + s->next;
-			if (new_offset <= offset + target_spec_size)
-				goto misplaced;
-			offset = new_offset;
-		} else {
-misplaced:
-			tprints(", /* misplaced struct dm_target_spec */ ...");
+		struct dm_target_spec s;
+		uint32_t new_offset;
+
+		if ((offset + target_spec_size) <= offset ||
+		    (offset + target_spec_size) > ioc->data_size)
+			goto misplaced;
+
+		tprints(", ");
+
+		if (i >= max_strlen) {
+			tprints("...");
 			break;
 		}
+
+		if (umove_or_printaddr(tcp, addr + offset, &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;
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH] Re: your dm patch for strace
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (21 preceding siblings ...)
  2016-10-09 13:31                         ` [PATCH 21/21] dm: rewrite structure decoding Eugene Syromyatnikov
@ 2016-10-10 10:27                         ` Mikulas Patocka
  2016-10-11 22:38                         ` [PATCH 0/9] Additional checks for strace DM ioctl decoder test Eugene Syromyatnikov
                                           ` (9 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Mikulas Patocka @ 2016-10-10 10:27 UTC (permalink / raw)
  To: Masatake YAMATO
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f



On Wed, 5 Oct 2016, Masatake YAMATO wrote:

> I tested the patch and it works fine.
> Could you add following patch if you approve?
> 
> commit bae7528fa92283726caac1ec7a6c306274f8899d
> Author: Masatake YAMATO <yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 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.
>     
>     Signed-off-by: Masatake YAMATO <yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 
> diff --git a/xlat/dm_flags.in b/xlat/dm_flags.in
> index ab4285c..1e7132b 100644
> --- a/xlat/dm_flags.in
> +++ b/xlat/dm_flags.in
> @@ -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(+)

Index: strace/Makefile.am
===================================================================
--- strace.orig/Makefile.am
+++ strace/Makefile.am
@@ -97,6 +97,7 @@ strace_SOURCES =	\
 	desc.c		\
 	dirent.c	\
 	dirent64.c	\
+	dm.c		\
 	empty.h		\
 	epoll.c		\
 	evdev.c		\
Index: strace/configure.ac
===================================================================
--- strace.orig/configure.ac
+++ strace/configure.ac
@@ -354,6 +354,7 @@ AC_CHECK_HEADERS(m4_normalize([
 	elf.h
 	inttypes.h
 	linux/bsg.h
+	linux/dm-ioctl.h
 	linux/dqblk_xfs.h
 	linux/falloc.h
 	linux/fiemap.h
Index: strace/defs.h
===================================================================
--- strace.orig/defs.h
+++ strace/defs.h
@@ -636,6 +636,7 @@ extern void print_struct_statfs64(struct
 
 extern void print_ifindex(unsigned int);
 
+extern int dm_ioctl(struct tcb *, const unsigned int, long);
 extern int file_ioctl(struct tcb *, const unsigned int, long);
 extern int fs_x_ioctl(struct tcb *, const unsigned int, long);
 extern int loop_ioctl(struct tcb *, const unsigned int, long);
Index: strace/dm.c
===================================================================
--- /dev/null
+++ strace/dm.c
@@ -0,0 +1,356 @@
+#include "defs.h"
+
+#ifdef HAVE_LINUX_DM_IOCTL_H
+
+#include <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
===================================================================
--- strace.orig/ioctl.c
+++ strace/ioctl.c
@@ -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
===================================================================
--- strace.orig/tests/Makefile.am
+++ strace/tests/Makefile.am
@@ -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 \
Index: strace/tests/ioctl_dm.c
===================================================================
--- /dev/null
+++ strace/tests/ioctl_dm.c
@@ -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
===================================================================
--- /dev/null
+++ strace/tests/ioctl_dm.test
@@ -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
===================================================================
--- /dev/null
+++ strace/xlat/dm_flags.in
@@ -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

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 0/9] Additional checks for strace DM ioctl decoder test
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (22 preceding siblings ...)
  2016-10-10 10:27                         ` [PATCH] Re: your dm patch for strace Mikulas Patocka
@ 2016-10-11 22:38                         ` Eugene Syromyatnikov
  2016-10-19 20:31                           ` [PATCH] device mapper ioctl Mikulas Patocka
  2016-10-11 22:38                         ` [PATCH 1/9] util: Add support for QUOTE_0_TERMINATED in user_style to ptrintstr_ex Eugene Syromyatnikov
                                           ` (8 subsequent siblings)
  32 siblings, 1 reply; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:38 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

Hello.

Aside from additional checks themselves, this patchset also contains two
notable changes:
 * Fix for the previous patchset - misplaced comma printing ("dm: Fix comma
   printing for the case when dm_target_msg structure is inaccessible").
 * Update of printstr_ex call, which enables proper handling of
   QUOTE_0_TERMINATED user style (it prints cropped string without ellipsis
   otherwise).

Eugene Syromyatnikov (9):
  util: Add support for QUOTE_0_TERMINATED in user_style to
    ptrintstr_ex
  tests: Add check for printing of overlength strings to ioctl_dm test
  tests: Add check for presence of HAVE_LINUX_DM_IOCTL_H macro
    definition to ioctl_dm test
  tests/ioctl_dm: whitespace
  dm: Fix comma printing for the case when dm_target_msg structure is
    inaccessible
  tests/ioctl_dm: overly long string printing checks
  tests: Some additional checks for ioctl_dm test
  tests: Add ioctl_dm to .gitignore
  tests: Add checks for abbreviated DM ioctl output

 dm.c                  |    4 +-
 tests/.gitignore      |    2 +
 tests/Makefile.am     |    2 +
 tests/ioctl_dm-v.c    |    2 +
 tests/ioctl_dm-v.test |   12 +
 tests/ioctl_dm.c      |  653 +++++++++++++++++++++++++++++++++++++++++++++++--
 tests/ioctl_dm.test   |    2 +-
 util.c                |   18 +-
 8 files changed, 674 insertions(+), 21 deletions(-)
 create mode 100644 tests/ioctl_dm-v.c
 create mode 100755 tests/ioctl_dm-v.test

-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 1/9] util: Add support for QUOTE_0_TERMINATED in user_style to ptrintstr_ex
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (23 preceding siblings ...)
  2016-10-11 22:38                         ` [PATCH 0/9] Additional checks for strace DM ioctl decoder test Eugene Syromyatnikov
@ 2016-10-11 22:38                         ` Eugene Syromyatnikov
  2016-10-11 22:38                         ` [PATCH 2/9] tests: Add check for printing of overlength strings to ioctl_dm test Eugene Syromyatnikov
                                           ` (7 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:38 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

This enables printing size-limited (expectedly) ASCIZ strings.
---
 util.c |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/util.c b/util.c
index 23a5fdb..00148d4 100644
--- a/util.c
+++ b/util.c
@@ -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 & QUOTE_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 & QUOTE_0_TERMINATED) ||
+				(unsigned long) len > max_strlen));
 
 	tprints(outstr);
 	if (ellipsis)
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 2/9] tests: Add check for printing of overlength strings to ioctl_dm test
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (24 preceding siblings ...)
  2016-10-11 22:38                         ` [PATCH 1/9] util: Add support for QUOTE_0_TERMINATED in user_style to ptrintstr_ex Eugene Syromyatnikov
@ 2016-10-11 22:38                         ` Eugene Syromyatnikov
  2016-10-11 22:38                         ` [PATCH 3/9] tests: Add check for presence of HAVE_LINUX_DM_IOCTL_H macro definition " Eugene Syromyatnikov
                                           ` (6 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:38 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/ioctl_dm.c    |    2 +-
 tests/ioctl_dm.test |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 6ad4ea9..0a3bbf4 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -77,7 +77,7 @@ main(void)
 	printf("ioctl(-1, DM_DEV_SET_GEOMETRY, "
 	       "{version=4.1.2, data_size=%u, data_start=%u, "
 	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
-	       "string=\"10 20 30 40\"}) = -1 EBADF (%m)\n",
+	       "string=\"10 20 30 \"...}) = -1 EBADF (%m)\n",
 	       s.ioc.data_size, s.ioc.data_start);
 
 	init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
diff --git a/tests/ioctl_dm.test b/tests/ioctl_dm.test
index db77616..78866d3 100755
--- a/tests/ioctl_dm.test
+++ b/tests/ioctl_dm.test
@@ -5,7 +5,7 @@
 . "${srcdir=.}/init.sh"
 
 run_prog > /dev/null
-run_strace -a16 -veioctl $args > "$EXP"
+run_strace -a16 -s9 -veioctl $args > "$EXP"
 check_prog grep
 grep -v '^ioctl([012],' < "$LOG" > "$OUT"
 match_diff "$OUT" "$EXP"
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 3/9] tests: Add check for presence of HAVE_LINUX_DM_IOCTL_H macro definition to ioctl_dm test
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (25 preceding siblings ...)
  2016-10-11 22:38                         ` [PATCH 2/9] tests: Add check for printing of overlength strings to ioctl_dm test Eugene Syromyatnikov
@ 2016-10-11 22:38                         ` Eugene Syromyatnikov
  2016-10-11 22:38                         ` [PATCH 4/9] tests/ioctl_dm: whitespace Eugene Syromyatnikov
                                           ` (5 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:38 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/ioctl_dm.c |   21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 0a3bbf4..5f2689c 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -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 */
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 4/9] tests/ioctl_dm: whitespace
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (26 preceding siblings ...)
  2016-10-11 22:38                         ` [PATCH 3/9] tests: Add check for presence of HAVE_LINUX_DM_IOCTL_H macro definition " Eugene Syromyatnikov
@ 2016-10-11 22:38                         ` Eugene Syromyatnikov
  2016-10-11 22:38                         ` [PATCH 5/9] dm: Fix comma printing for the case when dm_target_msg structure is inaccessible Eugene Syromyatnikov
                                           ` (4 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:38 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/ioctl_dm.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 5f2689c..261983c 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -24,7 +24,8 @@ static struct s {
 	} u;
 } s;
 
-static void init_s(struct dm_ioctl *s, size_t size, size_t offs)
+static void
+init_s(struct dm_ioctl *s, size_t size, size_t offs)
 {
 	memset(s, 0, size);
 	s->version[0] = DM_VERSION_MAJOR;
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 5/9] dm: Fix comma printing for the case when dm_target_msg structure is inaccessible
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (27 preceding siblings ...)
  2016-10-11 22:38                         ` [PATCH 4/9] tests/ioctl_dm: whitespace Eugene Syromyatnikov
@ 2016-10-11 22:38                         ` Eugene Syromyatnikov
  2016-10-11 22:39                         ` [PATCH 6/9] tests/ioctl_dm: overly long string printing checks Eugene Syromyatnikov
                                           ` (3 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:38 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 dm.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/dm.c b/dm.c
index d846233..b1d455c 100644
--- a/dm.c
+++ b/dm.c
@@ -342,10 +342,12 @@ dm_decode_dm_target_msg(struct tcb *tcp, unsigned long addr,
 	    offset + target_msg_message_offs <= ioc->data_size) {
 		struct dm_target_msg s;
 
+		tprints(", ");
+
 		if (umove_or_printaddr(tcp, addr + offset, &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);
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 6/9] tests/ioctl_dm: overly long string printing checks
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (28 preceding siblings ...)
  2016-10-11 22:38                         ` [PATCH 5/9] dm: Fix comma printing for the case when dm_target_msg structure is inaccessible Eugene Syromyatnikov
@ 2016-10-11 22:39                         ` Eugene Syromyatnikov
  2016-10-11 22:39                         ` [PATCH 7/9] tests: Some additional checks for ioctl_dm test Eugene Syromyatnikov
                                           ` (2 subsequent siblings)
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:39 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/ioctl_dm.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 261983c..24232b7 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -67,12 +67,12 @@ main(void)
 	init_s(&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));
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 7/9] tests: Some additional checks for ioctl_dm test
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (29 preceding siblings ...)
  2016-10-11 22:39                         ` [PATCH 6/9] tests/ioctl_dm: overly long string printing checks Eugene Syromyatnikov
@ 2016-10-11 22:39                         ` Eugene Syromyatnikov
  2016-10-11 22:39                         ` [PATCH 8/9] tests: Add ioctl_dm to .gitignore Eugene Syromyatnikov
  2016-10-11 22:39                         ` [PATCH 9/9] tests: Add checks for abbreviated DM ioctl output Eugene Syromyatnikov
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:39 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/ioctl_dm.c |  505 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 505 insertions(+)

diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 24232b7..0b2c5a7 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -2,13 +2,26 @@
 
 #ifdef HAVE_LINUX_DM_IOCTL_H
 
+# include <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);
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 8/9] tests: Add ioctl_dm to .gitignore
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (30 preceding siblings ...)
  2016-10-11 22:39                         ` [PATCH 7/9] tests: Some additional checks for ioctl_dm test Eugene Syromyatnikov
@ 2016-10-11 22:39                         ` Eugene Syromyatnikov
  2016-10-11 22:39                         ` [PATCH 9/9] tests: Add checks for abbreviated DM ioctl output Eugene Syromyatnikov
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:39 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/.gitignore |    1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/.gitignore b/tests/.gitignore
index a6d014d..9045117 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -103,6 +103,7 @@ getxxid
 inet-cmsg
 ioctl
 ioctl_block
+ioctl_dm
 ioctl_evdev
 ioctl_evdev-v
 ioctl_mtd
-- 
1.7.10.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 9/9] tests: Add checks for abbreviated DM ioctl output
       [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                                           ` (31 preceding siblings ...)
  2016-10-11 22:39                         ` [PATCH 8/9] tests: Add ioctl_dm to .gitignore Eugene Syromyatnikov
@ 2016-10-11 22:39                         ` Eugene Syromyatnikov
  32 siblings, 0 replies; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-10-11 22:39 UTC (permalink / raw)
  To: strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, mpatocka-H+wXaHxf7aLQT0dZR+AlfA

---
 tests/.gitignore      |    1 +
 tests/Makefile.am     |    2 +
 tests/ioctl_dm-v.c    |    2 +
 tests/ioctl_dm-v.test |   12 ++++
 tests/ioctl_dm.c      |  178 +++++++++++++++++++++++++++++++++++++++----------
 tests/ioctl_dm.test   |    2 +-
 6 files changed, 160 insertions(+), 37 deletions(-)
 create mode 100644 tests/ioctl_dm-v.c
 create mode 100755 tests/ioctl_dm-v.test

diff --git a/tests/.gitignore b/tests/.gitignore
index 9045117..b2c5434 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -104,6 +104,7 @@ inet-cmsg
 ioctl
 ioctl_block
 ioctl_dm
+ioctl_dm-v
 ioctl_evdev
 ioctl_evdev-v
 ioctl_mtd
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2405415..61b6db7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -164,6 +164,7 @@ check_PROGRAMS = \
 	ioctl \
 	ioctl_block \
 	ioctl_dm \
+	ioctl_dm-v \
 	ioctl_evdev \
 	ioctl_evdev-v \
 	ioctl_mtd \
@@ -513,6 +514,7 @@ DECODER_TESTS = \
 	ioctl.test \
 	ioctl_block.test \
 	ioctl_dm.test \
+	ioctl_dm-v.test \
 	ioctl_evdev.test \
 	ioctl_evdev-v.test \
 	ioctl_mtd.test \
diff --git a/tests/ioctl_dm-v.c b/tests/ioctl_dm-v.c
new file mode 100644
index 0000000..d95058f
--- /dev/null
+++ b/tests/ioctl_dm-v.c
@@ -0,0 +1,2 @@
+#define VERBOSE 1
+#include "ioctl_dm.c"
diff --git a/tests/ioctl_dm-v.test b/tests/ioctl_dm-v.test
new file mode 100755
index 0000000..4f6d64c
--- /dev/null
+++ b/tests/ioctl_dm-v.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Check abbreviated decoding of DM* ioctls.
+
+. "${srcdir=.}/init.sh"
+
+run_prog > /dev/null
+run_strace -a16 -s9 -veioctl $args > "$EXP"
+check_prog grep
+grep -v '^ioctl([012],' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
+rm -f "$EXP" "$OUT"
diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c
index 0b2c5a7..2fcd430 100644
--- a/tests/ioctl_dm.c
+++ b/tests/ioctl_dm.c
@@ -11,6 +11,10 @@
 # include <sys/ioctl.h>
 # include <linux/dm-ioctl.h>
 
+# ifndef VERBOSE
+#  define VERBOSE 0
+# endif
+
 # define STR32 "AbCdEfGhIjKlMnOpQrStUvWxYz012345"
 
 static const char str129[] = STR32 STR32 STR32 STR32 "6";
@@ -102,6 +106,7 @@ init_dm_target_spec(struct dm_target_spec *ptr, uint32_t id)
 		ptr->target_type[id % (sizeof(ptr->target_type) + 1)] = '\0';
 }
 
+# if VERBOSE
 static void
 print_dm_target_spec(struct dm_target_spec *ptr, uint32_t id)
 {
@@ -112,6 +117,7 @@ print_dm_target_spec(struct dm_target_spec *ptr, uint32_t id)
 	       (int) (id % (sizeof(ptr->target_type) + 1)),
 	       str129 + id % (sizeof(str129) - sizeof(ptr->target_type)));
 }
+# endif /* VERBOSE */
 
 # define ARG_STR(_arg) (_arg), #_arg
 
@@ -303,9 +309,14 @@ main(void)
 	printf("ioctl(-1, DM_TABLE_LOAD, "
 	       "{version=4.1.2, data_size=%u, data_start=%u, "
 	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
-	       "target_count=1, flags=0, {sector_start=16, "
-	       "length=32, target_type=\"tgt\", string=\"tparams\"}}) = "
-	       "-1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start);
+	       "target_count=1, flags=0, "
+# if VERBOSE
+	       "{sector_start=16, length=32, target_type=\"tgt\", "
+	       "string=\"tparams\"}"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start);
 
 	/* No targets */
 	init_s(dm_arg, sizeof(*dm_arg) - sizeof(dm_arg->data),
@@ -328,8 +339,12 @@ main(void)
 	       "{version=4.1.2, data_size=%zu, data_start=%u, "
 	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
 	       "target_count=1234, flags=0, "
-	       "/* misplaced struct dm_target_spec */ ...}) = -1 EBADF (%m)\n",
-	       sizeof(*dm_arg), 0xfffffff8);
+# if VERBOSE
+	       "/* misplaced struct dm_target_spec */ ..."
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n", sizeof(*dm_arg), 0xfffffff8);
 
 	/* Inaccessible pointer */
 	init_s(&dm_arg_open1->ioc, offsetof(struct dm_table_open_test, target1),
@@ -340,11 +355,19 @@ main(void)
 	printf("ioctl(-1, DM_TABLE_LOAD, "
 	       "{version=4.1.2, data_size=%zu, data_start=%zu, "
 	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
-	       "target_count=3735936673, flags=0, %p}) = -1 EBADF (%m)\n",
-	       sizeof(*dm_arg_open1),
-	       offsetof(struct dm_table_open_test, target1),
-	       (char *) dm_arg_open1 +
-	       offsetof(struct dm_table_open_test, target1));
+	       "target_count=3735936673, flags=0, "
+# if VERBOSE
+	       "%p"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n", sizeof(*dm_arg_open1),
+	       offsetof(struct dm_table_open_test, target1)
+# if VERBOSE
+	       , (char *) dm_arg_open1 +
+	       offsetof(struct dm_table_open_test, target1)
+# endif /* VERBOSE */
+	       );
 
 	/* Inaccessible string */
 	init_s(&dm_arg_open2->ioc, offsetof(struct dm_table_open_test, param1),
@@ -363,13 +386,18 @@ main(void)
 	       "target_count=2, flags=0, ",
 	       sizeof(*dm_arg_open2),
 	       offsetof(struct dm_table_open_test, target1));
+# if VERBOSE
 	print_dm_target_spec(&dm_arg_open2->target1, 7);
-	errno = saved_errno;
-	printf("%p}, %p}) = -1 EBADF (%m)\n",
+	printf("%p}, %p",
 	       (char *) dm_arg_open2 +
 	       offsetof(struct dm_table_open_test, param1),
 	       (char *) dm_arg_open2 +
 	       offsetof(struct dm_table_open_test, target3));
+# else /* !VERBOSE */
+	printf("...");
+# endif /* VERBOSE */
+	errno = saved_errno;
+	printf("}) = -1 EBADF (%m)\n");
 
 	/* Incorrect next */
 	init_s(&dm_arg_open3->ioc, offsetof(struct dm_table_open_test, target5),
@@ -403,14 +431,19 @@ main(void)
 	       "target_count=4, flags=0, ",
 	       offsetof(struct dm_table_open_test, target5),
 	       offsetof(struct dm_table_open_test, target0));
+# if VERBOSE
 	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");
+	printf("\"\\1\\2\"}, /* misplaced struct dm_target_spec */ ...");
+# else /* !VERBOSE */
+	printf("...");
+# endif /* VERBOSE */
+	errno = saved_errno;
+	printf("}) = -1 EBADF (%m)\n");
 
 	#define FILL_DM_TARGET(id, id_next) \
 		do { \
@@ -451,6 +484,7 @@ main(void)
 	       "target_count=3134983661, flags=0, ",
 	       sizeof(*dm_arg_open3),
 	       offsetof(struct dm_table_open_test, target0));
+# if VERBOSE
 	PRINT_DM_TARGET(0);
 	PRINT_DM_TARGET(1);
 	PRINT_DM_TARGET(2);
@@ -460,6 +494,7 @@ main(void)
 	PRINT_DM_TARGET(6);
 	PRINT_DM_TARGET(7);
 	PRINT_DM_TARGET(8);
+# endif /* VERBOSE */
 	errno = saved_errno;
 	printf("...}) = -1 EBADF (%m)\n");
 
@@ -473,7 +508,12 @@ main(void)
 	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=\"long targ\"...}}) = -1 EBADF (%m)\n",
+# if VERBOSE
+	       "{sector=4660, message=\"long targ\"...}"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
 	       s.ioc.data_size, s.ioc.data_start);
 
 	/* Invalid data_start */
@@ -484,7 +524,12 @@ main(void)
 	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",
+# if VERBOSE
+	       "/* misplaced struct dm_target_msg */"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
 	       sizeof(*dm_arg), sizeof(*dm_arg) - sizeof(dm_arg->data));
 
 	/* Invalid data_start */
@@ -494,7 +539,12 @@ main(void)
 	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",
+# if VERBOSE
+	       "/* misplaced struct dm_target_msg */"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
 	       sizeof(*dm_arg), 0xffffffff);
 
 	/* Inaccessible pointer */
@@ -504,10 +554,19 @@ main(void)
 	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",
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, "
+# if VERBOSE
+	       "%p"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
 	       sizeof(*dm_arg) + sizeof(struct dm_target_msg),
-	       sizeof(*dm_arg), (char *) dm_arg + sizeof(*dm_arg));
+	       sizeof(*dm_arg)
+# if VERBOSE
+	       , (char *) dm_arg + sizeof(*dm_arg)
+# endif /* VERBOSE */
+	       );
 
 	/* Inaccessible string */
 	init_s(&dm_arg_msg->ioc, sizeof(*dm_arg_msg),
@@ -515,29 +574,41 @@ main(void)
 	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);
+	saved_errno = errno;
 	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",
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, ",
 	       sizeof(*dm_arg_msg) + 1,
-	       offsetof(struct dm_target_msg_test, msg),
+	       offsetof(struct dm_target_msg_test, msg));
+# if VERBOSE
+	printf("{sector=%" PRI__u64 ", message=%p}",
 	       (__u64) 0xdeadbeeffacef157ULL,
 	       (char *) dm_arg_msg +
 	       offsetof(struct dm_target_msg_test, msg.message));
+# else /* !VERBOSE */
+	printf("...");
+# endif /* VERBOSE */
+	errno = saved_errno;
+	printf("}) = -1 EBADF (%m)\n");
 
 	/* 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);
+	saved_errno = errno;
 	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),
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", flags=0, ",
+	       sizeof(*dm_arg_msg), offsetof(struct dm_target_msg_test, msg));
+# if VERBOSE
+	printf("{sector=%" PRI__u64 ", message=\"\"}",
 	       (__u64) 0xdeadbeeffacef157ULL);
+# else /* !VERBOSE */
+	printf("...");
+# endif /* VERBOSE */
+	errno = saved_errno;
+	printf("}) = -1 EBADF (%m)\n");
 
 
 	/* DM_DEV_SET_GEOMETRY */
@@ -547,7 +618,12 @@ 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 \"...}) = -1 EBADF (%m)\n",
+# if VERBOSE
+	       "string=\"10 20 30 \"..."
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
 	       s.ioc.data_size, s.ioc.data_start);
 
 
@@ -560,9 +636,18 @@ main(void)
 	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));
+	       "flags=0, "
+# if VERBOSE
+	       "string=%p"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
+	       sizeof(*dm_arg), sizeof(*dm_arg) - sizeof(dm_arg->data)
+# if VERBOSE
+	       , (char *) dm_arg + sizeof(*dm_arg) - sizeof(dm_arg->data)
+# endif /* VERBOSE */
+	       );
 
 	/* Incorrect data_start data */
 	init_s(&s.ioc, sizeof(s), offsetof(struct s, u));
@@ -571,7 +656,13 @@ main(void)
 	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",
+	       "flags=0, "
+# if VERBOSE
+	       "/* misplaced string */"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
 	       s.ioc.data_size);
 
 	/* Strange but still valid data_start */
@@ -582,7 +673,13 @@ main(void)
 	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",
+	       "flags=0, "
+# if VERBOSE
+	       "string=\"nn\""
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
 	       s.ioc.data_size,
 	       offsetof(struct dm_ioctl, name) + 1);
 
@@ -593,7 +690,13 @@ main(void)
 	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 long \"...}) = -1 EBADF (%m)\n",
+	       "flags=0, "
+# if VERBOSE
+	       "string=\"new long \"..."
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
 	       s.ioc.data_size, s.ioc.data_start);
 
 
@@ -605,8 +708,11 @@ main(void)
 	       "{version=4.1.2, data_size=%u, data_start=%u, "
 	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
 	       "target_count=4294967295, flags=0, "
+# if VERBOSE
 	       "{sector_start=0, length=0, target_type=\"\", string=\"\"}, "
-	       "/* misplaced struct dm_target_spec */ ...}) = -1 EBADF (%m)\n",
+	       "/* misplaced struct dm_target_spec */ "
+# endif /* VERBOSE */
+	       "...}) = -1 EBADF (%m)\n",
 	       s.ioc.data_size, s.ioc.data_start);
 
 	puts("+++ exited with 0 +++");
diff --git a/tests/ioctl_dm.test b/tests/ioctl_dm.test
index 78866d3..6485205 100755
--- a/tests/ioctl_dm.test
+++ b/tests/ioctl_dm.test
@@ -5,7 +5,7 @@
 . "${srcdir=.}/init.sh"
 
 run_prog > /dev/null
-run_strace -a16 -s9 -veioctl $args > "$EXP"
+run_strace -a16 -s9 -eioctl $args > "$EXP"
 check_prog grep
 grep -v '^ioctl([012],' < "$LOG" > "$OUT"
 match_diff "$OUT" "$EXP"
-- 
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

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH] device mapper ioctl
  2016-10-11 22:38                         ` [PATCH 0/9] Additional checks for strace DM ioctl decoder test Eugene Syromyatnikov
@ 2016-10-19 20:31                           ` Mikulas Patocka
       [not found]                             ` <alpine.LRH.2.02.1610191626360.628-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Mikulas Patocka @ 2016-10-19 20:31 UTC (permalink / raw)
  To: Eugene Syromyatnikov, Dmitry V. Levin
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f



On Wed, 12 Oct 2016, Eugene Syromyatnikov wrote:

> Hello.
> 
> Aside from additional checks themselves, this patchset also contains two
> notable changes:
>  * Fix for the previous patchset - misplaced comma printing ("dm: Fix comma
>    printing for the case when dm_target_msg structure is inaccessible").
>  * Update of printstr_ex call, which enables proper handling of
>    QUOTE_0_TERMINATED user style (it prints cropped string without ellipsis
>    otherwise).

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(-)

Index: strace/Makefile.am
===================================================================
--- strace.orig/Makefile.am
+++ strace/Makefile.am
@@ -97,6 +97,7 @@ strace_SOURCES =	\
 	desc.c		\
 	dirent.c	\
 	dirent64.c	\
+	dm.c		\
 	empty.h		\
 	epoll.c		\
 	evdev.c		\
Index: strace/configure.ac
===================================================================
--- strace.orig/configure.ac
+++ strace/configure.ac
@@ -354,6 +354,7 @@ AC_CHECK_HEADERS(m4_normalize([
 	elf.h
 	inttypes.h
 	linux/bsg.h
+	linux/dm-ioctl.h
 	linux/dqblk_xfs.h
 	linux/falloc.h
 	linux/fiemap.h
Index: strace/defs.h
===================================================================
--- strace.orig/defs.h
+++ strace/defs.h
@@ -636,6 +636,7 @@ extern void print_struct_statfs64(struct
 
 extern void print_ifindex(unsigned int);
 
+extern int dm_ioctl(struct tcb *, const unsigned int, long);
 extern int file_ioctl(struct tcb *, const unsigned int, long);
 extern int fs_x_ioctl(struct tcb *, const unsigned int, long);
 extern int loop_ioctl(struct tcb *, const unsigned int, long);
Index: strace/dm.c
===================================================================
--- /dev/null
+++ strace/dm.c
@@ -0,0 +1,552 @@
+#include "defs.h"
+
+#ifdef HAVE_LINUX_DM_IOCTL_H
+
+# include <inttypes.h>
+# include <linux/dm-ioctl.h>
+# include <sys/ioctl.h>
+
+# 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)
+{
+	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;
+			/* Fall through */
+		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, 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++) {
+		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(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 (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=%" PRIu32 ", 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(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;
+
+	if (abbrev(tcp)) {
+		tprints(", ...");
+		return;
+	}
+
+	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(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;
+
+	if (abbrev(tcp)) {
+		tprints(", ...");
+		return;
+	}
+
+	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(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 (abbrev(tcp)) {
+		tprints(", ...");
+		return;
+	}
+
+	if (offset + target_msg_message_offs > offset &&
+	    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);
+		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 */");
+	}
+}
+
+static void
+dm_decode_string(struct tcb *tcp, unsigned long addr,
+		 const struct dm_ioctl *ioc)
+{
+	uint32_t offset = ioc->data_start;
+
+	if (abbrev(tcp)) {
+		tprints(", ...");
+		return;
+	}
+
+	if (offset < ioc->data_size) {
+		tprints(", string=");
+		printstr_ex(tcp, addr + offset, ioc->data_size - offset,
+			    QUOTE_0_TERMINATED);
+	} else {
+		tprints(", /* misplaced string */");
+	}
+}
+
+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)
+{
+	struct dm_ioctl *ioc = NULL;
+	struct dm_ioctl *entering_ioc = NULL;
+	bool ioc_changed = false;
+
+	ioc = malloc(sizeof(* ioc));
+	if (!ioc)
+		return 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;
+	}
+	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;
+	}
+
+	/*
+	 * device mapper code uses %d in some places and %u in another, but
+	 * fields themselves are declared as __u32.
+	 */
+	tprintf("%s{version=%" PRIu32 ".%" PRIu32 ".%" PRIu32,
+		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
+	 */
+	if (ioc->version[0] != DM_VERSION_MAJOR) {
+		tprints(", /* Unsupported device mapper ABI version */ ...");
+		goto skip;
+	}
+
+	tprintf(", data_size=%" PRIu32, ioc->data_size);
+
+	if (dm_ioctl_has_params(code))
+		tprintf(", data_start=%" PRIu32, ioc->data_start);
+
+	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);
+
+	switch (code) {
+	case DM_DEV_WAIT:
+	case DM_TABLE_STATUS:
+		if (entering(tcp) || syserror(tcp))
+			break;
+		dm_decode_dm_target_spec(tcp, arg, ioc);
+		break;
+	case DM_TABLE_LOAD:
+		if (!entering(tcp))
+			break;
+		dm_decode_dm_target_spec(tcp, arg, ioc);
+		break;
+	case DM_TABLE_DEPS:
+		if (entering(tcp) || syserror(tcp))
+			break;
+		dm_decode_dm_target_deps(tcp, arg, ioc);
+		break;
+	case DM_LIST_DEVICES:
+		if (entering(tcp) || syserror(tcp))
+			break;
+		dm_decode_dm_name_list(tcp, arg, ioc);
+		break;
+	case DM_LIST_VERSIONS:
+		if (entering(tcp) || syserror(tcp))
+			break;
+		dm_decode_dm_target_versions(tcp, arg, ioc);
+		break;
+	case DM_TARGET_MSG:
+		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(tcp, arg, ioc);
+		break;
+	}
+
+ skip:
+	tprints("}");
+	if (exiting(tcp))
+		free(ioc);
+	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;
+	}
+}
+
+# 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 */
Index: strace/ioctl.c
===================================================================
--- strace.orig/ioctl.c
+++ strace/ioctl.c
@@ -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
===================================================================
--- strace.orig/tests/Makefile.am
+++ strace/tests/Makefile.am
@@ -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 \
Index: strace/tests/ioctl_dm.c
===================================================================
--- /dev/null
+++ strace/tests/ioctl_dm.c
@@ -0,0 +1,726 @@
+#include "tests.h"
+
+#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>
+
+# ifndef VERBOSE
+#  define VERBOSE 0
+# endif
+
+# 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 {
+		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;
+
+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)
+{
+	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");
+}
+
+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';
+}
+
+# if VERBOSE
+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)));
+}
+# endif /* VERBOSE */
+
+# 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, "
+	       "{version=4.1.2, data_size=%zu, "
+	       "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;
+	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, data_size=%u, data_start=%u, "
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
+	       "target_count=1, flags=0, "
+# if VERBOSE
+	       "{sector_start=16, length=32, target_type=\"tgt\", "
+	       "string=\"tparams\"}"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n", s.ioc.data_size, s.ioc.data_start);
+
+	/* No targets */
+	init_s(dm_arg, sizeof(*dm_arg) - sizeof(dm_arg->data),
+		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, "
+# if VERBOSE
+	       "/* misplaced struct dm_target_spec */ ..."
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -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, "
+# if VERBOSE
+	       "%p"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n", sizeof(*dm_arg_open1),
+	       offsetof(struct dm_table_open_test, target1)
+# if VERBOSE
+	       , (char *) dm_arg_open1 +
+	       offsetof(struct dm_table_open_test, target1)
+# endif /* VERBOSE */
+	       );
+
+	/* 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));
+# if VERBOSE
+	print_dm_target_spec(&dm_arg_open2->target1, 7);
+	printf("%p}, %p",
+	       (char *) dm_arg_open2 +
+	       offsetof(struct dm_table_open_test, param1),
+	       (char *) dm_arg_open2 +
+	       offsetof(struct dm_table_open_test, target3));
+# else /* !VERBOSE */
+	printf("...");
+# endif /* VERBOSE */
+	errno = saved_errno;
+	printf("}) = -1 EBADF (%m)\n");
+
+	/* 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->param3[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));
+# if VERBOSE
+	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 */ ...");
+# else /* !VERBOSE */
+	printf("...");
+# endif /* VERBOSE */
+	errno = saved_errno;
+	printf("}) = -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));
+# if VERBOSE
+	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);
+# endif /* VERBOSE */
+	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),
+		"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, "
+# if VERBOSE
+	       "{sector=4660, message=\"long targ\"...}"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -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, "
+# if VERBOSE
+	       "/* misplaced struct dm_target_msg */"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -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, "
+# if VERBOSE
+	       "/* misplaced struct dm_target_msg */"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -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, "
+# if VERBOSE
+	       "%p"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
+	       sizeof(*dm_arg) + sizeof(struct dm_target_msg),
+	       sizeof(*dm_arg)
+# if VERBOSE
+	       , (char *) dm_arg + sizeof(*dm_arg)
+# endif /* VERBOSE */
+	       );
+
+	/* 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);
+	saved_errno = errno;
+	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, ",
+	       sizeof(*dm_arg_msg) + 1,
+	       offsetof(struct dm_target_msg_test, msg));
+# if VERBOSE
+	printf("{sector=%" PRI__u64 ", message=%p}",
+	       (__u64) 0xdeadbeeffacef157ULL,
+	       (char *) dm_arg_msg +
+	       offsetof(struct dm_target_msg_test, msg.message));
+# else /* !VERBOSE */
+	printf("...");
+# endif /* VERBOSE */
+	errno = saved_errno;
+	printf("}) = -1 EBADF (%m)\n");
+
+	/* 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);
+	saved_errno = errno;
+	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, ",
+	       sizeof(*dm_arg_msg), offsetof(struct dm_target_msg_test, msg));
+# if VERBOSE
+	printf("{sector=%" PRI__u64 ", message=\"\"}",
+	       (__u64) 0xdeadbeeffacef157ULL);
+# else /* !VERBOSE */
+	printf("...");
+# endif /* VERBOSE */
+	errno = saved_errno;
+	printf("}) = -1 EBADF (%m)\n");
+
+
+	/* 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);
+	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, "
+# if VERBOSE
+	       "string=\"10 20 30 \"..."
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -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, "
+# if VERBOSE
+	       "string=%p"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -1 EBADF (%m)\n",
+	       sizeof(*dm_arg), sizeof(*dm_arg) - sizeof(dm_arg->data)
+# if VERBOSE
+	       , (char *) dm_arg + sizeof(*dm_arg) - sizeof(dm_arg->data)
+# endif /* VERBOSE */
+	       );
+
+	/* 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, "
+# if VERBOSE
+	       "/* misplaced string */"
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -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, "
+# if VERBOSE
+	       "string=\"nn\""
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -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);
+	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, "
+# if VERBOSE
+	       "string=\"new long \"..."
+# else /* !VERBOSE */
+	       "..."
+# endif /* VERBOSE */
+	       "}) = -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);
+	printf("ioctl(-1, DM_TABLE_LOAD, "
+	       "{version=4.1.2, data_size=%u, data_start=%u, "
+	       "dev=makedev(18, 52), name=\"nnn\", uuid=\"uuu\", "
+	       "target_count=4294967295, flags=0, "
+# if VERBOSE
+	       "{sector_start=0, length=0, target_type=\"\", string=\"\"}, "
+	       "/* misplaced struct dm_target_spec */ "
+# endif /* VERBOSE */
+	       "...}) = -1 EBADF (%m)\n",
+	       s.ioc.data_size, s.ioc.data_start);
+
+	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 */
Index: strace/tests/ioctl_dm.test
===================================================================
--- /dev/null
+++ strace/tests/ioctl_dm.test
@@ -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"
Index: strace/xlat/dm_flags.in
===================================================================
--- /dev/null
+++ strace/xlat/dm_flags.in
@@ -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)
Index: strace/util.c
===================================================================
--- strace.orig/util.c
+++ strace/util.c
@@ -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 & QUOTE_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 & QUOTE_0_TERMINATED) ||
+				(unsigned long) len > max_strlen));
 
 	tprints(outstr);
 	if (ellipsis)
Index: strace/tests/.gitignore
===================================================================
--- strace.orig/tests/.gitignore
+++ strace/tests/.gitignore
@@ -103,6 +103,8 @@ getxxid
 inet-cmsg
 ioctl
 ioctl_block
+ioctl_dm
+ioctl_dm-v
 ioctl_evdev
 ioctl_evdev-v
 ioctl_mtd
Index: strace/tests/ioctl_dm-v.c
===================================================================
--- /dev/null
+++ strace/tests/ioctl_dm-v.c
@@ -0,0 +1,2 @@
+#define VERBOSE 1
+#include "ioctl_dm.c"
Index: strace/tests/ioctl_dm-v.test
===================================================================
--- /dev/null
+++ strace/tests/ioctl_dm-v.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Check abbreviated decoding of DM* ioctls.
+
+. "${srcdir=.}/init.sh"
+
+run_prog > /dev/null
+run_strace -a16 -s9 -veioctl $args > "$EXP"
+check_prog grep
+grep -v '^ioctl([012],' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
+rm -f "$EXP" "$OUT"

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] device mapper ioctl
       [not found]                             ` <alpine.LRH.2.02.1610191626360.628-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
@ 2016-11-10 21:01                               ` Eugene Syromyatnikov
       [not found]                                 ` <CACGkJdts9AKHnXb+b6J2kfpDNZJZW12WaNaYukrA11PHtAydag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Eugene Syromyatnikov @ 2016-11-10 21:01 UTC (permalink / raw)
  To: Mikulas Patocka; +Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA, strace development list

On Wed, Oct 19, 2016 at 8:31 PM, Mikulas Patocka <mpatocka-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>
> Hi
>
> Here I'm sending the device mapper ioctl patch with these changes merged.

Hello.

Thank you for your contribution. The implementation of DM_* ioctl
decoding is now in strace's master, you can check it out at
https://github.com/strace/strace/commit/a507a0bb777c552e43e1e45f302703a09ffea1b8

Could you please review it and let us know if there are any issues?

> In this piece of code:
> +       dm_arg_open3->target3.next = 0xdeadbeef;
> +       dm_arg_open3->param3[0] = '\1';
> +       dm_arg_open3->param3[1] = '\2';
> +       dm_arg_open3->param1[2] = '\0';
> there should be "dm_arg_open3->param3[2]" instead of
> "dm_arg_open3->param1[2]". "dm_arg_open3->param1[2]" produces a warning
> about access beyond the end of array.
Thank you for noticing, it was an oversight on my part.

> Mikulas


-- 
Eugene "eSyr" Syromyatnikov
mailto:evgSyr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
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

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] device mapper ioctl
       [not found]                                 ` <CACGkJdts9AKHnXb+b6J2kfpDNZJZW12WaNaYukrA11PHtAydag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-11-11  3:13                                   ` Masatake YAMATO
  0 siblings, 0 replies; 41+ messages in thread
From: Masatake YAMATO @ 2016-11-11  3:13 UTC (permalink / raw)
  To: evgsyr-Re5JQEeQqe8AvxtiuMwx3w
  Cc: dm-devel-H+wXaHxf7aLQT0dZR+AlfA,
	strace-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	mpatocka-H+wXaHxf7aLQT0dZR+AlfA

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

> 
>> In this piece of code:
>> +       dm_arg_open3->target3.next = 0xdeadbeef;
>> +       dm_arg_open3->param3[0] = '\1';
>> +       dm_arg_open3->param3[1] = '\2';
>> +       dm_arg_open3->param1[2] = '\0';
>> there should be "dm_arg_open3->param3[2]" instead of
>> "dm_arg_open3->param1[2]". "dm_arg_open3->param1[2]" produces a warning
>> about access beyond the end of array.
> Thank you for noticing, it was an oversight on my part.
> 
>> Mikulas
> 
> 
> -- 
> Eugene "eSyr" Syromyatnikov
> mailto:evgSyr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
> 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

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2016-11-11  3:13 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <alpine.LRH.2.02.1608221155410.17400@file01.intranet.prod.int.rdu2.redhat.com>
     [not found] ` <20160822170920.GA5147@altlinux.org>
     [not found]   ` <alpine.LRH.2.02.1608231303510.7049@file01.intranet.prod.int.rdu2.redhat.com>
     [not found]     ` <20160824.233543.198328104871315294.yamato@redhat.com>
     [not found]       ` <20160824.233543.198328104871315294.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-08-25 12:27         ` [PATCH] Re: your dm patch for strace Mikulas Patocka
     [not found]           ` <alpine.LRH.2.02.1608250823130.24332-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
2016-09-12 17:10             ` Dmitry V. Levin
     [not found]               ` <20160912171029.GA5263-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
2016-10-02 21:59                 ` Mikulas Patocka
     [not found]                   ` <alpine.LRH.2.02.1610021751280.29417-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
2016-10-05 10:28                     ` Masatake YAMATO
     [not found]                       ` <20161005.192828.566127461630656590.yamato-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-09 13:27                         ` [PATCH 00/21] Some possible additions to the DM ioctl " Eugene Syromyatnikov
2016-10-09 13:28                         ` [PATCH 01/21] tests/ioctl_dm: Formatting Eugene Syromyatnikov
2016-10-09 13:28                         ` [PATCH 02/21] dm: whitespace fixes Eugene Syromyatnikov
2016-10-09 13:28                         ` [PATCH 03/21] tests: Working around bounds check Eugene Syromyatnikov
2016-10-09 13:28                         ` [PATCH 04/21] dm: Minor output tweaks Eugene Syromyatnikov
2016-10-09 13:29                         ` [PATCH 05/21] xlat: Add values for dm_flags Eugene Syromyatnikov
2016-10-09 13:29                         ` [PATCH 06/21] dm: Some future-proofing by means of compile-time DM_VERSION_MAJOR check Eugene Syromyatnikov
2016-10-09 13:29                         ` [PATCH 07/21] dm: Add definitions for ioctl commands not implemented initially Eugene Syromyatnikov
2016-10-09 13:30                         ` [PATCH 08/21] dm: Use static constants for offset sizes Eugene Syromyatnikov
2016-10-09 13:30                         ` [PATCH 09/21] dm: Remove char * cast Eugene Syromyatnikov
2016-10-09 13:30                         ` [PATCH 10/21] dm: use => instead of , for splitting output structure from input Eugene Syromyatnikov
2016-10-09 13:30                         ` [PATCH 11/21] dm: Compare entering field values with exiting ones Eugene Syromyatnikov
2016-10-09 13:30                         ` [PATCH 12/21] dm: Add inttypes.h, include reorder Eugene Syromyatnikov
2016-10-09 13:30                         ` [PATCH 13/21] dm: Move printing of dm_ioctl fields before allocation of extra data Eugene Syromyatnikov
2016-10-09 13:30                         ` [PATCH 14/21] dm: replace abbrev branching with goto Eugene Syromyatnikov
2016-10-09 13:31                         ` [PATCH 15/21] dm: Additional data_size/data_start checks Eugene Syromyatnikov
2016-10-09 13:31                         ` [PATCH 16/21] dm: Add comment regarding intended fall-through in switch statement Eugene Syromyatnikov
2016-10-09 13:31                         ` [PATCH 17/21] dm: Add data_size and data_offset fields to output Eugene Syromyatnikov
2016-10-09 13:31                         ` [PATCH 18/21] tests/ioctl_dm: Allow passing size and data_start to init_s Eugene Syromyatnikov
2016-10-09 13:31                         ` [PATCH 19/21] dm: Add check whether command uses parameters Eugene Syromyatnikov
2016-10-09 13:31                         ` [PATCH 20/21] dm: Fix printing of version field Eugene Syromyatnikov
2016-10-09 13:31                         ` [PATCH 21/21] dm: rewrite structure decoding Eugene Syromyatnikov
2016-10-10 10:27                         ` [PATCH] Re: your dm patch for strace Mikulas Patocka
2016-10-11 22:38                         ` [PATCH 0/9] Additional checks for strace DM ioctl decoder test Eugene Syromyatnikov
2016-10-19 20:31                           ` [PATCH] device mapper ioctl Mikulas Patocka
     [not found]                             ` <alpine.LRH.2.02.1610191626360.628-Hpncn10jQN4oNljnaZt3ZvA+iT7yCHsGwRM8/txMwJMAicBL8TP8PQ@public.gmane.org>
2016-11-10 21:01                               ` Eugene Syromyatnikov
     [not found]                                 ` <CACGkJdts9AKHnXb+b6J2kfpDNZJZW12WaNaYukrA11PHtAydag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-11-11  3:13                                   ` Masatake YAMATO
2016-10-11 22:38                         ` [PATCH 1/9] util: Add support for QUOTE_0_TERMINATED in user_style to ptrintstr_ex Eugene Syromyatnikov
2016-10-11 22:38                         ` [PATCH 2/9] tests: Add check for printing of overlength strings to ioctl_dm test Eugene Syromyatnikov
2016-10-11 22:38                         ` [PATCH 3/9] tests: Add check for presence of HAVE_LINUX_DM_IOCTL_H macro definition " Eugene Syromyatnikov
2016-10-11 22:38                         ` [PATCH 4/9] tests/ioctl_dm: whitespace Eugene Syromyatnikov
2016-10-11 22:38                         ` [PATCH 5/9] dm: Fix comma printing for the case when dm_target_msg structure is inaccessible Eugene Syromyatnikov
2016-10-11 22:39                         ` [PATCH 6/9] tests/ioctl_dm: overly long string printing checks Eugene Syromyatnikov
2016-10-11 22:39                         ` [PATCH 7/9] tests: Some additional checks for ioctl_dm test Eugene Syromyatnikov
2016-10-11 22:39                         ` [PATCH 8/9] tests: Add ioctl_dm to .gitignore Eugene Syromyatnikov
2016-10-11 22:39                         ` [PATCH 9/9] tests: Add checks for abbreviated DM ioctl output Eugene Syromyatnikov
2016-10-08 17:45                   ` [PATCH] Re: your dm patch for strace Eugene Syromyatnikov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.