// SPDX-License-Identifier: GPL-2.0
/*
 * This is for all the tests related to logic bugs (e.g. bad dereferences,
 * bad alignment, bad loops, bad locking, bad scheduling, deep stacks, and
 * lockups) along with other things that don't fit well into existing LKDTM
 * test source files.
 */
#include "lkdtm.h"
#include <linux/cpu.h>
#include <linux/list.h>
#include <linux/hrtimer.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/sched/task_stack.h>
#include <linux/slab.h>
#include <linux/stop_machine.h>
#include <linux/uaccess.h>

#if IS_ENABLED(CONFIG_X86_32) && !IS_ENABLED(CONFIG_UML)
#include <asm/desc.h>
#endif

struct lkdtm_list {
	struct list_head node;
};

/*
 * Make sure our attempts to over run the kernel stack doesn't trigger
 * a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we
 * recurse past the end of THREAD_SIZE by default.
 */
#if defined(CONFIG_FRAME_WARN) && (CONFIG_FRAME_WARN > 0)
#define REC_STACK_SIZE (_AC(CONFIG_FRAME_WARN, UL) / 2)
#else
#define REC_STACK_SIZE (THREAD_SIZE / 8UL)
#endif
#define REC_NUM_DEFAULT ((THREAD_SIZE / REC_STACK_SIZE) * 2)

static int recur_count = REC_NUM_DEFAULT;

static DEFINE_SPINLOCK(lock_me_up);

/*
 * Make sure compiler does not optimize this function or stack frame away:
 * - function marked noinline
 * - stack variables are marked volatile
 * - stack variables are written (memset()) and read (buf[..] passed as arg)
 * - function may have external effects (memzero_explicit())
 * - no tail recursion possible
 */
static int noinline recursive_loop(int remaining)
{
	volatile char buf[REC_STACK_SIZE];
	volatile int ret;

	memset((void *)buf, remaining & 0xFF, sizeof(buf));
	if (!remaining)
		ret = 0;
	else
		ret = recursive_loop((int)buf[remaining % sizeof(buf)] - 1);
	memzero_explicit((void *)buf, sizeof(buf));
	return ret;
}

/* If the depth is negative, use the default, otherwise keep parameter. */
void __init lkdtm_bugs_init(int *recur_param)
{
	if (*recur_param < 0)
		*recur_param = recur_count;
	else
		recur_count = *recur_param;
}

static void lkdtm_PANIC(void)
{
	panic("dumptest");
}

static int panic_stop_irqoff_fn(void *arg)
{
	atomic_t *v = arg;

	/*
	 * As stop_machine() disables interrupts, all CPUs within this function
	 * have interrupts disabled and cannot take a regular IPI.
	 *
	 * The last CPU which enters here will trigger a panic, and as all CPUs
	 * cannot take a regular IPI, we'll only be able to stop secondaries if
	 * smp_send_stop() or crash_smp_send_stop() uses an NMI.
	 */
	if (atomic_inc_return(v) == num_online_cpus())
		panic("panic stop irqoff test");

	for (;;)
		cpu_relax();
}

static void lkdtm_PANIC_STOP_IRQOFF(void)
{
	atomic_t v = ATOMIC_INIT(0);
	stop_machine(panic_stop_irqoff_fn, &v, cpu_online_mask);
}

static bool wait_for_panic;

static enum hrtimer_restart panic_in_hardirq(struct hrtimer *timer)
{
	panic("from hard IRQ context");

	wait_for_panic = false;
	return HRTIMER_NORESTART;
}

