// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */

#include "libxfs.h"
#include <ctype.h>
#include <time.h>
#include "bit.h"
#include "block.h"
#include "command.h"
#include "type.h"
#include "faddr.h"
#include "fprint.h"
#include "field.h"
#include "flist.h"
#include "io.h"
#include "init.h"
#include "output.h"
#include "print.h"
#include "write.h"
#include "malloc.h"
#include "fuzz.h"

static int	fuzz_f(int argc, char **argv);
static void     fuzz_help(void);

static const cmdinfo_t	fuzz_cmd =
	{ "fuzz", NULL, fuzz_f, 0, -1, 0, N_("[-c] [-d] field fuzzcmd..."),
	  N_("fuzz values on disk"), fuzz_help };

void
fuzz_init(void)
{
	if (!expert_mode)
		return;

	add_command(&fuzz_cmd);
	srand48(clock());
}

static void
fuzz_help(void)
{
	dbprintf(_(
"\n"
" The 'fuzz' command fuzzes fields in any on-disk data structure.  For\n"
" block fuzzing, see the 'blocktrash' or 'write' commands."
"\n"
" Examples:\n"
"  Struct mode: 'fuzz core.uid zeroes'    - set an inode uid field to 0.\n"
"               'fuzz crc ones'           - set a crc filed to all ones.\n"
"               'fuzz bno[11] firstbit'   - set the high bit of a block array.\n"
"               'fuzz keys[5].startblock add'    - increase a btree key value.\n"
"               'fuzz uuid random'        - randomize the superblock uuid.\n"
"\n"
" Type 'fuzz' by itself for a list of specific commands.\n\n"
" Specifying the -c option will allow writes of invalid (corrupt) data with\n"
" an invalid CRC. Specifying the -d option will allow writes of invalid data,\n"
" but still recalculate the CRC so we are forced to check and detect the\n"
" invalid data appropriately.\n\n"
));

}

static int
fuzz_f(
	int		argc,
	char		**argv)
{
	pfunc_t	pf;
	extern char *progname;
	int c;
	bool corrupt = false;	/* Allow write of bad data w/ invalid CRC */
	bool invalid_data = false; /* Allow write of bad data w/ valid CRC */
	struct xfs_buf_ops local_ops;
	const struct xfs_buf_ops *stashed_ops = NULL;

	if (x.isreadonly & LIBXFS_ISREADONLY) {
		dbprintf(_("%s started in read only mode, fuzzing disabled\n"),
			progname);
		return 0;
	}

	if (cur_typ == NULL) {
		dbprintf(_("no current type\n"));
		return 0;
	}

	pf = cur_typ->pfunc;
	if (pf == NULL) {
		dbprintf(_("no handler function for type %s, fuzz unsupported.\n"),
			 cur_typ->name);
		return 0;
	}

	while ((c = getopt(argc, argv, "cd")) != EOF) {
		switch (c) {
		case 'c':
			corrupt = true;
			break;
		case 'd':
			invalid_data = true;
			break;
		default:
			dbprintf(_("bad option for fuzz command\n"));
			return 0;
		}
	}

	if (corrupt && invalid_data) {
		dbprintf(_("Cannot specify both -c and -d options\n"));
		return 0;
	}

	if (invalid_data &&
	    iocur_top->typ->crc_off == TYP_F_NO_CRC_OFF &&
	    xfs_sb_version_hascrc(&mp->m_sb)) {
		dbprintf(_("Cannot recalculate CRCs on this type of object\n"));
		return 0;
	}

	argc -= optind;
	argv += optind;

	/*
	 * If the buffer has no verifier or we are using standard verifier
	 * paths, then just fuzz it and return
	 */
	if (!iocur_top->bp->b_ops ||
	    !(corrupt || invalid_data)) {
		(*pf)(DB_FUZZ, cur_typ->fields, argc, argv);
		return 0;
	}


	/* Temporarily remove write verifier to write bad data */
	stashed_ops = iocur_top->bp->b_ops;
	local_ops.verify_read = stashed_ops->verify_read;
	iocur_top->bp->b_ops = &local_ops;

	if (!xfs_sb_version_hascrc(&mp->m_sb)) {
		local_ops.verify_write = xfs_dummy_verify;
	} else if (corrupt) {
		local_ops.verify_write = xfs_dummy_verify;
		dbprintf(_("Allowing fuzz of corrupted data and bad CRC\n"));
	} else if (iocur_top->typ->crc_off == TYP_F_CRC_FUNC) {
		local_ops.verify_write = iocur_top->typ->set_crc;
		dbprintf(_("Allowing fuzz of corrupted data with good CRC\n"));
	} else { /* invalid data */
		local_ops.verify_write = xfs_verify_recalc_crc;
		dbprintf(_("Allowing fuzz of corrupted data with good CRC\n"));
	}

	(*pf)(DB_FUZZ, cur_typ->fields, argc, argv);

	iocur_top->bp->b_ops = stashed_ops;

	return 0;
}

