// 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.flags & 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_has_crc(mp)) {
		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_has_crc(mp)) {
		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);
}