static void lkdtm_PANIC_IN_HARDIRQ(void)
{
	struct hrtimer timer;

	wait_for_panic = true;
	hrtimer_setup_on_stack(&timer, panic_in_hardirq,
			       CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
	hrtimer_start(&timer, us_to_ktime(100), HRTIMER_MODE_REL_HARD);

	while (READ_ONCE(wait_for_panic))
		cpu_relax();

	hrtimer_cancel(&timer);
}

static void lkdtm_BUG(void)
{
	BUG();
}

static bool wait_for_bug;

static enum hrtimer_restart bug_in_hardirq(struct hrtimer *timer)
{
	BUG();

	wait_for_bug = false;
	return HRTIMER_NORESTART;
}

static void lkdtm_BUG_IN_HARDIRQ(void)
{
	struct hrtimer timer;

	wait_for_bug = true;
	hrtimer_setup_on_stack(&timer, bug_in_hardirq,
			       CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
	hrtimer_start(&timer, us_to_ktime(100), HRTIMER_MODE_REL_HARD);

	while (READ_ONCE(wait_for_bug))
		cpu_relax();

	hrtimer_cancel(&timer);
}

static int warn_counter;

static void lkdtm_WARNING(void)
{
	WARN_ON(++warn_counter);
}

static void lkdtm_WARNING_MESSAGE(void)
{
	WARN(1, "Warning message trigger count: %d\n", ++warn_counter);
}

static void lkdtm_EXCEPTION(void)
{
	*((volatile int *) 0) = 0;
}

static void lkdtm_LOOP(void)
{
	for (;;)
		;
}

static void lkdtm_EXHAUST_STACK(void)
{
	pr_info("Calling function with %lu frame size to depth %d ...\n",
		REC_STACK_SIZE, recur_count);
	recursive_loop(recur_count);
	pr_info("FAIL: survived without exhausting stack?!\n");
}

static noinline void __lkdtm_CORRUPT_STACK(void *stack)
{
	memset(stack, '\xff', 64);
}

/* This should trip the stack canary, not corrupt the return address. */
static noinline void lkdtm_CORRUPT_STACK(void)
{
	/* Use default char array length that triggers stack protection. */
	char data[8] __aligned(sizeof(void *));

	pr_info("Corrupting stack containing char array ...\n");
	__lkdtm_CORRUPT_STACK((void *)&data);
}

/* Same as above but will only get a canary with -fstack-protector-strong */
static noinline void lkdtm_CORRUPT_STACK_STRONG(void)
{
	union {
		unsigned short shorts[4];
		unsigned long *ptr;
	} data __aligned(sizeof(void *));

	pr_info("Corrupting stack containing union ...\n");
	__lkdtm_CORRUPT_STACK((void *)&data);
}

static pid_t stack_pid;
static unsigned long stack_addr;

static void lkdtm_REPORT_STACK(void)
{
	volatile uintptr_t magic;
	pid_t pid = task_pid_nr(current);

	if (pid != stack_pid) {
		pr_info("Starting stack offset tracking for pid %d\n", pid);
		stack_pid = pid;
		stack_addr = (uintptr_t)&magic;
	}

	pr_info("Stack offset: %d\n", (int)(stack_addr - (uintptr_t)&magic));
}

static pid_t stack_canary_pid;
static unsigned long stack_canary;
static unsigned long stack_canary_offset;

static noinline void __lkdtm_REPORT_STACK_CANARY(void *stack)
{
	int i = 0;
	pid_t pid = task_pid_nr(current);
	unsigned long *canary = (unsigned long *)stack;
	unsigned long current_offset = 0, init_offset = 0;

	/* Do our best to find the canary in a 16 word window ... */
	for (i = 1; i < 16; i++) {
		canary = (unsigned long *)stack + i;
#ifdef CONFIG_STACKPROTECTOR
		if (*canary == current->stack_canary)
			current_offset = i;
		if (*canary == init_task.stack_canary)
			init_offset = i;
#endif
	}

	if (current_offset == 0) {
		/*
		 * If the canary doesn't match what's in the task_struct,
		 * we're either using a global canary or the stack frame
		 * layout changed.
		 */
		if (init_offset != 0) {
			pr_err("FAIL: global stack canary found at offset %ld (canary for pid %d matches init_task's)!\n",
			       init_offset, pid);
		} else {
			pr_warn("FAIL: did not correctly locate stack canary :(\n");
			pr_expected_config(CONFIG_STACKPROTECTOR);
		}

		return;
	} else if (init_offset != 0) {
		pr_warn("WARNING: found both current and init_task canaries nearby?!\n");
	}

	canary = (unsigned long *)stack + current_offset;
	if (stack_canary_pid == 0) {
		stack_canary = *canary;
		stack_canary_pid = pid;
		stack_canary_offset = current_offset;
		pr_info("Recorded stack canary for pid %d at offset %ld\n",
			stack_canary_pid, stack_canary_offset);
	} else if (pid == stack_canary_pid) {
		pr_warn("ERROR: saw pid %d again -- please use a new pid\n", pid);
	} else {
		if (current_offset != stack_canary_offset) {
			pr_warn("ERROR: canary offset changed from %ld to %ld!?\n",
				stack_canary_offset, current_offset);
			return;
		}

		if (*canary == stack_canary) {
			pr_warn("FAIL: canary identical for pid %d and pid %d at offset %ld!\n",
				stack_canary_pid, pid, current_offset);
		} else {
			pr_info("ok: stack canaries differ between pid %d and pid %d at offset %ld.\n",
				stack_canary_pid, pid, current_offset);
			/* Reset the test. */
			stack_canary_pid = 0;
		}
	}
}

static void lkdtm_REPORT_STACK_CANARY(void)
{
	/* Use default char array length that triggers stack protection. */
	char data[8] __aligned(sizeof(void *)) = { };

	__lkdtm_REPORT_STACK_CANARY((void *)&data);
}

static void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void)
{
	static u8 data[5] __attribute__((aligned(4))) = {1, 2, 3, 4, 5};
	u32 *p;
	u32 val = 0x12345678;

	p = (u32 *)(data + 1);
	if (*p == 0)
		val = 0x87654321;
	*p = val;

	if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
		pr_err("XFAIL: arch has CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS\n");
}

static void lkdtm_SOFTLOCKUP(void)
{
	preempt_disable();
	for (;;)
		cpu_relax();
}

static void lkdtm_HARDLOCKUP(void)
{
	local_irq_disable();
	for (;;)
		cpu_relax();
}

static void __lkdtm_SMP_CALL_LOCKUP(void *unused)
{
	for (;;)
		cpu_relax();
}

static void lkdtm_SMP_CALL_LOCKUP(void)
{
	unsigned int cpu, target;

	cpus_read_lock();

	cpu = get_cpu();
	target = cpumask_any_but(cpu_online_mask, cpu);

	if (target >= nr_cpu_ids) {
		pr_err("FAIL: no other online CPUs\n");
		goto out_put_cpus;
	}

	smp_call_function_single(target, __lkdtm_SMP_CALL_LOCKUP, NULL, 1);

	pr_err("FAIL: did not hang\n");

out_put_cpus:
	put_cpu();
	cpus_read_unlock();
}

static void lkdtm_SPINLOCKUP(void)
{
	/* Must be called twice to trigger. */
	spin_lock(&lock_me_up);
	/* Let sparse know we intended to exit holding the lock. */
	__release(&lock_me_up);
}

static void __noreturn lkdtm_HUNG_TASK(void)
{
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule();
	BUG();
}

static volatile unsigned int huge = INT_MAX - 2;
static volatile unsigned int ignored;

static void lkdtm_OVERFLOW_SIGNED(void)
{
	int value;

	value = huge;
	pr_info("Normal signed addition ...\n");
	value += 1;
	ignored = value;

	pr_info("Overflowing signed addition ...\n");
	value += 4;
	ignored = value;
}


static void lkdtm_OVERFLOW_UNSIGNED(void)
{
	unsigned int value;

	value = huge;
	pr_info("Normal unsigned addition ...\n");
	value += 1;
	ignored = value;

	pr_info("Overflowing unsigned addition ...\n");
	value += 4;
	ignored = value;
}

/* Intentionally using unannotated flex array definition. */
struct array_bounds_flex_array {
	int one;
	int two;
	char data[];
};

struct array_bounds {
	int one;
	int two;
	char data[8];
	int three;
};

static void lkdtm_ARRAY_BOUNDS(void)
{
	struct array_bounds_flex_array *not_checked;
	struct array_bounds *checked;
	volatile int i;

	not_checked = kmalloc(sizeof(*not_checked) * 2, GFP_KERNEL);
	checked = kmalloc(sizeof(*checked) * 2, GFP_KERNEL);
	if (!not_checked || !checked) {
		kfree(not_checked);
		kfree(checked);
		return;
	}

	pr_info("Array access within bounds ...\n");
	/* For both, touch all bytes in the actual member size. */
	for (i = 0; i < sizeof(checked->data); i++)
		checked->data[i] = 'A';
	/*
	 * For the uninstrumented flex array member, also touch 1 byte
	 * beyond to verify it is correctly uninstrumented.
	 */
	for (i = 0; i < 2; i++)
		not_checked->data[i] = 'A';

	pr_info("Array access beyond bounds ...\n");
	for (i = 0; i < sizeof(checked->data) + 1; i++)
		checked->data[i] = 'B';

	kfree(not_checked);
	kfree(checked);
	pr_err("FAIL: survived array bounds overflow!\n");
	if (IS_ENABLED(CONFIG_UBSAN_BOUNDS))
		pr_expected_config(CONFIG_UBSAN_TRAP);
	else
		pr_expected_config(CONFIG_UBSAN_BOUNDS);
}

struct lkdtm_cb_fam {
	unsigned long flags;
	int count;
	int array[] __counted_by(count);
};

static volatile int element_count = 4;

static void lkdtm_FAM_BOUNDS(void)
{
	struct lkdtm_cb_fam *inst;

	inst = kzalloc_flex(*inst, array, element_count + 1);
	if (!inst) {
		pr_err("FAIL: could not allocate test struct!\n");
		return;
	}

	inst->count = element_count;
	pr_info("Array access within bounds ...\n");
	inst->array[1] = element_count;
	ignored = inst->array[1];

	pr_info("Array access beyond bounds ...\n");
	inst->array[element_count] = element_count;
	ignored = inst->array[element_count];

	kfree(inst);

	pr_err("FAIL: survived access of invalid flexible array member index!\n");

	if (!IS_ENABLED(CONFIG_CC_HAS_COUNTED_BY))
		pr_warn("This is expected since this %s was built with a compiler that does not support __counted_by\n",
			lkdtm_kernel_info);
	else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS))
		pr_expected_config(CONFIG_UBSAN_TRAP);
	else
		pr_expected_config(CONFIG_UBSAN_BOUNDS);
}