/* Write zeroes to the field */
static bool
fuzz_zeroes(
	void		*buf,
	int		bitoff,
	int		nbits)
{
	char		*out = buf;
	int		bit;

	if (bitoff % NBBY || nbits % NBBY) {
		for (bit = 0; bit < nbits; bit++)
			setbit_l(out, bit + bitoff, 0);
	} else
		memset(out + byteize(bitoff), 0, byteize(nbits));
	return true;
}

/* Write ones to the field */
static bool
fuzz_ones(
	void		*buf,
	int		bitoff,
	int		nbits)
{
	char		*out = buf;
	int		bit;

	if (bitoff % NBBY || nbits % NBBY) {
		for (bit = 0; bit < nbits; bit++)
			setbit_l(out, bit + bitoff, 1);
	} else
		memset(out + byteize(bitoff), 0xFF, byteize(nbits));
	return true;
}

/* Flip the high bit in the (presumably big-endian) field */
static bool
fuzz_firstbit(
	void		*buf,
	int		bitoff,
	int		nbits)
{
	setbit_l((char *)buf, bitoff, !getbit_l((char *)buf, bitoff));
	return true;
}

/* Flip the low bit in the (presumably big-endian) field */
static bool
fuzz_lastbit(
	void		*buf,
	int		bitoff,
	int		nbits)
{
	setbit_l((char *)buf, bitoff + nbits - 1,
			!getbit_l((char *)buf, bitoff + nbits - 1));
	return true;
}

/* Flip the middle bit in the (presumably big-endian) field */
static bool
fuzz_middlebit(
	void		*buf,
	int		bitoff,
	int		nbits)
{
	setbit_l((char *)buf, bitoff + nbits / 2,
			!getbit_l((char *)buf, bitoff + nbits / 2));
	return true;
}

/* Format and shift a number into a buffer for setbitval. */
static char *
format_number(
	uint64_t	val,
	__be64		*out,
	int		bit_length)
{
	int		offset;
	char		*rbuf = (char *)out;

	/*
	 * If the length of the field is not a multiple of a byte, push
	 * the bits up in the field, so the most signicant field bit is
	 * the most significant bit in the byte:
	 *
	 * before:
	 * val  |----|----|----|----|----|--MM|mmmm|llll|
	 * after
	 * val  |----|----|----|----|----|MMmm|mmll|ll00|
	 */
	offset = bit_length % NBBY;
	if (offset)
		val <<= (NBBY - offset);

	/*
	 * convert to big endian and copy into the array
	 * rbuf |----|----|----|----|----|MMmm|mmll|ll00|
	 */
	*out = cpu_to_be64(val);

	/*
	 * Align the array to point to the field in the array.
	 *  rbuf  = |MMmm|mmll|ll00|
	 */
	offset = sizeof(__be64) - 1 - ((bit_length - 1) / sizeof(__be64));
	return rbuf + offset;
}

/* Increase the value by some small prime number. */
static bool
fuzz_add(
	void		*buf,
	int		bitoff,
	int		nbits)
{
	uint64_t	val;
	__be64		out;
	char		*b;

	if (nbits > 64)
		return false;

	val = getbitval(buf, bitoff, nbits, BVUNSIGNED);
	val += (nbits > 8 ? 2017 : 137);
	b = format_number(val, &out, nbits);
	setbitval(buf, bitoff, nbits, b);

	return true;
}

/* Decrease the value by some small prime number. */
static bool
fuzz_sub(
	void		*buf,
	int		bitoff,
	int		nbits)
{
	uint64_t	val;
	__be64		out;
	char		*b;

	if (nbits > 64)
		return false;

	val = getbitval(buf, bitoff, nbits, BVUNSIGNED);
	val -= (nbits > 8 ? 2017 : 137);
	b = format_number(val, &out, nbits);
	setbitval(buf, bitoff, nbits, b);

	return true;
}

