1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/config.h>
31#include <linux/kprobes.h>
32#include <linux/ptrace.h>
33#include <linux/spinlock.h>
34#include <linux/string.h>
35#include <linux/slab.h>
36#include <linux/preempt.h>
37#include <linux/vmalloc.h>
38
39#include <asm/pgtable.h>
40#include <asm/kdebug.h>
41
42static DECLARE_MUTEX(kprobe_mutex);
43
44
45#define KPROBE_HIT_ACTIVE 0x00000001
46#define KPROBE_HIT_SS 0x00000002
47
48static struct kprobe *current_kprobe;
49static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags;
50static struct pt_regs jprobe_saved_regs;
51static long *jprobe_saved_rsp;
52static kprobe_opcode_t *get_insn_slot(void);
53static void free_insn_slot(kprobe_opcode_t *slot);
54void jprobe_return_end(void);
55
56
57static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
58
59
60
61
62static inline int is_IF_modifier(kprobe_opcode_t *insn)
63{
64 switch (*insn) {
65 case 0xfa:
66 case 0xfb:
67 case 0xcf:
68 case 0x9d:
69 return 1;
70 }
71
72 if (*insn >= 0x40 && *insn <= 0x4f && *++insn == 0xcf)
73 return 1;
74 return 0;
75}
76
77int arch_prepare_kprobe(struct kprobe *p)
78{
79
80 up(&kprobe_mutex);
81 p->ainsn.insn = get_insn_slot();
82 down(&kprobe_mutex);
83 if (!p->ainsn.insn) {
84 return -ENOMEM;
85 }
86 return 0;
87}
88
89void arch_copy_kprobe(struct kprobe *p)
90{
91 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
92}
93
94void arch_remove_kprobe(struct kprobe *p)
95{
96 up(&kprobe_mutex);
97 free_insn_slot(p->ainsn.insn);
98 down(&kprobe_mutex);
99}
100
101static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
102{
103 *p->addr = p->opcode;
104 regs->rip = (unsigned long)p->addr;
105}
106
107static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
108{
109 regs->eflags |= TF_MASK;
110 regs->eflags &= ~IF_MASK;
111
112 regs->rip = (unsigned long)p->ainsn.insn;
113}
114
115
116
117
118
119int kprobe_handler(struct pt_regs *regs)
120{
121 struct kprobe *p;
122 int ret = 0;
123 kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t));
124
125
126 preempt_disable();
127
128
129 if (kprobe_running()) {
130
131
132 p = get_kprobe(addr);
133 if (p) {
134 disarm_kprobe(p, regs);
135 ret = 1;
136 } else {
137 p = current_kprobe;
138 if (p->break_handler && p->break_handler(p, regs)) {
139 goto ss_probe;
140 }
141 }
142
143 goto no_kprobe;
144 }
145
146 lock_kprobes();
147 p = get_kprobe(addr);
148 if (!p) {
149 unlock_kprobes();
150 if (*addr != BREAKPOINT_INSTRUCTION) {
151
152
153
154
155
156
157
158 ret = 1;
159 }
160
161 goto no_kprobe;
162 }
163
164 kprobe_status = KPROBE_HIT_ACTIVE;
165 current_kprobe = p;
166 kprobe_saved_rflags = kprobe_old_rflags
167 = (regs->eflags & (TF_MASK | IF_MASK));
168 if (is_IF_modifier(p->ainsn.insn))
169 kprobe_saved_rflags &= ~IF_MASK;
170
171 if (p->pre_handler(p, regs)) {
172
173 return 1;
174 }
175
176 ss_probe:
177 prepare_singlestep(p, regs);
178 kprobe_status = KPROBE_HIT_SS;
179 return 1;
180
181 no_kprobe:
182 preempt_enable_no_resched();
183 return ret;
184}
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208static void resume_execution(struct kprobe *p, struct pt_regs *regs)
209{
210 unsigned long *tos = (unsigned long *)regs->rsp;
211 unsigned long next_rip = 0;
212 unsigned long copy_rip = (unsigned long)p->ainsn.insn;
213 unsigned long orig_rip = (unsigned long)p->addr;
214 kprobe_opcode_t *insn = p->ainsn.insn;
215
216
217 if (*insn >= 0x40 && *insn <= 0x4f)
218 insn++;
219
220 switch (*insn) {
221 case 0x9c:
222 *tos &= ~(TF_MASK | IF_MASK);
223 *tos |= kprobe_old_rflags;
224 break;
225 case 0xe8:
226 *tos = orig_rip + (*tos - copy_rip);
227 break;
228 case 0xff:
229 if ((*insn & 0x30) == 0x10) {
230
231
232 next_rip = regs->rip;
233 *tos = orig_rip + (*tos - copy_rip);
234 } else if (((*insn & 0x31) == 0x20) ||
235 ((*insn & 0x31) == 0x21)) {
236
237 next_rip = regs->rip;
238 }
239 break;
240 case 0xea:
241 next_rip = regs->rip;
242 break;
243 default:
244 break;
245 }
246
247 regs->eflags &= ~TF_MASK;
248 if (next_rip) {
249 regs->rip = next_rip;
250 } else {
251 regs->rip = orig_rip + (regs->rip - copy_rip);
252 }
253}
254
255
256
257
258
259int post_kprobe_handler(struct pt_regs *regs)
260{
261 if (!kprobe_running())
262 return 0;
263
264 if (current_kprobe->post_handler)
265 current_kprobe->post_handler(current_kprobe, regs, 0);
266
267 resume_execution(current_kprobe, regs);
268 regs->eflags |= kprobe_saved_rflags;
269
270 unlock_kprobes();
271 preempt_enable_no_resched();
272
273
274
275
276
277
278 if (regs->eflags & TF_MASK)
279 return 0;
280
281 return 1;
282}
283
284
285int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
286{
287 if (current_kprobe->fault_handler
288 && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
289 return 1;
290
291 if (kprobe_status & KPROBE_HIT_SS) {
292 resume_execution(current_kprobe, regs);
293 regs->eflags |= kprobe_old_rflags;
294
295 unlock_kprobes();
296 preempt_enable_no_resched();
297 }
298 return 0;
299}
300
301
302
303
304int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
305 void *data)
306{
307 struct die_args *args = (struct die_args *)data;
308 switch (val) {
309 case DIE_INT3:
310 if (kprobe_handler(args->regs))
311 return NOTIFY_STOP;
312 break;
313 case DIE_DEBUG:
314 if (post_kprobe_handler(args->regs))
315 return NOTIFY_STOP;
316 break;
317 case DIE_GPF:
318 if (kprobe_running() &&
319 kprobe_fault_handler(args->regs, args->trapnr))
320 return NOTIFY_STOP;
321 break;
322 case DIE_PAGE_FAULT:
323 if (kprobe_running() &&
324 kprobe_fault_handler(args->regs, args->trapnr))
325 return NOTIFY_STOP;
326 break;
327 default:
328 break;
329 }
330 return NOTIFY_DONE;
331}
332
333int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
334{
335 struct jprobe *jp = container_of(p, struct jprobe, kp);
336 unsigned long addr;
337
338 jprobe_saved_regs = *regs;
339 jprobe_saved_rsp = (long *) regs->rsp;
340 addr = (unsigned long)jprobe_saved_rsp;
341
342
343
344
345
346
347
348 memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr));
349 regs->eflags &= ~IF_MASK;
350 regs->rip = (unsigned long)(jp->entry);
351 return 1;
352}
353
354void jprobe_return(void)
355{
356 preempt_enable_no_resched();
357 asm volatile (" xchg %%rbx,%%rsp \n"
358 " int3 \n"
359 " .globl jprobe_return_end \n"
360 " jprobe_return_end: \n"
361 " nop \n"::"b"
362 (jprobe_saved_rsp):"memory");
363}
364
365int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
366{
367 u8 *addr = (u8 *) (regs->rip - 1);
368 unsigned long stack_addr = (unsigned long)jprobe_saved_rsp;
369 struct jprobe *jp = container_of(p, struct jprobe, kp);
370
371 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
372 if ((long *)regs->rsp != jprobe_saved_rsp) {
373 struct pt_regs *saved_regs =
374 container_of(jprobe_saved_rsp, struct pt_regs, rsp);
375 printk("current rsp %p does not match saved rsp %p\n",
376 (long *)regs->rsp, jprobe_saved_rsp);
377 printk("Saved registers for jprobe %p\n", jp);
378 show_registers(saved_regs);
379 printk("Current registers\n");
380 show_registers(regs);
381 BUG();
382 }
383 *regs = jprobe_saved_regs;
384 memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack,
385 MIN_STACK_SIZE(stack_addr));
386 return 1;
387 }
388 return 0;
389}
390
391
392
393
394
395
396
397
398
399
400
401
402#define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE*sizeof(kprobe_opcode_t)))
403struct kprobe_insn_page {
404 struct hlist_node hlist;
405 kprobe_opcode_t *insns;
406 char slot_used[INSNS_PER_PAGE];
407 int nused;
408};
409
410static struct hlist_head kprobe_insn_pages;
411
412
413
414
415
416static kprobe_opcode_t *get_insn_slot(void)
417{
418 struct kprobe_insn_page *kip;
419 struct hlist_node *pos;
420
421 hlist_for_each(pos, &kprobe_insn_pages) {
422 kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
423 if (kip->nused < INSNS_PER_PAGE) {
424 int i;
425 for (i = 0; i < INSNS_PER_PAGE; i++) {
426 if (!kip->slot_used[i]) {
427 kip->slot_used[i] = 1;
428 kip->nused++;
429 return kip->insns + (i*MAX_INSN_SIZE);
430 }
431 }
432
433 kip->nused = INSNS_PER_PAGE;
434 }
435 }
436
437
438 kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL);
439 if (!kip) {
440 return NULL;
441 }
442 kip->insns = (kprobe_opcode_t*) __vmalloc(PAGE_SIZE,
443 GFP_KERNEL|__GFP_HIGHMEM, __pgprot(__PAGE_KERNEL_EXEC));
444 if (!kip->insns) {
445 kfree(kip);
446 return NULL;
447 }
448 INIT_HLIST_NODE(&kip->hlist);
449 hlist_add_head(&kip->hlist, &kprobe_insn_pages);
450 memset(kip->slot_used, 0, INSNS_PER_PAGE);
451 kip->slot_used[0] = 1;
452 kip->nused = 1;
453 return kip->insns;
454}
455
456
457
458
459static void free_insn_slot(kprobe_opcode_t *slot)
460{
461 struct kprobe_insn_page *kip;
462 struct hlist_node *pos;
463
464 hlist_for_each(pos, &kprobe_insn_pages) {
465 kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
466 if (kip->insns <= slot
467 && slot < kip->insns+(INSNS_PER_PAGE*MAX_INSN_SIZE)) {
468 int i = (slot - kip->insns) / MAX_INSN_SIZE;
469 kip->slot_used[i] = 0;
470 kip->nused--;
471 if (kip->nused == 0) {
472
473
474
475
476
477
478 hlist_del(&kip->hlist);
479 if (hlist_empty(&kprobe_insn_pages)) {
480 INIT_HLIST_NODE(&kip->hlist);
481 hlist_add_head(&kip->hlist,
482 &kprobe_insn_pages);
483 } else {
484 vfree(kip->insns);
485 kfree(kip);
486 }
487 }
488 return;
489 }
490 }
491}
492