struct lkdtm_extra {
	short a, b;
	u16 sixteen;
	u32 bigger;
	u64 biggest;
};

struct lkdtm_cb_ptr {
	int a, b, c;
	int nr_extra;
	char *buf __counted_by_ptr(len);
	size_t len;
	struct lkdtm_extra *extra __counted_by_ptr(nr_extra);
};

static noinline void check_ptr_len(struct lkdtm_cb_ptr *p, size_t len)
{
	if (__member_size(p->buf) != len)
		pr_err("FAIL: could not determine size of inst->buf: %zu\n",
			__member_size(p->buf));
	else
		pr_info("good: inst->buf length is %zu\n", len);
}

static void lkdtm_PTR_BOUNDS(void)
{
	struct lkdtm_cb_ptr *inst;

	inst = kzalloc_obj(*inst);
	if (!inst) {
		pr_err("FAIL: could not allocate struct lkdtm_cb_ptr!\n");
		return;
	}

	inst->buf = kzalloc(element_count, GFP_KERNEL);
	if (!inst->buf) {
		pr_err("FAIL: could not allocate inst->buf!\n");
		return;
	}
	inst->len = element_count;

	/* Double element_count */
	inst->extra = kzalloc_objs(*inst->extra, element_count * 2);
	inst->nr_extra = element_count * 2;

	pr_info("Pointer access within bounds ...\n");
	check_ptr_len(inst, 4);
	/* All 4 bytes */
	inst->buf[0] = 'A';
	inst->buf[1] = 'B';
	inst->buf[2] = 'C';
	inst->buf[3] = 'D';
	/* Halfway into the array */
	inst->extra[element_count].biggest = 0x1000;

	pr_info("Pointer access beyond bounds ...\n");
	ignored = inst->extra[inst->nr_extra].b;

	kfree(inst->extra);
	kfree(inst->buf);
	kfree(inst);

	pr_err("FAIL: survived access of invalid pointer member offset!\n");

	if (!IS_ENABLED(CONFIG_CC_HAS_COUNTED_BY_PTR))
		pr_warn("This is expected since this %s was built with a compiler that does not support __counted_by_ptr\n",
			lkdtm_kernel_info);
	else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS))
		pr_expected_config(CONFIG_UBSAN_TRAP);
	else
		pr_expected_config(CONFIG_UBSAN_BOUNDS);
}

