// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
 *
 */
#include <linux/sched/task_stack.h>
#include <linux/stacktrace.h>
#include <linux/kallsyms.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
#include <linux/module.h>
#include <linux/sysctl.h>
#include <linux/init.h>

#include <asm/setup.h>

#include "trace.h"

#define STACK_TRACE_ENTRIES 500

static unsigned long stack_dump_trace[STACK_TRACE_ENTRIES];
static unsigned stack_trace_index[STACK_TRACE_ENTRIES];

static unsigned int stack_trace_nr_entries;
static unsigned long stack_trace_max_size;
static arch_spinlock_t stack_trace_max_lock =
	(arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;

DEFINE_PER_CPU(int, disable_stack_tracer);
static DEFINE_MUTEX(stack_sysctl_mutex);

int stack_tracer_enabled;

static void print_max_stack(void)
{
	long i;
	int size;

	pr_emerg("        Depth    Size   Location    (%d entries)\n"
			   "        -----    ----   --------\n",
			   stack_trace_nr_entries);

	for (i = 0; i < stack_trace_nr_entries; i++) {
		if (i + 1 == stack_trace_nr_entries)
			size = stack_trace_index[i];
		else
			size = stack_trace_index[i] - stack_trace_index[i+1];

		pr_emerg("%3ld) %8d   %5d   %pS\n", i, stack_trace_index[i],
				size, (void *)stack_dump_trace[i]);
	}
}

/*
 * The stack tracer looks for a maximum stack at each call from a function. It
 * registers a callback from ftrace, and in that callback it examines the stack
 * size. It determines the stack size from the variable passed in, which is the
 * address of a local variable in the stack_trace_call() callback function.
 * The stack size is calculated by the address of the local variable to the top
 * of the current stack. If that size is smaller than the currently saved max
 * stack size, nothing more is done.
 *
 * If the size of the stack is greater than the maximum recorded size, then the
 * following algorithm takes place.
 *
 * For architectures (like x86) that store the function's return address before
 * saving the function's local variables, the stack will look something like
 * this:
 *
 *   [ top of stack ]
 *    0: sys call entry frame
 *   10: return addr to entry code
 *   11: start of sys_foo frame
 *   20: return addr to sys_foo
 *   21: start of kernel_func_bar frame
 *   30: return addr to kernel_func_bar
 *   31: [ do trace stack here ]
 *
 * The save_stack_trace() is called returning all the functions it finds in the
 * current stack. Which would be (from the bottom of the stack to the top):
 *
 *   return addr to kernel_func_bar
 *   return addr to sys_foo
 *   return addr to entry code
 *
 * Now to figure out how much each of these functions' local variable size is,
 * a search of the stack is made to find these values. When a match is made, it
 * is added to the stack_dump_trace[] array. The offset into the stack is saved
 * in the stack_trace_index[] array. The above example would show:
 *
 *        stack_dump_trace[]        |   stack_trace_index[]
 *        ------------------        +   -------------------
 *  return addr to kernel_func_bar  |          30
 *  return addr to sys_foo          |          20
 *  return addr to entry            |          10
 *
 * The print_max_stack() function above, uses these values to print the size of
 * each function's portion of the stack.
 *
 *  for (i = 0; i < nr_entries; i++) {
 *     size = i == nr_entries - 1 ? stack_trace_index[i] :
 *                    stack_trace_index[i] - stack_trace_index[i+1]
 *     print "%d %d %d %s\n", i, stack_trace_index[i], size, stack_dump_trace[i]);
 *  }
 *
 * The above shows
 *
 *     depth size  location
 *     ----- ----  --------
 *  0    30   10   kernel_func_bar
 *  1    20   10   sys_foo
 *  2    10   10   entry code
 *
 * Now for architectures that might save the return address after the functions
 * local variables (saving the link register before calling nested functions),
 * this will cause the stack to look a little different:
 *
 * [ top of stack ]
 *  0: sys call entry frame
 * 10: start of sys_foo_frame
 * 19: return addr to entry code << lr saved before calling kernel_func_bar
 * 20: start of kernel_func_bar frame
 * 29: return addr to sys_foo_frame << lr saved before calling next function
 * 30: [ do trace stack here ]
 *
 * Although the functions returned by save_stack_trace() may be the same, the
 * placement in the stack will be different. Using the same algorithm as above
 * would yield:
 *
 *        stack_dump_trace[]        |   stack_trace_index[]
 *        ------------------        +   -------------------
 *  return addr to kernel_func_bar  |          30
 *  return addr to sys_foo          |          29
 *  return addr to entry            |          19
 *
 * Where the mapping is off by one:
 *
 *   kernel_func_bar stack frame size is 29 - 19 not 30 - 29!
 *
 * To fix this, if the architecture sets ARCH_RET_ADDR_AFTER_LOCAL_VARS the
 * values in stack_trace_index[] are shifted by one to and the number of
 * stack trace entries is decremented by one.
 *
 *        stack_dump_trace[]        |   stack_trace_index[]
 *        ------------------        +   -------------------
 *  return addr to kernel_func_bar  |          29
 *  return addr to sys_foo          |          19
 *
 * Although the entry function is not displayed, the first function (sys_foo)
 * will still include the stack size of it.
 */
static void check_stack(unsigned long ip, unsigned long *stack)
{
	unsigned long this_size, flags; unsigned long *p, *top, *start;
	static int tracer_frame;
	int frame_size = READ_ONCE(tracer_frame);
	int i, x;

	this_size = ((unsigned long)stack) & (THREAD_SIZE-1);
	this_size = THREAD_SIZE - this_size;
	/* Remove the frame of the tracer */
	this_size -= frame_size;

	if (this_size <= stack_trace_max_size)
		return;

	/* we do not handle interrupt stacks yet */
	if (!object_is_on_stack(stack))
		return;

	/* Can't do this from NMI context (can cause deadlocks) */
	if (in_nmi())
		return;

	local_irq_save(flags);
	arch_spin_lock(&stack_trace_max_lock);

	/* In case another CPU set the tracer_frame on us */
	if (unlikely(!frame_size))
		this_size -= tracer_frame;

	/* a race could have already updated it */
	if (this_size <= stack_trace_max_size)
		goto out;

	stack_trace_max_size = this_size;

	stack_trace_nr_entries = stack_trace_save(stack_dump_trace,
					       ARRAY_SIZE(stack_dump_trace) - 1,
					       0);

	/* Skip over the overhead of the stack tracer itself */
	for (i = 0; i < stack_trace_nr_entries; i++) {
		if (stack_dump_trace[i] == ip)
			break;
	}

	/*
	 * Some archs may not have the passed in ip in the dump.
	 * If that happens, we need to show everything.
	 */
	if (i == stack_trace_nr_entries)
		i = 0;

	/*
	 * Now find where in the stack these are.
	 */
	x = 0;
	start = stack;
	top = (unsigned long *)
		(((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE);

	/*
	 * Loop through all the entries. One of the entries may
	 * for some reason be missed on the stack, so we may
	 * have to account for them. If they are all there, this
	 * loop will only happen once. This code only takes place
	 * on a new max, so it is far from a fast path.
	 */
	while (i < stack_trace_nr_entries) {
		int found = 0;

		stack_trace_index[x] = this_size;
		p = start;

		for (; p < top && i < stack_trace_nr_entries; p++) {
			/*
			 * The READ_ONCE_NOCHECK is used to let KASAN know that
			 * this is not a stack-out-of-bounds error.
			 */
			if ((READ_ONCE_NOCHECK(*p)) == stack_dump_trace[i]) {
				stack_dump_trace[x] = stack_dump_trace[i++];
				this_size = stack_trace_index[x++] =
					(top - p) * sizeof(unsigned long);
				found = 1;
				/* Start the search from here */
				start = p + 1;
				/*
				 * We do not want to show the overhead
				 * of the stack tracer stack in the
				 * max stack. If we haven't figured
				 * out what that is, then figure it out
				 * now.
				 */
				if (unlikely(!tracer_frame)) {
					tracer_frame = (p - stack) *
						sizeof(unsigned long);
					stack_trace_max_size -= tracer_frame;
				}
			}
		}

		if (!found)
			i++;
	}

#ifdef ARCH_FTRACE_SHIFT_STACK_TRACER
	/*
	 * Some archs will store the link register before calling
	 * nested functions. This means the saved return address
	 * comes after the local storage, and we need to shift
	 * for that.
	 */
	if (x > 1) {
		memmove(&stack_trace_index[0], &stack_trace_index[1],
			sizeof(stack_trace_index[0]) * (x - 1));
		x--;
	}
#endif

	stack_trace_nr_entries = x;

	if (task_stack_end_corrupted(current)) {
		print_max_stack();
		BUG();
	}

 out:
	arch_spin_unlock(&stack_trace_max_lock);
	local_irq_restore(flags);
}

static void
stack_trace_call(unsigned long ip, unsigned long parent_ip,
		 struct ftrace_ops *op, struct pt_regs *pt_regs)
{
	unsigned long stack;

	preempt_disable_notrace();

	/* no atomic needed, we only modify this variable by this cpu */
	__this_cpu_inc(disable_stack_tracer);
	if (__this_cpu_read(disable_stack_tracer) != 1)
		goto out;

	/* If rcu is not watching, then save stack trace can fail */
	if (!rcu_is_watching())
		goto out;

	ip += MCOUNT_INSN_SIZE;

	check_stack(ip, &stack);

 out:
	__this_cpu_dec(disable_stack_tracer);
	/* prevent recursion in schedule */
	preempt_enable_notrace();
}

static struct ftrace_ops trace_ops __read_mostly =
{
	.func = stack_trace_call,
	.flags = FTRACE_OPS_FL_RECURSION_SAFE,
};

static ssize_t
stack_max_size_read(struct file *filp, char __user *ubuf,
		    size_t count, loff_t *ppos)
{
	unsigned long *ptr = filp->private_data;
	char buf[64];
	int r;

	r = snprintf(buf, sizeof(buf), "%ld\n", *ptr);
	if (r > sizeof(buf))
		r = sizeof(buf);
	return simple_read_from_buffer(ubuf, count, ppos, buf, r);
}

static ssize_t
stack_max_size_write(struct file *filp, const char __user *ubuf,
		     size_t count, loff_t *ppos)
{
	long *ptr = filp->private_data;
	unsigned long val, flags;
	int ret;

	ret = kstrtoul_from_user(ubuf, count, 10, &val);
	if (ret)
		return ret;

	local_irq_save(flags);

	/*
	 * In case we trace inside arch_spin_lock() or after (NMI),
	 * we will cause circular lock, so we also need to increase
	 * the percpu disable_stack_tracer here.
	 */
	__this_cpu_inc(disable_stack_tracer);

	arch_spin_lock(&stack_trace_max_lock);
	*ptr = val;
	arch_spin_unlock(&stack_trace_max_lock);

	__this_cpu_dec(disable_stack_tracer);
	local_irq_restore(flags);

	return count;
}

static const struct file_operations stack_max_size_fops = {
	.open		= tracing_open_generic,
	.read		= stack_max_size_read,
	.write		= stack_max_size_write,
	.llseek		= default_llseek,
};

static void *
__next(struct seq_file *m, loff_t *pos)
{
	long n = *pos - 1;

	if (n >= stack_trace_nr_entries)
		return NULL;

	m->private = (void *)n;
	return &m->private;
}

static void *
t_next(struct seq_file *m, void *v, loff_t *pos)
{
	(*pos)++;
	return __next(m, pos);
}

static void *t_start(struct seq_file *m, loff_t *pos)
{
	local_irq_disable();

	__this_cpu_inc(disable_stack_tracer);

	arch_spin_lock(&stack_trace_max_lock);

	if (*pos == 0)
		return SEQ_START_TOKEN;

	return __next(m, pos);
}

static void t_stop(struct seq_file *m, void *p)
{
	arch_spin_unlock(&stack_trace_max_lock);

	__this_cpu_dec(disable_stack_tracer);

	local_irq_enable();
}

static void trace_lookup_stack(struct seq_file *m, long i)
{
	unsigned long addr = stack_dump_trace[i];

	seq_printf(m, "%pS\n", (void *)addr);
}

static void print_disabled(struct seq_file *m)
{
	seq_puts(m, "#\n"
		 "#  Stack tracer disabled\n"
		 "#\n"
		 "# To enable the stack tracer, either add 'stacktrace' to the\n"
		 "# kernel command line\n"
		 "# or 'echo 1 > /proc/sys/kernel/stack_tracer_enabled'\n"
		 "#\n");
}

static int t_show(struct seq_file *m, void *v)
{
	long i;
	int size;

	if (v == SEQ_START_TOKEN) {
		seq_printf(m, "        Depth    Size   Location"
			   "    (%d entries)\n"
			   "        -----    ----   --------\n",
			   stack_trace_nr_entries);

		if (!stack_tracer_enabled && !stack_trace_max_size)
			print_disabled(m);

		return 0;
	}

	i = *(long *)v;

	if (i >= stack_trace_nr_entries)
		return 0;

	if (i + 1 == stack_trace_nr_entries)
		size = stack_trace_index[i];
	else
		size = stack_trace_index[i] - stack_trace_index[i+1];

	seq_printf(m, "%3ld) %8d   %5d   ", i, stack_trace_index[i], size);

	trace_lookup_stack(m, i);

	return 0;
}

static const struct seq_operations stack_trace_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};

static int stack_trace_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &stack_trace_seq_ops);
}

