/*
 *  Copyright (c) 2008-2010 Sun Microsystems, Inc.
 *  Written by Ricardo Correia <Ricardo.M.Correia@Sun.COM>
 *
 *  This file is part of the SPL, Solaris Porting Layer.
 *  For details, see <http://zfsonlinux.org/>.
 *
 *  The SPL is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 2 of the License, or (at your
 *  option) any later version.
 *
 *  The SPL is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  Solaris Porting Layer (SPL) XDR Implementation.
 */

#include <linux/string.h>
#include <sys/kmem.h>
#include <sys/debug.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <rpc/xdr.h>

/*
 * SPL's XDR mem implementation.
 *
 * This is used by libnvpair to serialize/deserialize the name-value pair data
 * structures into byte arrays in a well-defined and portable manner.
 *
 * These data structures are used by the DMU/ZFS to flexibly manipulate various
 * information in memory and later serialize it/deserialize it to disk.
 * Examples of usages include the pool configuration, lists of pool and dataset
 * properties, etc.
 *
 * Reference documentation for the XDR representation and XDR operations can be
 * found in RFC 1832 and xdr(3), respectively.
 *
 * ===  Implementation shortcomings ===
 *
 * It is assumed that the following C types have the following sizes:
 *
 * char/unsigned char:      1 byte
 * short/unsigned short:    2 bytes
 * int/unsigned int:        4 bytes
 * longlong_t/u_longlong_t: 8 bytes
 *
 * The C standard allows these types to be larger (and in the case of ints,
 * shorter), so if that is the case on some compiler/architecture, the build
 * will fail (on purpose).
 *
 * If someone wants to fix the code to work properly on such environments, then:
 *
 * 1) Preconditions should be added to xdrmem_enc functions to make sure the
 *    caller doesn't pass arguments which exceed the expected range.
 * 2) Functions which take signed integers should be changed to properly do
 *    sign extension.
 * 3) For ints with less than 32 bits, well.. I suspect you'll have bigger
 *    problems than this implementation.
 *
 * It is also assumed that:
 *
 * 1) Chars have 8 bits.
 * 2) We can always do 32-bit-aligned int memory accesses and byte-aligned
 *    memcpy, memset and memcmp.
 * 3) Arrays passed to xdr_array() are packed and the compiler/architecture
 *    supports element-sized-aligned memory accesses.
 * 4) Negative integers are natively stored in two's complement binary
 *    representation.
 *
 * No checks are done for the 4 assumptions above, though.
 *
 * === Caller expectations ===
 *
 * Existing documentation does not describe the semantics of XDR operations very
 * well.  Therefore, some assumptions about failure semantics will be made and
 * will be described below:
 *
 * 1) If any encoding operation fails (e.g., due to lack of buffer space), the
 * the stream should be considered valid only up to the encoding operation
 * previous to the one that first failed. However, the stream size as returned
 * by xdr_control() cannot be considered to be strictly correct (it may be
 * bigger).
 *
 * Putting it another way, if there is an encoding failure it's undefined
 * whether anything is added to the stream in that operation and therefore
 * neither xdr_control() nor future encoding operations on the same stream can
 * be relied upon to produce correct results.
 *
 * 2) If a decoding operation fails, it's undefined whether anything will be
 * decoded into passed buffers/pointers during that operation, or what the
 * values on those buffers will look like.
 *
 * Future decoding operations on the same stream will also have similar
 * undefined behavior.
 *
 * 3) When the first decoding operation fails it is OK to trust the results of
 * previous decoding operations on the same stream, as long as the caller
 * expects a failure to be possible (e.g. due to end-of-stream).
 *
 * However, this is highly discouraged because the caller should know the
 * stream size and should be coded to expect any decoding failure to be data
 * corruption due to hardware, accidental or even malicious causes, which should
 * be handled gracefully in all cases.
 *
 * In very rare situations where there are strong reasons to believe the data
 * can be trusted to be valid and non-tampered with, then the caller may assume
 * a decoding failure to be a bug (e.g. due to mismatched data types) and may
 * fail non-gracefully.
 *
 * 4) Non-zero padding bytes will cause the decoding operation to fail.
 *
 * 5) Zero bytes on string types will also cause the decoding operation to fail.
 *
 * 6) It is assumed that either the pointer to the stream buffer given by the
 * caller is 32-bit aligned or the architecture supports non-32-bit-aligned int
 * memory accesses.
 *
 * 7) The stream buffer and encoding/decoding buffers/ptrs should not overlap.
 *
 * 8) If a caller passes pointers to non-kernel memory (e.g., pointers to user
 * space or MMIO space), the computer may explode.
 */