static void lkdtm_CORRUPT_LIST_ADD(void)
{
	/*
	 * Initially, an empty list via LIST_HEAD:
	 *	test_head.next = &test_head
	 *	test_head.prev = &test_head
	 */
	LIST_HEAD(test_head);
	struct lkdtm_list good, bad;
	void *target[2] = { };
	void *redirection = &target;

	pr_info("attempting good list addition\n");

	/*
	 * Adding to the list performs these actions:
	 *	test_head.next->prev = &good.node
	 *	good.node.next = test_head.next
	 *	good.node.prev = test_head
	 *	test_head.next = good.node
	 */
	list_add(&good.node, &test_head);

	pr_info("attempting corrupted list addition\n");
	/*
	 * In simulating this "write what where" primitive, the "what" is
	 * the address of &bad.node, and the "where" is the address held
	 * by "redirection".
	 */
	test_head.next = redirection;
	list_add(&bad.node, &test_head);

	if (target[0] == NULL && target[1] == NULL)
		pr_err("Overwrite did not happen, but no BUG?!\n");
	else {
		pr_err("list_add() corruption not detected!\n");
		pr_expected_config(CONFIG_LIST_HARDENED);
	}
}

static void lkdtm_CORRUPT_LIST_DEL(void)
{
	LIST_HEAD(test_head);
	struct lkdtm_list item;
	void *target[2] = { };
	void *redirection = &target;

	list_add(&item.node, &test_head);

	pr_info("attempting good list removal\n");
	list_del(&item.node);

	pr_info("attempting corrupted list removal\n");
	list_add(&item.node, &test_head);

	/* As with the list_add() test above, this corrupts "next". */
	item.node.next = redirection;
	list_del(&item.node);

	if (target[0] == NULL && target[1] == NULL)
		pr_err("Overwrite did not happen, but no BUG?!\n");
	else {
		pr_err("list_del() corruption not detected!\n");
		pr_expected_config(CONFIG_LIST_HARDENED);
	}
}