static const struct file_operations stack_trace_fops = {
	.open		= stack_trace_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

#ifdef CONFIG_DYNAMIC_FTRACE

static int
stack_trace_filter_open(struct inode *inode, struct file *file)
{
	struct ftrace_ops *ops = inode->i_private;

	return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
				 inode, file);
}

static const struct file_operations stack_trace_filter_fops = {
	.open = stack_trace_filter_open,
	.read = seq_read,
	.write = ftrace_filter_write,
	.llseek = tracing_lseek,
	.release = ftrace_regex_release,
};

#endif /* CONFIG_DYNAMIC_FTRACE */

int
stack_trace_sysctl(struct ctl_table *table, int write,
		   void __user *buffer, size_t *lenp,
		   loff_t *ppos)
{
	int was_enabled;
	int ret;

	mutex_lock(&stack_sysctl_mutex);
	was_enabled = !!stack_tracer_enabled;

	ret = proc_dointvec(table, write, buffer, lenp, ppos);

	if (ret || !write || (was_enabled == !!stack_tracer_enabled))
		goto out;

	if (stack_tracer_enabled)
		register_ftrace_function(&trace_ops);
	else
		unregister_ftrace_function(&trace_ops);
 out:
	mutex_unlock(&stack_sysctl_mutex);
	return ret;
}