static struct xdr_ops xdrmem_encode_ops;
static struct xdr_ops xdrmem_decode_ops;

void
xdrmem_create(XDR *xdrs, const caddr_t addr, const uint_t size,
    const enum xdr_op op)
{
	switch (op) {
		case XDR_ENCODE:
			xdrs->x_ops = &xdrmem_encode_ops;
			break;
		case XDR_DECODE:
			xdrs->x_ops = &xdrmem_decode_ops;
			break;
		default:
			xdrs->x_ops = NULL; /* Let the caller know we failed */
			return;
	}

	xdrs->x_op = op;
	xdrs->x_addr = addr;
	xdrs->x_addr_end = addr + size;

	if (xdrs->x_addr_end < xdrs->x_addr) {
		xdrs->x_ops = NULL;
	}
}
EXPORT_SYMBOL(xdrmem_create);

static bool_t
xdrmem_control(XDR *xdrs, int req, void *info)
{
	struct xdr_bytesrec *rec = (struct xdr_bytesrec *)info;

	if (req != XDR_GET_BYTES_AVAIL)
		return (FALSE);

	rec->xc_is_last_record = TRUE; /* always TRUE in xdrmem streams */
	rec->xc_num_avail = xdrs->x_addr_end - xdrs->x_addr;

	return (TRUE);
}

static bool_t
xdrmem_enc_bytes(XDR *xdrs, caddr_t cp, const uint_t cnt)
{
	uint_t size = roundup(cnt, 4);
	uint_t pad;

	if (size < cnt)
		return (FALSE); /* Integer overflow */

	if (xdrs->x_addr > xdrs->x_addr_end)
		return (FALSE);

	if (xdrs->x_addr_end - xdrs->x_addr < size)
		return (FALSE);

	memcpy(xdrs->x_addr, cp, cnt);

	xdrs->x_addr += cnt;

	pad = size - cnt;
	if (pad > 0) {
		memset(xdrs->x_addr, 0, pad);
		xdrs->x_addr += pad;
	}

	return (TRUE);
}

static bool_t
xdrmem_dec_bytes(XDR *xdrs, caddr_t cp, const uint_t cnt)
{
	static uint32_t zero = 0;
	uint_t size = roundup(cnt, 4);
	uint_t pad;

	if (size < cnt)
		return (FALSE); /* Integer overflow */

	if (xdrs->x_addr > xdrs->x_addr_end)
		return (FALSE);

	if (xdrs->x_addr_end - xdrs->x_addr < size)
		return (FALSE);

	memcpy(cp, xdrs->x_addr, cnt);
	xdrs->x_addr += cnt;

	pad = size - cnt;
	if (pad > 0) {
		/* An inverted memchr() would be useful here... */
		if (memcmp(&zero, xdrs->x_addr, pad) != 0)
			return (FALSE);

		xdrs->x_addr += pad;
	}

	return (TRUE);
}

static bool_t
xdrmem_enc_uint32(XDR *xdrs, uint32_t val)
{
	if (xdrs->x_addr + sizeof (uint32_t) > xdrs->x_addr_end)
		return (FALSE);

	*((uint32_t *)xdrs->x_addr) = cpu_to_be32(val);

	xdrs->x_addr += sizeof (uint32_t);

	return (TRUE);
}