/* Test that VMAP_STACK is actually allocating with a leading guard page */
static void lkdtm_STACK_GUARD_PAGE_LEADING(void)
{
	const unsigned char *stack = task_stack_page(current);
	const unsigned char *ptr = stack - 1;
	volatile unsigned char byte;

	pr_info("attempting bad read from page below current stack\n");

	byte = *ptr;

	pr_err("FAIL: accessed page before stack! (byte: %x)\n", byte);
}

/* Test that VMAP_STACK is actually allocating with a trailing guard page */
static void lkdtm_STACK_GUARD_PAGE_TRAILING(void)
{
	const unsigned char *stack = task_stack_page(current);
	const unsigned char *ptr = stack + THREAD_SIZE;
	volatile unsigned char byte;

	pr_info("attempting bad read from page above current stack\n");

	byte = *ptr;

	pr_err("FAIL: accessed page after stack! (byte: %x)\n", byte);
}

static void lkdtm_UNSET_SMEP(void)
{
#if IS_ENABLED(CONFIG_X86_64) && !IS_ENABLED(CONFIG_UML)
#define MOV_CR4_DEPTH	64
	void (*direct_write_cr4)(unsigned long val);
	unsigned char *insn;
	unsigned long cr4;
	int i;

	cr4 = native_read_cr4();

	if ((cr4 & X86_CR4_SMEP) != X86_CR4_SMEP) {
		pr_err("FAIL: SMEP not in use\n");
		return;
	}
	cr4 &= ~(X86_CR4_SMEP);

	pr_info("trying to clear SMEP normally\n");
	native_write_cr4(cr4);
	if (cr4 == native_read_cr4()) {
		pr_err("FAIL: pinning SMEP failed!\n");
		cr4 |= X86_CR4_SMEP;
		pr_info("restoring SMEP\n");
		native_write_cr4(cr4);
		return;
	}
	pr_info("ok: SMEP did not get cleared\n");

	/*
	 * To test the post-write pinning verification we need to call
	 * directly into the middle of native_write_cr4() where the
	 * cr4 write happens, skipping any pinning. This searches for
	 * the cr4 writing instruction.
	 */
	insn = (unsigned char *)native_write_cr4;
	OPTIMIZER_HIDE_VAR(insn);
	for (i = 0; i < MOV_CR4_DEPTH; i++) {
		/* mov %rdi, %cr4 */
		if (insn[i] == 0x0f && insn[i+1] == 0x22 && insn[i+2] == 0xe7)
			break;
		/* mov %rdi,%rax; mov %rax, %cr4 */
		if (insn[i]   == 0x48 && insn[i+1] == 0x89 &&
		    insn[i+2] == 0xf8 && insn[i+3] == 0x0f &&
		    insn[i+4] == 0x22 && insn[i+5] == 0xe0)
			break;
	}
	if (i >= MOV_CR4_DEPTH) {
		pr_info("ok: cannot locate cr4 writing call gadget\n");
		return;
	}
	direct_write_cr4 = (void *)(insn + i);

	pr_info("trying to clear SMEP with call gadget\n");
	direct_write_cr4(cr4);
	if (native_read_cr4() & X86_CR4_SMEP) {
		pr_info("ok: SMEP removal was reverted\n");
	} else {
		pr_err("FAIL: cleared SMEP not detected!\n");
		cr4 |= X86_CR4_SMEP;
		pr_info("restoring SMEP\n");
		native_write_cr4(cr4);
	}
#else
	pr_err("XFAIL: this test is x86_64-only\n");
#endif
}