/* Randomize the field. */
static bool
fuzz_random(
	void		*buf,
	int		bitoff,
	int		nbits)
{
	int		i, bytes;
	char		*b, *rbuf;

	bytes = byteize_up(nbits);
	rbuf = b = malloc(bytes);
	if (!b) {
		perror("fuzz_random");
		return false;
	}

	for (i = 0; i < bytes; i++)
		*b++ = (char)lrand48();

	setbitval(buf, bitoff, nbits, rbuf);
	free(rbuf);

	return true;
}

struct fuzzcmd {
	const char	*verb;
	bool		(*fn)(void *buf, int bitoff, int nbits);
};

/* Keep these verbs in sync with enum fuzzcmds. */
static struct fuzzcmd fuzzverbs[] = {
	{"zeroes",		fuzz_zeroes},
	{"ones",		fuzz_ones},
	{"firstbit",		fuzz_firstbit},
	{"middlebit",		fuzz_middlebit},
	{"lastbit",		fuzz_lastbit},
	{"add",			fuzz_add},
	{"sub",			fuzz_sub},
	{"random",		fuzz_random},
	{NULL,			NULL},
};

/* ARGSUSED */
void
fuzz_struct(
	const field_t	*fields,
	int		argc,
	char		**argv)
{
	const ftattr_t	*fa;
	flist_t		*fl;
	flist_t		*sfl;
	int		bit_length;
	struct fuzzcmd	*fc;
	bool		success;
	int		parentoffset;

	if (argc != 2) {
		dbprintf(_("Usage: fuzz fieldname fuzzcmd\n"));
		dbprintf("Fuzz commands: %s", fuzzverbs->verb);
		for (fc = fuzzverbs + 1; fc->verb != NULL; fc++)
			dbprintf(", %s", fc->verb);
		dbprintf(".\n");
		return;
	}

	fl = flist_scan(argv[0]);
	if (!fl) {
		dbprintf(_("unable to parse '%s'.\n"), argv[0]);
		return;
	}

	/* Find our fuzz verb */
	for (fc = fuzzverbs; fc->verb != NULL; fc++)
		if (!strcmp(fc->verb, argv[1]))
			break;
	if (fc->fn == NULL) {
		dbprintf(_("Unknown fuzz command '%s'.\n"), argv[1]);
		goto out_free;
	}

	/* if we're a root field type, go down 1 layer to get field list */
	if (fields->name[0] == '\0') {
		fa = &ftattrtab[fields->ftyp];
		ASSERT(fa->ftyp == fields->ftyp);
		fields = fa->subfld;
	}

	/* run down the field list and set offsets into the data */
	if (!flist_parse(fields, fl, iocur_top->data, 0)) {
		dbprintf(_("parsing error\n"));
		goto out_free;
	}

	sfl = fl;
	parentoffset = 0;
	while (sfl->child) {
		parentoffset = sfl->offset;
		sfl = sfl->child;
	}

	/*
	 * For structures, fsize * fcount tells us the size of the region we are
	 * modifying, which is usually a single structure member and is pointed
	 * to by the last child in the list.
	 *
	 * However, if the base structure is an array and we have a direct index
	 * into the array (e.g. write bno[5]) then we are returned a single
	 * flist object with the offset pointing directly at the location we
	 * need to modify. The length of the object we are modifying is then
	 * determined by the size of the individual array entry (fsize) and the
	 * indexes defined in the object, not the overall size of the array
	 * (which is what fcount returns).
	 */
	bit_length = fsize(sfl->fld, iocur_top->data, parentoffset, 0);
	if (sfl->fld->flags & FLD_ARRAY)
		bit_length *= sfl->high - sfl->low + 1;
	else
		bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset);

	/* Fuzz the value */
	success = fc->fn(iocur_top->data, sfl->offset, bit_length);
	if (!success) {
		dbprintf(_("unable to fuzz field '%s'\n"), argv[0]);
		goto out_free;
	}

	/* Write the fuzzed value back */
	write_cur();

	flist_print(fl);
	print_flist(fl);
out_free:
	flist_free(fl);
}
