[FIX] Change safe_arm and safe_thumb type
[kernel/swap-modules.git] / kprobe / dbi_uprobes.c
1 /*
2  *  Dynamic Binary Instrumentation Module based on KProbes
3  *  modules/kprobe/dbi_uprobes.h
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2006-2010
20  *
21  * 2008-2009    Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
22  *              Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
23  * 2010         Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
24  *
25  */
26
27
28 #include "dbi_uprobes.h"
29 #include "dbi_insn_slots.h"
30 #include "dbi_kdebug.h"
31
32 #include <linux/hash.h>
33 #include <linux/mempolicy.h>
34 #include <linux/module.h>
35
36 struct hlist_head uprobe_insn_slot_table[KPROBE_TABLE_SIZE];
37
38
39 #define DEBUG_PRINT_HASH_TABLE 0
40
41 #if DEBUG_PRINT_HASH_TABLE
42 void print_kprobe_hash_table(void)
43 {
44         int i;
45         struct hlist_head *head;
46         struct hlist_node *node;
47         struct kprobe *p;
48
49         // print uprobe table
50         for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
51                 head = &kprobe_table[i];
52                 swap_hlist_for_each_entry_rcu (p, node, head, is_hlist_arm) {
53                         printk("####### find K tgid=%u, addr=%x\n",
54                                         p->tgid, p->addr);
55                 }
56         }
57 }
58
59 void print_kretprobe_hash_table(void)
60 {
61         int i;
62         struct hlist_head *head;
63         struct hlist_node *node;
64         struct kprobe *p;
65
66         // print uprobe table
67         for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
68                 head = &kretprobe_inst_table[i];
69                 swap_hlist_for_each_entry_rcu (p, node, head, is_hlist_arm) {
70                         printk("####### find KR tgid=%u, addr=%x\n",
71                                         p->tgid, p->addr);
72                 }
73         }
74 }
75
76 void print_uprobe_hash_table(void)
77 {
78         int i;
79         struct hlist_head *head;
80         struct hlist_node *node;
81         struct kprobe *p;
82
83         // print uprobe table
84         for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
85                 head = &uprobe_insn_slot_table[i];
86                 swap_hlist_for_each_entry_rcu (p, node, head, is_hlist_arm) {
87                         printk("####### find U tgid=%u, addr=%x\n",
88                                         p->tgid, p->addr);
89                 }
90         }
91 }
92 #endif
93
94
95 static void add_uprobe_table(struct kprobe *p)
96 {
97 #ifdef CONFIG_ARM
98         INIT_HLIST_NODE(&p->is_hlist_arm);
99         hlist_add_head_rcu(&p->is_hlist_arm, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn_arm, KPROBE_HASH_BITS)]);
100         INIT_HLIST_NODE(&p->is_hlist_thumb);
101         hlist_add_head_rcu(&p->is_hlist_thumb, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn_thumb, KPROBE_HASH_BITS)]);
102 #else /* CONFIG_ARM */
103         INIT_HLIST_NODE(&p->is_hlist);
104         hlist_add_head_rcu(&p->is_hlist, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn, KPROBE_HASH_BITS)]);
105 #endif /* CONFIG_ARM */
106 }
107
108
109 static int __register_uprobe(struct kprobe *p, struct task_struct *task, int atomic)
110 {
111         int ret = 0;
112         struct kprobe *old_p;
113
114         if (!p->addr) {
115                 return -EINVAL;
116         }
117
118         DBPRINTF("p->addr = 0x%p p = 0x%p\n", p->addr, p);
119
120 // thumb address = address-1;
121 #if defined(CONFIG_ARM)
122         // TODO: must be corrected in 'bundle'
123         if ((unsigned long) p->addr & 0x01) {
124                 p->addr = (kprobe_opcode_t *)((unsigned long)p->addr & 0xfffffffe);
125         }
126 #endif
127
128         p->mod_refcounted = 0;
129         p->nmissed = 0;
130         INIT_LIST_HEAD(&p->list);
131 #ifdef KPROBES_PROFILE
132         p->start_tm.tv_sec = p->start_tm.tv_usec = 0;
133         p->hnd_tm_sum.tv_sec = p->hnd_tm_sum.tv_usec = 0;
134         p->count = 0;
135 #endif
136
137         // get the first item
138         old_p = get_kprobe(p->addr, p->tgid);
139         if (old_p) {
140 #ifdef CONFIG_ARM
141                 p->safe_arm = old_p->safe_arm;
142                 p->safe_thumb = old_p->safe_thumb;
143 #endif
144                 ret = register_aggr_kprobe(old_p, p);
145                 if (!ret) {
146                         atomic_inc(&kprobe_count);
147                         add_uprobe_table(p);
148                 }
149                 DBPRINTF("goto out\n", ret);
150                 goto out;
151         }
152
153         ret = arch_prepare_uprobe(p, task, atomic);
154         if (ret) {
155                 DBPRINTF("goto out\n", ret);
156                 goto out;
157         }
158
159         DBPRINTF ("before out ret = 0x%x\n", ret);
160
161         // TODO: add uprobe (must be in function)
162         INIT_HLIST_NODE(&p->hlist);
163         hlist_add_head_rcu(&p->hlist, &kprobe_table[hash_ptr (p->addr, KPROBE_HASH_BITS)]);
164         add_uprobe_table(p);
165         arch_arm_uprobe(p, task);
166
167 out:
168         DBPRINTF("out ret = 0x%x\n", ret);
169         return ret;
170 }
171
172 void unregister_uprobe(struct kprobe *p, struct task_struct *task, int atomic)
173 {
174         dbi_unregister_kprobe (p, task);
175 }
176
177
178 int dbi_register_ujprobe(struct task_struct *task, struct jprobe *jp, int atomic)
179 {
180         int ret = 0;
181
182         /* Todo: Verify probepoint is a function entry point */
183         jp->kp.pre_handler = setjmp_pre_handler;
184         jp->kp.break_handler = longjmp_break_handler;
185
186         ret = __register_uprobe(&jp->kp, task, atomic);
187
188         return ret;
189 }
190
191 void dbi_unregister_ujprobe(struct task_struct *task, struct jprobe *jp, int atomic)
192 {
193         unregister_uprobe(&jp->kp, task, atomic);
194         /*
195          * Here is an attempt to unregister even those probes that have not been
196          * installed (hence not added to the hlist).
197          * So if we try to delete them from the hlist we will get NULL pointer
198          * dereference error. That is why we check whether this node
199          * really belongs to the hlist.
200          */
201 #ifdef CONFIG_ARM
202         if (!(hlist_unhashed(&jp->kp.is_hlist_arm))) {
203                 hlist_del_rcu(&jp->kp.is_hlist_arm);
204         }
205         if (!(hlist_unhashed(&jp->kp.is_hlist_thumb))) {
206                 hlist_del_rcu(&jp->kp.is_hlist_thumb);
207         }
208 #else /* CONFIG_ARM */
209         if (!(hlist_unhashed(&jp->kp.is_hlist))) {
210                 hlist_del_rcu(&jp->kp.is_hlist);
211         }
212 #endif /* CONFIG_ARM */
213 }
214
215 int dbi_register_uretprobe(struct task_struct *task, struct kretprobe *rp, int atomic)
216 {
217         int i, ret = 0;
218         struct kretprobe_instance *inst;
219
220         DBPRINTF ("START\n");
221
222         rp->kp.pre_handler = pre_handler_kretprobe;
223         rp->kp.post_handler = NULL;
224         rp->kp.fault_handler = NULL;
225         rp->kp.break_handler = NULL;
226
227         rp->disarm = 0;
228
229         /* Pre-allocate memory for max kretprobe instances */
230         if (rp->maxactive <= 0) {
231 #if 1//def CONFIG_PREEMPT
232                 rp->maxactive = max(10, 2 * NR_CPUS);
233 #else
234                 rp->maxactive = NR_CPUS;
235 #endif
236         }
237
238         INIT_HLIST_HEAD(&rp->used_instances);
239         INIT_HLIST_HEAD(&rp->free_instances);
240
241         for (i = 0; i < rp->maxactive; i++) {
242                 inst = kmalloc(sizeof(*inst), GFP_KERNEL);
243                 if (inst == NULL) {
244                         free_rp_inst (rp);
245                         ret = -ENOMEM;
246                         goto out;
247                 }
248
249                 INIT_HLIST_NODE(&inst->uflist);
250                 hlist_add_head(&inst->uflist, &rp->free_instances);
251         }
252
253         rp->nmissed = 0;
254
255         /* Establish function exit probe point */
256         ret = arch_prepare_uretprobe(rp, task);
257         if (ret) {
258                 goto out;
259         }
260
261         /* Establish function entry probe point */
262         ret = __register_uprobe(&rp->kp, task, atomic);
263         if (ret) {
264                 free_rp_inst(rp);
265                 goto out;
266         }
267
268         arch_arm_uretprobe(rp, task);
269 out:
270         return ret;
271 }
272
273 int dbi_disarm_urp_inst(struct kretprobe_instance *ri, struct task_struct *rm_task)
274 {
275         struct task_struct *task = rm_task ? rm_task : ri->task;
276         unsigned long *tramp;
277         unsigned long *sp = (unsigned long *)((long)ri->sp & ~1);
278         unsigned long *stack = sp - RETPROBE_STACK_DEPTH + 1;
279         unsigned long *found = NULL;
280         unsigned long *buf[RETPROBE_STACK_DEPTH];
281         int i, retval;
282
283         /* Understand function mode */
284         if ((long)ri->sp & 1) {
285                 tramp = (unsigned long *)
286                         ((unsigned long)ri->rp->kp.ainsn.insn + 0x1b);
287         } else {
288                 tramp = (unsigned long *)
289                         (ri->rp->kp.ainsn.insn + UPROBES_TRAMP_RET_BREAK_IDX);
290         }
291
292         retval = read_proc_vm_atomic(task, (unsigned long)stack, buf, sizeof(buf));
293         if (retval != sizeof(buf)) {
294                 printk("---> %s (%d/%d): failed to read stack from %08lx",
295                         task->comm, task->tgid, task->pid, (unsigned long)stack);
296                 retval = -EFAULT;
297                 goto out;
298         }
299
300         /* search the stack from the bottom */
301         for (i = RETPROBE_STACK_DEPTH - 1; i >= 0; i--) {
302                 if (buf[i] == tramp) {
303                         found = stack + i;
304                         break;
305                 }
306         }
307
308         if (found) {
309                 printk("---> %s (%d/%d): trampoline found at %08lx (%08lx /%+d) - %p\n",
310                                 task->comm, task->tgid, task->pid,
311                                 (unsigned long)found, (unsigned long)sp,
312                                 found - sp, ri->rp->kp.addr);
313                 retval = write_proc_vm_atomic(task, (unsigned long)found, &ri->ret_addr,
314                                 sizeof(ri->ret_addr));
315                 if (retval != sizeof(ri->ret_addr)) {
316                         printk("---> %s (%d/%d): failed to write value to %08lx",
317                                 task->comm, task->tgid, task->pid, (unsigned long)found);
318                         retval = -EFAULT;
319                 } else {
320                         retval = 0;
321                 }
322         } else {
323                 struct pt_regs *uregs = task_pt_regs(ri->task);
324                 unsigned long ra = dbi_get_ret_addr(uregs);
325                 if (ra == (unsigned long)tramp) {
326                         printk("---> %s (%d/%d): trampoline found at lr = %08lx - %p\n",
327                                         task->comm, task->tgid, task->pid, ra, ri->rp->kp.addr);
328                         dbi_set_ret_addr(uregs, (unsigned long)tramp);
329                         retval = 0;
330                 } else {
331                         printk("---> %s (%d/%d): trampoline NOT found at sp = %08lx, lr = %08lx - %p\n",
332                                         task->comm, task->tgid, task->pid,
333                                         (unsigned long)sp, ra, ri->rp->kp.addr);
334                         retval = -ENOENT;
335                 }
336         }
337
338 out:
339         return retval;
340 }
341
342 void dbi_unregister_uretprobe(struct task_struct *task, struct kretprobe *rp, int atomic, int not_rp2)
343 {
344         unsigned long flags;
345         struct kretprobe_instance *ri;
346         struct kretprobe *rp2 = NULL;
347
348         spin_lock_irqsave (&kretprobe_lock, flags);
349
350         while ((ri = get_used_rp_inst(rp)) != NULL) {
351                 if (dbi_disarm_urp_inst(ri, NULL) != 0)
352                         /*panic*/printk("%s (%d/%d): cannot disarm urp instance (%08lx)\n",
353                                         ri->task->comm, ri->task->tgid, ri->task->pid,
354                                         (unsigned long)rp->kp.addr);
355                 recycle_rp_inst(ri);
356         }
357
358         if (hlist_empty(&rp->used_instances) || not_rp2) {
359                 struct kprobe *p = &rp->kp;
360                 // if there are no used retprobe instances (i.e. function is not entered) - disarm retprobe
361                 arch_disarm_uretprobe(rp, task);//vmas[1], pages[1], kaddrs[1]);
362 #ifdef CONFIG_ARM
363                 if (!(hlist_unhashed(&p->is_hlist_arm))) {
364                         hlist_del_rcu(&p->is_hlist_arm);
365                 }
366
367                 if (!(hlist_unhashed(&p->is_hlist_thumb))) {
368                         hlist_del_rcu(&p->is_hlist_thumb);
369                 }
370 #else /* CONFIG_ARM */
371                 if (!(hlist_unhashed(&p->is_hlist))) {
372                         hlist_del_rcu(&p->is_hlist);
373                 }
374 #endif /* CONFIG_ARM */
375         } else {
376                 struct kprobe *new_p = NULL;
377                 struct kprobe *p = &rp->kp;
378                 rp2 = clone_kretprobe(rp);
379                 if (!rp2) {
380                         DBPRINTF ("dbi_unregister_uretprobe addr %p: failed to clone retprobe!", rp->kp.addr);
381                 } else {
382                         DBPRINTF ("initiating deferred retprobe deletion addr %p", rp->kp.addr);
383                         printk ("initiating deferred retprobe deletion addr %p\n", rp->kp.addr);
384                         arch_disarm_uprobe(&rp->kp, task);
385                         rp2->disarm = 1;
386                 }
387                 /*
388                  * As we cloned retprobe we have to update the entry in the insn slot
389                  * hash list.
390                  */
391 #ifdef CONFIG_ARM
392                 if (!(hlist_unhashed(&p->is_hlist_arm))) {
393                         hlist_del_rcu(&p->is_hlist_arm);
394                 }
395                 if (!(hlist_unhashed(&p->is_hlist_thumb))) {
396                         hlist_del_rcu(&p->is_hlist_thumb);
397                 }
398 #else /* CONFIG_ARM */
399                 if (!(hlist_unhashed(&p->is_hlist))) {
400                         hlist_del_rcu(&p->is_hlist);
401                 }
402 #endif /* CONFIG_ARM */
403                 new_p = &rp2->kp;
404                 add_uprobe_table(new_p);
405         }
406
407         while ((ri = get_used_rp_inst(rp)) != NULL) {
408                 ri->rp = NULL;
409                 ri->rp2 = rp2;
410                 hlist_del(&ri->uflist);
411         }
412
413         spin_unlock_irqrestore(&kretprobe_lock, flags);
414         free_rp_inst(rp);
415
416         unregister_uprobe(&rp->kp, task, atomic);
417 }
418
419 void dbi_unregister_all_uprobes(struct task_struct *task, int atomic)
420 {
421         struct hlist_head *head;
422         struct hlist_node *node, *tnode;
423         struct kprobe *p;
424         int i;
425
426         for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
427                 head = &kprobe_table[i];
428                 swap_hlist_for_each_entry_safe(p, node, tnode, head, hlist) {
429                         if (p->tgid == task->tgid) {
430                                 printk("dbi_unregister_all_uprobes: delete uprobe at %p[%lx] for %s/%d\n",
431                                                 p->addr, (unsigned long)p->opcode, task->comm, task->pid);
432                                 unregister_uprobe(p, task, atomic);
433                         }
434                 }
435         }
436 }
437
438 void init_uprobes_insn_slots(int i)
439 {
440         INIT_HLIST_HEAD(&uprobe_insn_slot_table[i]);
441 }
442
443 void dbi_uprobe_return(void)
444 {
445         dbi_arch_uprobe_return();
446 }
447
448
449 EXPORT_SYMBOL_GPL(dbi_uprobe_return);
450 EXPORT_SYMBOL_GPL(dbi_register_ujprobe);
451 EXPORT_SYMBOL_GPL(dbi_unregister_ujprobe);
452 EXPORT_SYMBOL_GPL(dbi_register_uretprobe);
453 EXPORT_SYMBOL_GPL(dbi_unregister_uretprobe);
454 EXPORT_SYMBOL_GPL(dbi_unregister_all_uprobes);