static void lkdtm_DOUBLE_FAULT(void)
{
#if IS_ENABLED(CONFIG_X86_32) && !IS_ENABLED(CONFIG_UML)
	/*
	 * Trigger #DF by setting the stack limit to zero.  This clobbers
	 * a GDT TLS slot, which is okay because the current task will die
	 * anyway due to the double fault.
	 */
	struct desc_struct d = {
		.type = 3,	/* expand-up, writable, accessed data */
		.p = 1,		/* present */
		.d = 1,		/* 32-bit */
		.g = 0,		/* limit in bytes */
		.s = 1,		/* not system */
	};

	local_irq_disable();
	write_gdt_entry(get_cpu_gdt_rw(smp_processor_id()),
			GDT_ENTRY_TLS_MIN, &d, DESCTYPE_S);

	/*
	 * Put our zero-limit segment in SS and then trigger a fault.  The
	 * 4-byte access to (%esp) will fault with #SS, and the attempt to
	 * deliver the fault will recursively cause #SS and result in #DF.
	 * This whole process happens while NMIs and MCEs are blocked by the
	 * MOV SS window.  This is nice because an NMI with an invalid SS
	 * would also double-fault, resulting in the NMI or MCE being lost.
	 */
	asm volatile ("movw %0, %%ss; addl $0, (%%esp)" ::
		      "r" ((unsigned short)(GDT_ENTRY_TLS_MIN << 3)));

	pr_err("FAIL: tried to double fault but didn't die\n");
#else
	pr_err("XFAIL: this test is ia32-only\n");
#endif
}