static bool_t
xdrmem_dec_uint32(XDR *xdrs, uint32_t *val)
{
	if (xdrs->x_addr + sizeof (uint32_t) > xdrs->x_addr_end)
		return (FALSE);

	*val = be32_to_cpu(*((uint32_t *)xdrs->x_addr));

	xdrs->x_addr += sizeof (uint32_t);

	return (TRUE);
}

static bool_t
xdrmem_enc_char(XDR *xdrs, char *cp)
{
	uint32_t val;

	BUILD_BUG_ON(sizeof (char) != 1);
	val = *((unsigned char *) cp);

	return (xdrmem_enc_uint32(xdrs, val));
}

static bool_t
xdrmem_dec_char(XDR *xdrs, char *cp)
{
	uint32_t val;

	BUILD_BUG_ON(sizeof (char) != 1);

	if (!xdrmem_dec_uint32(xdrs, &val))
		return (FALSE);

	/*
	 * If any of the 3 other bytes are non-zero then val will be greater
	 * than 0xff and we fail because according to the RFC, this block does
	 * not have a char encoded in it.
	 */
	if (val > 0xff)
		return (FALSE);

	*((unsigned char *) cp) = val;

	return (TRUE);
}

static bool_t
xdrmem_enc_ushort(XDR *xdrs, unsigned short *usp)
{
	BUILD_BUG_ON(sizeof (unsigned short) != 2);

	return (xdrmem_enc_uint32(xdrs, *usp));
}

static bool_t
xdrmem_dec_ushort(XDR *xdrs, unsigned short *usp)
{
	uint32_t val;

	BUILD_BUG_ON(sizeof (unsigned short) != 2);

	if (!xdrmem_dec_uint32(xdrs, &val))
		return (FALSE);

	/*
	 * Short ints are not in the RFC, but we assume similar logic as in
	 * xdrmem_dec_char().
	 */
	if (val > 0xffff)
		return (FALSE);

	*usp = val;

	return (TRUE);
}

static bool_t
xdrmem_enc_uint(XDR *xdrs, unsigned *up)
{
	BUILD_BUG_ON(sizeof (unsigned) != 4);

	return (xdrmem_enc_uint32(xdrs, *up));
}

static bool_t
xdrmem_dec_uint(XDR *xdrs, unsigned *up)
{
	BUILD_BUG_ON(sizeof (unsigned) != 4);

	return (xdrmem_dec_uint32(xdrs, (uint32_t *)up));
}

static bool_t
xdrmem_enc_ulonglong(XDR *xdrs, u_longlong_t *ullp)
{
	BUILD_BUG_ON(sizeof (u_longlong_t) != 8);

	if (!xdrmem_enc_uint32(xdrs, *ullp >> 32))
		return (FALSE);

	return (xdrmem_enc_uint32(xdrs, *ullp & 0xffffffff));
}

static bool_t
xdrmem_dec_ulonglong(XDR *xdrs, u_longlong_t *ullp)
{
	uint32_t low, high;

	BUILD_BUG_ON(sizeof (u_longlong_t) != 8);

	if (!xdrmem_dec_uint32(xdrs, &high))
		return (FALSE);
	if (!xdrmem_dec_uint32(xdrs, &low))
		return (FALSE);

	*ullp = ((u_longlong_t)high << 32) | low;

	return (TRUE);
}

static bool_t
xdr_enc_array(XDR *xdrs, caddr_t *arrp, uint_t *sizep, const uint_t maxsize,
    const uint_t elsize, const xdrproc_t elproc)
{
	uint_t i;
	caddr_t addr = *arrp;

	if (*sizep > maxsize || *sizep > UINT_MAX / elsize)
		return (FALSE);

	if (!xdrmem_enc_uint(xdrs, sizep))
		return (FALSE);

	for (i = 0; i < *sizep; i++) {
		if (!elproc(xdrs, addr))
			return (FALSE);
		addr += elsize;
	}

	return (TRUE);
}

