// SPDX-License-Identifier: GPL-2.0
/*
 * This code fills the used part of the kernel stack with a poison value
 * before returning to userspace. It's part of the STACKLEAK feature
 * ported from grsecurity/PaX.
 *
 * Author: Alexander Popov <alex.popov@linux.com>
 *
 * KSTACK_ERASE reduces the information which kernel stack leak bugs can
 * reveal and blocks some uninitialized stack variable attacks.
 */

#include <linux/kstack_erase.h>
#include <linux/kprobes.h>

#ifdef CONFIG_KSTACK_ERASE_RUNTIME_DISABLE
#include <linux/jump_label.h>
#include <linux/string_choices.h>
#include <linux/sysctl.h>
#include <linux/init.h>

static DEFINE_STATIC_KEY_FALSE(stack_erasing_bypass);

#ifdef CONFIG_SYSCTL
static int stack_erasing_sysctl(const struct ctl_table *table, int write,
			void __user *buffer, size_t *lenp, loff_t *ppos)
{
	int ret = 0;
	int state = !static_branch_unlikely(&stack_erasing_bypass);
	int prev_state = state;
	struct ctl_table table_copy = *table;

	table_copy.data = &state;
	ret = proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos);
	state = !!state;
	if (ret || !write || state == prev_state)
		return ret;

	if (state)
		static_branch_disable(&stack_erasing_bypass);
	else
		static_branch_enable(&stack_erasing_bypass);

	pr_warn("stackleak: kernel stack erasing is %s\n",
					str_enabled_disabled(state));
	return ret;
}
static const struct ctl_table stackleak_sysctls[] = {
	{
		.procname	= "stack_erasing",
		.data		= NULL,
		.maxlen		= sizeof(int),
		.mode		= 0600,
		.proc_handler	= stack_erasing_sysctl,
		.extra1		= SYSCTL_ZERO,
		.extra2		= SYSCTL_ONE,
	},
};

static int __init stackleak_sysctls_init(void)
{
	register_sysctl_init("kernel", stackleak_sysctls);
	return 0;
}
late_initcall(stackleak_sysctls_init);
#endif /* CONFIG_SYSCTL */

#define skip_erasing()	static_branch_unlikely(&stack_erasing_bypass)
#else
#define skip_erasing()	false
#endif /* CONFIG_KSTACK_ERASE_RUNTIME_DISABLE */

#ifndef __stackleak_poison
static __always_inline void __stackleak_poison(unsigned long erase_low,
					       unsigned long erase_high,
					       unsigned long poison)
{
	while (erase_low < erase_high) {
		*(unsigned long *)erase_low = poison;
		erase_low += sizeof(unsigned long);
	}
}
#endif

static __always_inline void __stackleak_erase(bool on_task_stack)
{
	const unsigned long task_stack_low = stackleak_task_low_bound(current);
	const unsigned long task_stack_high = stackleak_task_high_bound(current);
	unsigned long erase_low, erase_high;

	erase_low = stackleak_find_top_of_poison(task_stack_low,
						 current->lowest_stack);

#ifdef CONFIG_KSTACK_ERASE_METRICS
	current->prev_lowest_stack = erase_low;
#endif

	/*
	 * Write poison to the task's stack between 'erase_low' and
	 * 'erase_high'.
	 *
	 * If we're running on a different stack (e.g. an entry trampoline
	 * stack) we can erase everything below the pt_regs at the top of the
	 * task stack.
	 *
	 * If we're running on the task stack itself, we must not clobber any
	 * stack used by this function and its caller. We assume that this
	 * function has a fixed-size stack frame, and the current stack pointer
	 * doesn't change while we write poison.
	 */
	if (on_task_stack)
		erase_high = current_stack_pointer;
	else
		erase_high = task_stack_high;

	__stackleak_poison(erase_low, erase_high, KSTACK_ERASE_POISON);

	/* Reset the 'lowest_stack' value for the next syscall */
	current->lowest_stack = task_stack_high;
}

/*
 * Erase and poison the portion of the task stack used since the last erase.
 * Can be called from the task stack or an entry stack when the task stack is
 * no longer in use.
 */
asmlinkage void noinstr stackleak_erase(void)
{
	if (skip_erasing())
		return;

	__stackleak_erase(on_thread_stack());
}

/*
 * Erase and poison the portion of the task stack used since the last erase.
 * Can only be called from the task stack.
 */
asmlinkage void noinstr stackleak_erase_on_task_stack(void)
{
	if (skip_erasing())
		return;

	__stackleak_erase(true);
}

/*
 * Erase and poison the portion of the task stack used since the last erase.
 * Can only be called from a stack other than the task stack.
 */
asmlinkage void noinstr stackleak_erase_off_task_stack(void)
{
	if (skip_erasing())
		return;

	__stackleak_erase(false);
}

void __used __no_caller_saved_registers noinstr __sanitizer_cov_stack_depth(void)
{
	unsigned long sp = current_stack_pointer;

	/*
	 * Having CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE larger than
	 * KSTACK_ERASE_SEARCH_DEPTH makes the poison search in
	 * stackleak_erase() unreliable. Let's prevent that.
	 */
	BUILD_BUG_ON(CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE > KSTACK_ERASE_SEARCH_DEPTH);

	/* 'lowest_stack' should be aligned on the register width boundary */
	sp = ALIGN(sp, sizeof(unsigned long));
	if (sp < current->lowest_stack &&
	    sp >= stackleak_task_low_bound(current)) {
		current->lowest_stack = sp;
	}
}
EXPORT_SYMBOL(__sanitizer_cov_stack_depth);