#ifdef CONFIG_ARM64
static noinline void change_pac_parameters(void)
{
	if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL)) {
		/* Reset the keys of current task */
		ptrauth_thread_init_kernel(current);
		ptrauth_thread_switch_kernel(current);
	}
}
#endif

static noinline void lkdtm_CORRUPT_PAC(void)
{
#ifdef CONFIG_ARM64
#define CORRUPT_PAC_ITERATE	10
	int i;

	if (!IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL))
		pr_err("FAIL: kernel not built with CONFIG_ARM64_PTR_AUTH_KERNEL\n");

	if (!system_supports_address_auth()) {
		pr_err("FAIL: CPU lacks pointer authentication feature\n");
		return;
	}

	pr_info("changing PAC parameters to force function return failure...\n");
	/*
	 * PAC is a hash value computed from input keys, return address and
	 * stack pointer. As pac has fewer bits so there is a chance of
	 * collision, so iterate few times to reduce the collision probability.
	 */
	for (i = 0; i < CORRUPT_PAC_ITERATE; i++)
		change_pac_parameters();

	pr_err("FAIL: survived PAC changes! Kernel may be unstable from here\n");
#else
	pr_err("XFAIL: this test is arm64-only\n");
#endif
}

static struct crashtype crashtypes[] = {
	CRASHTYPE(PANIC),
	CRASHTYPE(PANIC_STOP_IRQOFF),
	CRASHTYPE(PANIC_IN_HARDIRQ),
	CRASHTYPE(BUG),
	CRASHTYPE(BUG_IN_HARDIRQ),
	CRASHTYPE(WARNING),
	CRASHTYPE(WARNING_MESSAGE),
	CRASHTYPE(EXCEPTION),
	CRASHTYPE(LOOP),
	CRASHTYPE(EXHAUST_STACK),
	CRASHTYPE(CORRUPT_STACK),
	CRASHTYPE(CORRUPT_STACK_STRONG),
	CRASHTYPE(REPORT_STACK),
	CRASHTYPE(REPORT_STACK_CANARY),
	CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
	CRASHTYPE(SOFTLOCKUP),
	CRASHTYPE(HARDLOCKUP),
	CRASHTYPE(SMP_CALL_LOCKUP),
	CRASHTYPE(SPINLOCKUP),
	CRASHTYPE(HUNG_TASK),
	CRASHTYPE(OVERFLOW_SIGNED),
	CRASHTYPE(OVERFLOW_UNSIGNED),
	CRASHTYPE(ARRAY_BOUNDS),
	CRASHTYPE(FAM_BOUNDS),
	CRASHTYPE(PTR_BOUNDS),
	CRASHTYPE(CORRUPT_LIST_ADD),
	CRASHTYPE(CORRUPT_LIST_DEL),
	CRASHTYPE(STACK_GUARD_PAGE_LEADING),
	CRASHTYPE(STACK_GUARD_PAGE_TRAILING),
	CRASHTYPE(UNSET_SMEP),
	CRASHTYPE(DOUBLE_FAULT),
	CRASHTYPE(CORRUPT_PAC),
};

struct crashtype_category bugs_crashtypes = {
	.crashtypes = crashtypes,
	.len	    = ARRAY_SIZE(crashtypes),
};
