[PATCH] Re: your dm patch for strace
Dmitry V. Levin
ldv at altlinux.org
Mon Sep 12 17:10:29 UTC 2016
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20160912/69748f24/attachment.bin>
More information about the Strace-devel
mailing list