3 * modules/us_manager/helper.c
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.
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.
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.
19 * Copyright (C) Samsung Electronics, 2013
21 * 2013 Vyacheslav Cherkashin: SWAP us_manager implement
26 #include <kprobe/swap_kprobes.h>
27 #include <kprobe/swap_kprobes_deps.h>
28 #include <ksyms/ksyms.h>
29 #include <writer/kernel_operations.h>
30 #include "us_slot_manager.h"
31 #include "sspt/sspt.h"
32 #include "sspt/sspt_filter.h"
37 struct task_struct *check_task(struct task_struct *task);
39 static atomic_t stop_flag = ATOMIC_INIT(0);
43 ******************************************************************************
45 ******************************************************************************
51 #if defined(CONFIG_ARM)
52 struct pt_regs *pf_regs;
53 unsigned long save_pc;
54 #endif /* CONFIG_ARM */
57 static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
59 struct pf_data *data = (struct pf_data *)ri->data;
61 #if defined(CONFIG_ARM)
62 data->addr = swap_get_karg(regs, 0);
63 data->pf_regs = (struct pt_regs *)swap_get_karg(regs, 2);
64 data->save_pc = data->pf_regs->ARM_pc;
65 #elif defined(CONFIG_X86_32)
66 data->addr = read_cr2();
68 #error "this architecture is not supported"
69 #endif /* CONFIG_arch */
72 struct sspt_proc * proc = sspt_proc_get_by_task(current);
74 if (proc && (proc->r_state_addr == data->addr))
75 /* skip ret_handler_pf() for current task */
82 static unsigned long cb_pf(void *data)
84 unsigned long page_addr = *(unsigned long *)data;
86 call_page_fault(current, page_addr);
91 /* Detects when IPs are really loaded into phy mem and installs probes. */
92 static int ret_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
94 struct task_struct *task = current;
95 struct pf_data *data = (struct pf_data *)ri->data;
96 unsigned long page_addr;
102 #if defined(CONFIG_ARM)
103 /* skip fixup page_fault */
104 if (data->save_pc != data->pf_regs->ARM_pc)
106 #endif /* CONFIG_ARM */
108 /* TODO: check return value */
109 page_addr = data->addr & PAGE_MASK;
110 ret = set_jump_cb((unsigned long)ri->ret_addr, regs, cb_pf,
111 &page_addr, sizeof(page_addr));
114 ri->ret_addr = (unsigned long *)get_jump_addr();
119 static struct kretprobe mf_kretprobe = {
120 .entry_handler = entry_handler_pf,
121 .handler = ret_handler_pf,
122 .data_size = sizeof(struct pf_data)
125 static int register_mf(void)
129 ret = swap_register_kretprobe(&mf_kretprobe);
131 printk(KERN_INFO "swap_register_kretprobe(handle_mm_fault) ret=%d!\n",
137 static void unregister_mf(void)
139 swap_unregister_kretprobe(&mf_kretprobe);
148 ******************************************************************************
149 * workaround for already running *
150 ******************************************************************************
152 static unsigned long cb_check_and_install(void *data);
154 static int ctx_task_pre_handler(struct kprobe *p, struct pt_regs *regs)
157 struct sspt_proc *proc;
158 struct task_struct *task = current;
160 if (is_kthread(task) || check_task_on_filters(task) == 0)
163 proc = sspt_proc_get_by_task(task);
164 if (proc && proc->first_install)
167 ret = set_kjump_cb(regs, cb_check_and_install, NULL, 0);
169 pr_err("ctx_task_pre_handler: ret=%d\n", ret);
174 static struct kprobe ctx_task_kprobe = {
175 .pre_handler = ctx_task_pre_handler,
178 static int register_ctx_task(void)
182 ret = swap_register_kprobe(&ctx_task_kprobe);
184 printk(KERN_INFO "swap_register_kprobe(workaround) ret=%d!\n",
190 static void unregister_ctx_task(void)
192 swap_unregister_kprobe(&ctx_task_kprobe);
194 #endif /* CONFIG_ARM */
201 ******************************************************************************
203 ******************************************************************************
205 static void func_uinst_creare(struct us_ip *ip, void *data)
207 struct hlist_head *head = (struct hlist_head *)data;
210 up = probe_info_get_uprobe(ip->desc->type, ip);
212 struct uinst_info *uinst;
213 unsigned long vaddr = (unsigned long)up->addr;
215 uinst = uinst_info_create(vaddr, up->opcode);
217 hlist_add_head(&uinst->hlist, head);
221 static void disarm_for_task(struct task_struct *child, struct hlist_head *head)
223 struct uinst_info *uinst;
224 struct hlist_node *tmp;
225 DECLARE_NODE_PTR_FOR_HLIST(node);
227 swap_hlist_for_each_entry_safe(uinst, node, tmp, head, hlist) {
228 uinst_info_disarm(uinst, child);
229 hlist_del(&uinst->hlist);
230 uinst_info_destroy(uinst);
235 struct task_struct *task;
237 struct hlist_head head;
238 struct hlist_head rhead;
241 static atomic_t rm_uprobes_child_cnt = ATOMIC_INIT(0);
243 static unsigned long cb_clean_child(void *data)
245 struct clean_data *cdata = (struct clean_data *)data;
246 struct task_struct *child = cdata->task;
248 /* disarm up for child */
249 disarm_for_task(child, &cdata->head);
251 /* disarm urp for child */
252 urinst_info_put_current_hlist(&cdata->rhead, child);
254 atomic_dec(&rm_uprobes_child_cnt);
258 static void rm_uprobes_child(struct kretprobe_instance *ri,
259 struct pt_regs *regs, struct task_struct *child)
261 struct sspt_proc *proc;
262 struct clean_data cdata = {
264 .head = HLIST_HEAD_INIT,
265 .rhead = HLIST_HEAD_INIT
268 sspt_proc_write_lock();
269 proc = sspt_proc_get_by_task_no_lock(current);
271 sspt_proc_on_each_ip(proc, func_uinst_creare, (void *)&cdata.head);
272 urinst_info_get_current_hlist(&cdata.rhead, false);
274 sspt_proc_write_unlock();
280 ret = set_jump_cb((unsigned long)ri->ret_addr, regs,
281 cb_clean_child, &cdata, sizeof(cdata));
283 atomic_inc(&rm_uprobes_child_cnt);
284 ri->ret_addr = (unsigned long *)get_jump_addr();
290 static atomic_t pre_handler_cp_cnt = ATOMIC_INIT(0);
292 static unsigned long cp_cb(void *data)
294 if (atomic_read(&stop_flag))
295 call_mm_release(current);
297 atomic_dec(&pre_handler_cp_cnt);
301 static int pre_handler_cp(struct kprobe *p, struct pt_regs *regs)
305 if (is_kthread(current))
308 if (!atomic_read(&stop_flag))
311 ret = set_kjump_cb(regs, cp_cb, NULL, 0);
313 pr_err("set_kjump_cp, ret=%d\n", ret);
316 atomic_inc(&pre_handler_cp_cnt);
323 static atomic_t copy_process_cnt = ATOMIC_INIT(0);
325 static int entry_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
327 atomic_inc(©_process_cnt);
332 /* Delete uprobs in children at fork */
333 static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
335 struct task_struct *task =
336 (struct task_struct *)regs_return_value(regs);
338 if (!task || IS_ERR(task))
341 if (task->mm != current->mm) { /* check flags CLONE_VM */
342 rm_uprobes_child(ri, regs, task);
345 atomic_dec(©_process_cnt);
350 static struct kretprobe cp_kretprobe = {
351 .entry_handler = entry_handler_cp,
352 .handler = ret_handler_cp,
355 static struct kprobe cp_kprobe = {
356 .pre_handler = pre_handler_cp
359 static int register_cp(void)
364 ret = swap_register_kprobe(&cp_kprobe);
366 pr_err("swap_register_kprobe(copy_process) ret=%d!\n", ret);
368 ret = swap_register_kretprobe(&cp_kretprobe);
370 pr_err("swap_register_kretprobe(copy_process) ret=%d!\n", ret);
371 swap_unregister_kprobe(&cp_kprobe);
377 static void unregister_cp(void)
379 swap_unregister_kretprobe_top(&cp_kretprobe, 0);
382 } while (atomic_read(©_process_cnt));
383 swap_unregister_kretprobe_bottom(&cp_kretprobe);
384 swap_unregister_kprobe(&cp_kprobe);
388 } while (atomic_read(&rm_uprobes_child_cnt)
389 || atomic_read(&pre_handler_cp_cnt));
397 ******************************************************************************
399 ******************************************************************************
402 static atomic_t mm_release_cnt = ATOMIC_INIT(0);
404 static unsigned long mr_cb(void *data)
406 struct task_struct *task = *(struct task_struct **)data;
407 struct mm_struct *mm = task->mm;
410 pr_err("mm is NULL\n");
414 /* TODO: this lock for synchronizing to disarm urp */
415 down_write(&mm->mmap_sem);
416 if (task->tgid != task->pid) {
417 struct sspt_proc *proc;
418 struct hlist_head head = HLIST_HEAD_INIT;
420 if (task != current) {
421 pr_err("call mm_release in isn't current context\n");
425 /* if the thread is killed we need to discard pending
426 * uretprobe instances which have not triggered yet */
427 sspt_proc_write_lock();
428 proc = sspt_proc_get_by_task_no_lock(task);
430 urinst_info_get_current_hlist(&head, true);
432 sspt_proc_write_unlock();
435 /* disarm urp for task */
436 urinst_info_put_current_hlist(&head, task);
439 call_mm_release(task);
441 up_write(&mm->mmap_sem);
443 atomic_dec(&mm_release_cnt);
448 /* Detects when target process removes IPs. */
449 static int mr_pre_handler(struct kprobe *p, struct pt_regs *regs)
452 struct task_struct *task = (struct task_struct *)swap_get_karg(regs, 0);
454 if (is_kthread(task))
457 ret = set_kjump_cb(regs, mr_cb, (void *)&task, sizeof(task));
459 printk("##### ERROR: mr_pre_handler, ret=%d\n", ret);
462 atomic_inc(&mm_release_cnt);
469 static struct kprobe mr_kprobe = {
470 .pre_handler = mr_pre_handler
473 static int register_mr(void)
477 ret = swap_register_kprobe(&mr_kprobe);
480 "swap_register_kprobe(mm_release) ret=%d!\n", ret);
485 static void unregister_mr(void)
487 swap_unregister_kprobe(&mr_kprobe);
490 } while (atomic_read(&mm_release_cnt));
498 ******************************************************************************
500 ******************************************************************************
507 static atomic_t unmap_cnt = ATOMIC_INIT(0);
509 struct msg_unmap_data {
514 static void msg_unmap(struct sspt_filter *f, void *data)
516 if (f->pfg_is_inst) {
517 struct pfg_msg_cb *cb = pfg_msg_cb_get(f->pfg);
519 if (cb && cb->msg_unmap) {
520 struct msg_unmap_data *msg_data;
522 msg_data = (struct msg_unmap_data *)data;
523 cb->msg_unmap(msg_data->start, msg_data->end);
528 static void __remove_unmap_probes(struct sspt_proc *proc,
529 struct unmap_data *umd)
531 struct task_struct *task = proc->task;
532 unsigned long start = umd->start;
533 size_t len = PAGE_ALIGN(umd->len);
536 if (sspt_proc_get_files_by_region(proc, &head, start, len)) {
537 struct sspt_file *file, *n;
538 unsigned long end = start + len;
539 struct msg_unmap_data msg_data = {
544 list_for_each_entry_safe(file, n, &head, list) {
545 if (file->vm_start >= end)
548 if (file->vm_start >= start)
549 sspt_file_uninstall(file, task, US_UNINSTALL);
550 /* TODO: else: uninstall pages: * start..file->vm_end */
553 sspt_proc_insert_files(proc, &head);
555 sspt_proc_on_each_filter(proc, msg_unmap, (void *)&msg_data);
559 static void remove_unmap_probes(struct task_struct *task,
560 struct unmap_data *umd)
562 struct sspt_proc *proc;
564 sspt_proc_write_lock();
566 proc = sspt_proc_get_by_task_no_lock(task);
568 __remove_unmap_probes(proc, umd);
570 sspt_proc_write_unlock();
573 static int entry_handler_unmap(struct kretprobe_instance *ri,
574 struct pt_regs *regs)
576 struct unmap_data *data = (struct unmap_data *)ri->data;
577 struct task_struct *task = current->group_leader;
579 atomic_inc(&unmap_cnt);
581 data->start = swap_get_karg(regs, 1);
582 data->len = (size_t)swap_get_karg(regs, 2);
584 if (!is_kthread(task) && atomic_read(&stop_flag))
585 remove_unmap_probes(task, data);
590 static int ret_handler_unmap(struct kretprobe_instance *ri,
591 struct pt_regs *regs)
593 struct task_struct *task;
595 task = current->group_leader;
596 if (is_kthread(task) || regs_return_value(regs))
599 remove_unmap_probes(task, (struct unmap_data *)ri->data);
602 atomic_dec(&unmap_cnt);
607 static struct kretprobe unmap_kretprobe = {
608 .entry_handler = entry_handler_unmap,
609 .handler = ret_handler_unmap,
610 .data_size = sizeof(struct unmap_data)
613 static int register_unmap(void)
617 ret = swap_register_kretprobe(&unmap_kretprobe);
619 printk(KERN_INFO "swap_register_kprobe(do_munmap) ret=%d!\n",
625 static void unregister_unmap(void)
627 swap_unregister_kretprobe_top(&unmap_kretprobe, 0);
630 } while (atomic_read(&unmap_cnt));
631 swap_unregister_kretprobe_bottom(&unmap_kretprobe);
639 ******************************************************************************
641 ******************************************************************************
643 static void msg_map(struct sspt_filter *f, void *data)
645 if (f->pfg_is_inst) {
646 struct pfg_msg_cb *cb = pfg_msg_cb_get(f->pfg);
648 if (cb && cb->msg_map)
649 cb->msg_map((struct vm_area_struct *)data);
653 static int ret_handler_mmap(struct kretprobe_instance *ri,
654 struct pt_regs *regs)
656 struct sspt_proc *proc;
657 struct task_struct *task;
658 unsigned long start_addr;
659 struct vm_area_struct *vma;
661 task = current->group_leader;
662 if (is_kthread(task))
665 start_addr = regs_return_value(regs);
666 if (IS_ERR_VALUE(start_addr))
669 proc = sspt_proc_get_by_task(task);
673 vma = find_vma_intersection(task->mm, start_addr, start_addr + 1);
674 if (vma && check_vma(vma))
675 sspt_proc_on_each_filter(proc, msg_map, (void *)vma);
680 static struct kretprobe mmap_kretprobe = {
681 .handler = ret_handler_mmap
684 static int register_mmap(void)
688 ret = swap_register_kretprobe(&mmap_kretprobe);
690 printk(KERN_INFO "swap_register_kretprobe(do_mmap_pgoff) ret=%d!\n",
696 static void unregister_mmap(void)
698 swap_unregister_kretprobe(&mmap_kretprobe);
706 ******************************************************************************
708 ******************************************************************************
711 struct task_struct *task;
714 static unsigned long cb_check_and_install(void *data)
716 check_task_and_install(current);
721 static int entry_handler_comm(struct kretprobe_instance *ri,
722 struct pt_regs *regs)
724 struct comm_data *data = (struct comm_data *)ri->data;
726 data->task = (struct task_struct *)swap_get_karg(regs, 0);
731 static int ret_handler_comm(struct kretprobe_instance *ri, struct pt_regs *regs)
733 struct task_struct *task;
736 if (is_kthread(current))
739 task = ((struct comm_data *)ri->data)->task;
743 ret = set_jump_cb((unsigned long)ri->ret_addr, regs,
744 cb_check_and_install, NULL, 0);
746 ri->ret_addr = (unsigned long *)get_jump_addr();
751 static struct kretprobe comm_kretprobe = {
752 .entry_handler = entry_handler_comm,
753 .handler = ret_handler_comm,
754 .data_size = sizeof(struct comm_data)
757 static int register_comm(void)
761 ret = swap_register_kretprobe(&comm_kretprobe);
763 printk(KERN_INFO "swap_register_kretprobe(set_task_comm) ret=%d!\n",
769 static void unregister_comm(void)
771 swap_unregister_kretprobe(&comm_kretprobe);
779 * @brief Registration of helper
783 int register_helper(void)
787 atomic_set(&stop_flag, 0);
790 * install probe on 'set_task_comm' to detect when field comm struct
791 * task_struct changes
793 ret = register_comm();
797 /* install probe on 'do_munmap' to detect when for remove US probes */
798 ret = register_unmap();
802 /* install probe on 'mm_release' to detect when for remove US probes */
807 /* install probe on 'copy_process' to disarm children process */
812 /* install probe on 'do_mmap_pgoff' to detect when mapping file */
813 ret = register_mmap();
818 * install probe on 'handle_mm_fault' to detect when US pages will be
826 /* install probe to detect already running process */
827 ret = register_ctx_task();
830 #endif /* CONFIG_ARM */
837 #endif /* CONFIG_ARM */
858 * @brief Unegistration of helper bottom
862 void unregister_helper_top(void)
865 unregister_ctx_task();
866 #endif /* CONFIG_ARM */
868 atomic_set(&stop_flag, 1);
872 * @brief Unegistration of helper top
876 void unregister_helper_bottom(void)
886 * @brief Initialization of helper
890 int once_helper(void)
894 sym = "do_page_fault";
895 mf_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
896 if (mf_kretprobe.kp.addr == NULL)
899 sym = "copy_process";
900 cp_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms_substr(sym);
901 if (cp_kretprobe.kp.addr == NULL)
903 cp_kprobe.addr = cp_kretprobe.kp.addr;
906 mr_kprobe.addr = (kprobe_opcode_t *)swap_ksyms(sym);
907 if (mr_kprobe.addr == NULL)
911 unmap_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
912 if (unmap_kretprobe.kp.addr == NULL)
915 sym = "do_mmap_pgoff";
916 mmap_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
917 if (mmap_kretprobe.kp.addr == NULL)
920 sym = "set_task_comm";
921 comm_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
922 if (comm_kretprobe.kp.addr == NULL)
927 ctx_task_kprobe.addr = (kprobe_opcode_t *)swap_ksyms(sym);
928 if (ctx_task_kprobe.addr == NULL)
930 #endif /* CONFIG_ARM */
935 printk(KERN_INFO "ERROR: symbol '%s' not found\n", sym);