static bool_t
xdr_dec_array(XDR *xdrs, caddr_t *arrp, uint_t *sizep, const uint_t maxsize,
    const uint_t elsize, const xdrproc_t elproc)
{
	uint_t i, size;
	bool_t alloc = FALSE;
	caddr_t addr;

	if (!xdrmem_dec_uint(xdrs, sizep))
		return (FALSE);

	size = *sizep;

	if (size > maxsize || size > UINT_MAX / elsize)
		return (FALSE);

	/*
	 * The Solaris man page says: "If *arrp is NULL when decoding,
	 * xdr_array() allocates memory and *arrp points to it".
	 */
	if (*arrp == NULL) {
		BUILD_BUG_ON(sizeof (uint_t) > sizeof (size_t));

		*arrp = kmem_alloc(size * elsize, KM_NOSLEEP);
		if (*arrp == NULL)
			return (FALSE);

		alloc = TRUE;
	}

	addr = *arrp;

	for (i = 0; i < size; i++) {
		if (!elproc(xdrs, addr)) {
			if (alloc)
				kmem_free(*arrp, size * elsize);
			return (FALSE);
		}
		addr += elsize;
	}

	return (TRUE);
}

static bool_t
xdr_enc_string(XDR *xdrs, char **sp, const uint_t maxsize)
{
	size_t slen = strlen(*sp);
	uint_t len;

	if (slen > maxsize)
		return (FALSE);

	len = slen;

	if (!xdrmem_enc_uint(xdrs, &len))
		return (FALSE);

	return (xdrmem_enc_bytes(xdrs, *sp, len));
}

static bool_t
xdr_dec_string(XDR *xdrs, char **sp, const uint_t maxsize)
{
	uint_t size;
	bool_t alloc = FALSE;

	if (!xdrmem_dec_uint(xdrs, &size))
		return (FALSE);

	if (size > maxsize || size > UINT_MAX - 1)
		return (FALSE);

	/*
	 * Solaris man page: "If *sp is NULL when decoding, xdr_string()
	 * allocates memory and *sp points to it".
	 */
	if (*sp == NULL) {
		BUILD_BUG_ON(sizeof (uint_t) > sizeof (size_t));

		*sp = kmem_alloc(size + 1, KM_NOSLEEP);
		if (*sp == NULL)
			return (FALSE);

		alloc = TRUE;
	}

	if (!xdrmem_dec_bytes(xdrs, *sp, size))
		goto fail;

	if (memchr(*sp, 0, size) != NULL)
		goto fail;

	(*sp)[size] = '\0';

	return (TRUE);

fail:
	if (alloc)
		kmem_free(*sp, size + 1);

	return (FALSE);
}

static struct xdr_ops xdrmem_encode_ops = {
	.xdr_control		= xdrmem_control,
	.xdr_char		= xdrmem_enc_char,
	.xdr_u_short		= xdrmem_enc_ushort,
	.xdr_u_int		= xdrmem_enc_uint,
	.xdr_u_longlong_t	= xdrmem_enc_ulonglong,
	.xdr_opaque		= xdrmem_enc_bytes,
	.xdr_string		= xdr_enc_string,
	.xdr_array		= xdr_enc_array
};

static struct xdr_ops xdrmem_decode_ops = {
	.xdr_control		= xdrmem_control,
	.xdr_char		= xdrmem_dec_char,
	.xdr_u_short		= xdrmem_dec_ushort,
	.xdr_u_int		= xdrmem_dec_uint,
	.xdr_u_longlong_t	= xdrmem_dec_ulonglong,
	.xdr_opaque		= xdrmem_dec_bytes,
	.xdr_string		= xdr_dec_string,
	.xdr_array		= xdr_dec_array
};
