xref: /linux/arch/x86/mm/extable.c (revision 26b433d0da062d6e19d75350c0171d3cf8ff560d)
1 #include <linux/extable.h>
2 #include <linux/uaccess.h>
3 #include <linux/sched/debug.h>
4 
5 #include <asm/traps.h>
6 #include <asm/kdebug.h>
7 
8 typedef bool (*ex_handler_t)(const struct exception_table_entry *,
9 			    struct pt_regs *, int);
10 
11 static inline unsigned long
12 ex_fixup_addr(const struct exception_table_entry *x)
13 {
14 	return (unsigned long)&x->fixup + x->fixup;
15 }
16 static inline ex_handler_t
17 ex_fixup_handler(const struct exception_table_entry *x)
18 {
19 	return (ex_handler_t)((unsigned long)&x->handler + x->handler);
20 }
21 
22 bool ex_handler_default(const struct exception_table_entry *fixup,
23 		       struct pt_regs *regs, int trapnr)
24 {
25 	regs->ip = ex_fixup_addr(fixup);
26 	return true;
27 }
28 EXPORT_SYMBOL(ex_handler_default);
29 
30 bool ex_handler_fault(const struct exception_table_entry *fixup,
31 		     struct pt_regs *regs, int trapnr)
32 {
33 	regs->ip = ex_fixup_addr(fixup);
34 	regs->ax = trapnr;
35 	return true;
36 }
37 EXPORT_SYMBOL_GPL(ex_handler_fault);
38 
39 /*
40  * Handler for UD0 exception following a failed test against the
41  * result of a refcount inc/dec/add/sub.
42  */
43 bool ex_handler_refcount(const struct exception_table_entry *fixup,
44 			 struct pt_regs *regs, int trapnr)
45 {
46 	/* First unconditionally saturate the refcount. */
47 	*(int *)regs->cx = INT_MIN / 2;
48 
49 	/*
50 	 * Strictly speaking, this reports the fixup destination, not
51 	 * the fault location, and not the actually overflowing
52 	 * instruction, which is the instruction before the "js", but
53 	 * since that instruction could be a variety of lengths, just
54 	 * report the location after the overflow, which should be close
55 	 * enough for finding the overflow, as it's at least back in
56 	 * the function, having returned from .text.unlikely.
57 	 */
58 	regs->ip = ex_fixup_addr(fixup);
59 
60 	/*
61 	 * This function has been called because either a negative refcount
62 	 * value was seen by any of the refcount functions, or a zero
63 	 * refcount value was seen by refcount_dec().
64 	 *
65 	 * If we crossed from INT_MAX to INT_MIN, OF (Overflow Flag: result
66 	 * wrapped around) will be set. Additionally, seeing the refcount
67 	 * reach 0 will set ZF (Zero Flag: result was zero). In each of
68 	 * these cases we want a report, since it's a boundary condition.
69 	 *
70 	 */
71 	if (regs->flags & (X86_EFLAGS_OF | X86_EFLAGS_ZF)) {
72 		bool zero = regs->flags & X86_EFLAGS_ZF;
73 
74 		refcount_error_report(regs, zero ? "hit zero" : "overflow");
75 	}
76 
77 	return true;
78 }
79 EXPORT_SYMBOL_GPL(ex_handler_refcount);
80 
81 bool ex_handler_ext(const struct exception_table_entry *fixup,
82 		   struct pt_regs *regs, int trapnr)
83 {
84 	/* Special hack for uaccess_err */
85 	current->thread.uaccess_err = 1;
86 	regs->ip = ex_fixup_addr(fixup);
87 	return true;
88 }
89 EXPORT_SYMBOL(ex_handler_ext);
90 
91 bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
92 			     struct pt_regs *regs, int trapnr)
93 {
94 	if (pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pF)\n",
95 			 (unsigned int)regs->cx, regs->ip, (void *)regs->ip))
96 		show_stack_regs(regs);
97 
98 	/* Pretend that the read succeeded and returned 0. */
99 	regs->ip = ex_fixup_addr(fixup);
100 	regs->ax = 0;
101 	regs->dx = 0;
102 	return true;
103 }
104 EXPORT_SYMBOL(ex_handler_rdmsr_unsafe);
105 
106 bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
107 			     struct pt_regs *regs, int trapnr)
108 {
109 	if (pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pF)\n",
110 			 (unsigned int)regs->cx, (unsigned int)regs->dx,
111 			 (unsigned int)regs->ax,  regs->ip, (void *)regs->ip))
112 		show_stack_regs(regs);
113 
114 	/* Pretend that the write succeeded. */
115 	regs->ip = ex_fixup_addr(fixup);
116 	return true;
117 }
118 EXPORT_SYMBOL(ex_handler_wrmsr_unsafe);
119 
120 bool ex_handler_clear_fs(const struct exception_table_entry *fixup,
121 			 struct pt_regs *regs, int trapnr)
122 {
123 	if (static_cpu_has(X86_BUG_NULL_SEG))
124 		asm volatile ("mov %0, %%fs" : : "rm" (__USER_DS));
125 	asm volatile ("mov %0, %%fs" : : "rm" (0));
126 	return ex_handler_default(fixup, regs, trapnr);
127 }
128 EXPORT_SYMBOL(ex_handler_clear_fs);
129 
130 bool ex_has_fault_handler(unsigned long ip)
131 {
132 	const struct exception_table_entry *e;
133 	ex_handler_t handler;
134 
135 	e = search_exception_tables(ip);
136 	if (!e)
137 		return false;
138 	handler = ex_fixup_handler(e);
139 
140 	return handler == ex_handler_fault;
141 }
142 
143 int fixup_exception(struct pt_regs *regs, int trapnr)
144 {
145 	const struct exception_table_entry *e;
146 	ex_handler_t handler;
147 
148 #ifdef CONFIG_PNPBIOS
149 	if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
150 		extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
151 		extern u32 pnp_bios_is_utter_crap;
152 		pnp_bios_is_utter_crap = 1;
153 		printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
154 		__asm__ volatile(
155 			"movl %0, %%esp\n\t"
156 			"jmp *%1\n\t"
157 			: : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip));
158 		panic("do_trap: can't hit this");
159 	}
160 #endif
161 
162 	e = search_exception_tables(regs->ip);
163 	if (!e)
164 		return 0;
165 
166 	handler = ex_fixup_handler(e);
167 	return handler(e, regs, trapnr);
168 }
169 
170 extern unsigned int early_recursion_flag;
171 
172 /* Restricted version used during very early boot */
173 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
174 {
175 	/* Ignore early NMIs. */
176 	if (trapnr == X86_TRAP_NMI)
177 		return;
178 
179 	if (early_recursion_flag > 2)
180 		goto halt_loop;
181 
182 	/*
183 	 * Old CPUs leave the high bits of CS on the stack
184 	 * undefined.  I'm not sure which CPUs do this, but at least
185 	 * the 486 DX works this way.
186 	 */
187 	if (regs->cs != __KERNEL_CS)
188 		goto fail;
189 
190 	/*
191 	 * The full exception fixup machinery is available as soon as
192 	 * the early IDT is loaded.  This means that it is the
193 	 * responsibility of extable users to either function correctly
194 	 * when handlers are invoked early or to simply avoid causing
195 	 * exceptions before they're ready to handle them.
196 	 *
197 	 * This is better than filtering which handlers can be used,
198 	 * because refusing to call a handler here is guaranteed to
199 	 * result in a hard-to-debug panic.
200 	 *
201 	 * Keep in mind that not all vectors actually get here.  Early
202 	 * fage faults, for example, are special.
203 	 */
204 	if (fixup_exception(regs, trapnr))
205 		return;
206 
207 	if (fixup_bug(regs, trapnr))
208 		return;
209 
210 fail:
211 	early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n",
212 		     (unsigned)trapnr, (unsigned long)regs->cs, regs->ip,
213 		     regs->orig_ax, read_cr2());
214 
215 	show_regs(regs);
216 
217 halt_loop:
218 	while (true)
219 		halt();
220 }
221