Merge tag 'keys-cve-2020-26541-v3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / arch / x86 / kernel / dumpstack_32.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  Copyright (C) 1991, 1992  Linus Torvalds
4  *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
5  */
6 #include <linux/sched/debug.h>
7 #include <linux/kallsyms.h>
8 #include <linux/kprobes.h>
9 #include <linux/uaccess.h>
10 #include <linux/hardirq.h>
11 #include <linux/kdebug.h>
12 #include <linux/export.h>
13 #include <linux/ptrace.h>
14 #include <linux/kexec.h>
15 #include <linux/sysfs.h>
16 #include <linux/bug.h>
17 #include <linux/nmi.h>
18
19 #include <asm/stacktrace.h>
20
21 const char *stack_type_name(enum stack_type type)
22 {
23         if (type == STACK_TYPE_IRQ)
24                 return "IRQ";
25
26         if (type == STACK_TYPE_SOFTIRQ)
27                 return "SOFTIRQ";
28
29         if (type == STACK_TYPE_ENTRY)
30                 return "ENTRY_TRAMPOLINE";
31
32         if (type == STACK_TYPE_EXCEPTION)
33                 return "#DF";
34
35         return NULL;
36 }
37
38 static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info)
39 {
40         unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack_ptr);
41         unsigned long *end   = begin + (THREAD_SIZE / sizeof(long));
42
43         /*
44          * This is a software stack, so 'end' can be a valid stack pointer.
45          * It just means the stack is empty.
46          */
47         if (stack < begin || stack > end)
48                 return false;
49
50         info->type      = STACK_TYPE_IRQ;
51         info->begin     = begin;
52         info->end       = end;
53
54         /*
55          * See irq_32.c -- the next stack pointer is stored at the beginning of
56          * the stack.
57          */
58         info->next_sp   = (unsigned long *)*begin;
59
60         return true;
61 }
62
63 static bool in_softirq_stack(unsigned long *stack, struct stack_info *info)
64 {
65         unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack_ptr);
66         unsigned long *end   = begin + (THREAD_SIZE / sizeof(long));
67
68         /*
69          * This is a software stack, so 'end' can be a valid stack pointer.
70          * It just means the stack is empty.
71          */
72         if (stack < begin || stack > end)
73                 return false;
74
75         info->type      = STACK_TYPE_SOFTIRQ;
76         info->begin     = begin;
77         info->end       = end;
78
79         /*
80          * The next stack pointer is stored at the beginning of the stack.
81          * See irq_32.c.
82          */
83         info->next_sp   = (unsigned long *)*begin;
84
85         return true;
86 }
87
88 static bool in_doublefault_stack(unsigned long *stack, struct stack_info *info)
89 {
90         struct cpu_entry_area *cea = get_cpu_entry_area(raw_smp_processor_id());
91         struct doublefault_stack *ss = &cea->doublefault_stack;
92
93         void *begin = ss->stack;
94         void *end = begin + sizeof(ss->stack);
95
96         if ((void *)stack < begin || (void *)stack >= end)
97                 return false;
98
99         info->type      = STACK_TYPE_EXCEPTION;
100         info->begin     = begin;
101         info->end       = end;
102         info->next_sp   = (unsigned long *)this_cpu_read(cpu_tss_rw.x86_tss.sp);
103
104         return true;
105 }
106
107
108 int get_stack_info(unsigned long *stack, struct task_struct *task,
109                    struct stack_info *info, unsigned long *visit_mask)
110 {
111         if (!stack)
112                 goto unknown;
113
114         task = task ? : current;
115
116         if (in_task_stack(stack, task, info))
117                 goto recursion_check;
118
119         if (task != current)
120                 goto unknown;
121
122         if (in_entry_stack(stack, info))
123                 goto recursion_check;
124
125         if (in_hardirq_stack(stack, info))
126                 goto recursion_check;
127
128         if (in_softirq_stack(stack, info))
129                 goto recursion_check;
130
131         if (in_doublefault_stack(stack, info))
132                 goto recursion_check;
133
134         goto unknown;
135
136 recursion_check:
137         /*
138          * Make sure we don't iterate through any given stack more than once.
139          * If it comes up a second time then there's something wrong going on:
140          * just break out and report an unknown stack type.
141          */
142         if (visit_mask) {
143                 if (*visit_mask & (1UL << info->type)) {
144                         printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type);
145                         goto unknown;
146                 }
147                 *visit_mask |= 1UL << info->type;
148         }
149
150         return 0;
151
152 unknown:
153         info->type = STACK_TYPE_UNKNOWN;
154         return -EINVAL;
155 }