/*
 * Support for decoding of DM_* ioctl commands.
 *
 * Copyright (c) 2016 Mikulas Patocka <mpatocka@redhat.com>
 * Copyright (c) 2016 Masatake Yamato <yamato@redhat.com>
 * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "defs.h"

#ifdef HAVE_LINUX_DM_IOCTL_H

# include <linux/dm-ioctl.h>
# include <linux/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) {
			tprints(", dev=");
			print_dev_t(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 *const tcp, const kernel_ulong_t addr,
			 const struct dm_ioctl *const ioc)
{
	static const uint32_t target_spec_size =
		sizeof(struct dm_target_spec);
	uint32_t i;
	uint32_t offset = ioc->data_start;
	uint32_t offset_end;

	if (abbrev(tcp)) {
		if (ioc->target_count)
			tprints(", ...");

		return;
	}

	for (i = 0; i < ioc->target_count; i++) {
		struct dm_target_spec s;

		offset_end = offset + target_spec_size;

		if (offset_end <= offset || offset_end > 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 (exiting(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_end, ioc->data_size - offset_end,
			     QUOTE_0_TERMINATED);
		tprintf("}");

		if (entering(tcp))
			offset += s.next;
		else
			offset = ioc->data_start + s.next;

		if (offset <= offset_end)
			goto misplaced;
	}

	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;

	print_dev_t(*dev);

	return 1;
}

static void
dm_decode_dm_target_deps(struct tcb *const tcp, const kernel_ulong_t addr,
			 const struct dm_ioctl *const 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 offset_end = offset + target_deps_dev_offs;
	uint32_t space;

	if (abbrev(tcp)) {
		tprints(", ...");
		return;
	}

	tprints(", ");

	if (offset_end <= offset || offset_end > ioc->data_size)
		goto misplaced;

	if (umove_or_printaddr(tcp, addr + offset, &s))
		return;

	space = (ioc->data_size - offset_end) / sizeof(dev_buf);

	if (s.count > space)
		goto misplaced;

	tprintf("{count=%u, deps=", s.count);

	print_array(tcp, addr + offset_end, 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 *const tcp, const kernel_ulong_t addr,
		       const struct dm_ioctl *const 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 offset_end;
	uint32_t count;

	if (abbrev(tcp)) {
		tprints(", ...");
		return;
	}

	for (count = 0;; count++) {
		offset_end = offset + name_list_name_offs;

		if (offset_end <= offset || offset_end > 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;
		}

		tprints("{dev=");
		print_dev_t(s.dev);

		tprints("name=");
		printstr_ex(tcp, addr + offset_end, ioc->data_size - offset_end,
			    QUOTE_0_TERMINATED);
		tprints("}");

		if (!s.next)
			break;

		offset += s.next;
		if (offset <= offset_end)
			goto misplaced;
	}

	return;

misplaced:
	tprints(", /* misplaced struct dm_name_list */ ...");
}

static void
dm_decode_dm_target_versions(struct tcb *const tcp, const kernel_ulong_t addr,
			     const struct dm_ioctl *const 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 offset_end;
	uint32_t count;

	if (abbrev(tcp)) {
		tprints(", ...");
		return;
	}

	for (count = 0;; count++) {
		offset_end = offset + target_vers_name_offs;

		if (offset_end <= offset || offset_end > 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_end, ioc->data_size - offset_end,
			    QUOTE_0_TERMINATED);
		tprintf(", version=%" PRIu32 ".%" PRIu32 ".%" PRIu32 "}",
			s.version[0], s.version[1], s.version[2]);

		if (!s.next)
			break;

		offset += s.next;
		if (offset <= offset_end)
			goto misplaced;
	}

	return;

misplaced:
	tprints(", /* misplaced struct dm_target_versions */ ...");
}

static void
dm_decode_dm_target_msg(struct tcb *const tcp, const kernel_ulong_t addr,
		        const struct dm_ioctl *const ioc)
{
	static const uint32_t target_msg_message_offs =
		offsetof(struct dm_target_msg, message);
	uint32_t offset = ioc->data_start;
	uint32_t offset_end = offset + target_msg_message_offs;

	if (abbrev(tcp)) {
		tprints(", ...");
		return;
	}

	if (offset_end > offset && offset_end <= 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_end, ioc->data_size - offset_end,
			    QUOTE_0_TERMINATED);
		tprints("}");
	} else {
		tprints(", /* misplaced struct dm_target_msg */");
	}
}

static void
dm_decode_string(struct tcb *const tcp, const kernel_ulong_t addr,
		 const struct dm_ioctl *const 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 *const tcp, const unsigned int code,
	       const kernel_ulong_t arg)
{
	struct dm_ioctl *ioc = NULL;
	struct dm_ioctl *entering_ioc = NULL;
	bool ioc_changed = false;

	if (entering(tcp)) {
		ioc = malloc(sizeof(*ioc));
		if (!ioc)
			return 0;
	} else {
		ioc = alloca(sizeof(*ioc));
	}

	if ((umoven(tcp, arg, offsetof(struct dm_ioctl, data), ioc) < 0) ||
	    (ioc->data_size < offsetof(struct dm_ioctl, data_size))) {
		if (entering(tcp))
			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)
		return 1;

	/*
	 * 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
	 * ioctl fields
	 */
	if (ioc->version[0] != DM_VERSION_MAJOR) {
		tprints(", /* Unsupported device mapper ABI version */ ...");
		goto skip;
	}

	tprintf(", data_size=%u", ioc->data_size);

	if (dm_ioctl_has_params(code))
		tprintf(", data_start=%u", ioc->data_start);

	if (ioc->data_size < offsetof(struct dm_ioctl, 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 (exiting(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 (exiting(tcp))
			break;
		dm_decode_string(tcp, arg, ioc);
		break;
	}

 skip:
	tprints("}");
	return 1;
}

int
dm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t 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 *const tcp, const unsigned int code, const kernel_ulong_t arg)
{
	return 0;
}

# endif /* DM_VERSION_MAJOR == 4 */
#endif /* HAVE_LINUX_DM_IOCTL_H */