static char stack_trace_filter_buf[COMMAND_LINE_SIZE+1] __initdata;

static __init int enable_stacktrace(char *str)
{
	int len;

	if ((len = str_has_prefix(str, "_filter=")))
		strncpy(stack_trace_filter_buf, str + len, COMMAND_LINE_SIZE);

	stack_tracer_enabled = 1;
	return 1;
}
__setup("stacktrace", enable_stacktrace);

static __init int stack_trace_init(void)
{
	struct dentry *d_tracer;

	d_tracer = tracing_init_dentry();
	if (IS_ERR(d_tracer))
		return 0;

	trace_create_file("stack_max_size", 0644, d_tracer,
			&stack_trace_max_size, &stack_max_size_fops);

	trace_create_file("stack_trace", 0444, d_tracer,
			NULL, &stack_trace_fops);

#ifdef CONFIG_DYNAMIC_FTRACE
	trace_create_file("stack_trace_filter", 0644, d_tracer,
			  &trace_ops, &stack_trace_filter_fops);
#endif

	if (stack_trace_filter_buf[0])
		ftrace_set_early_filter(&trace_ops, stack_trace_filter_buf, 1);

	if (stack_tracer_enabled)
		register_ftrace_function(&trace_ops);

	return 0;
}

device_initcall(stack_trace_init);
