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)
156 struct sspt_proc *proc;
157 unsigned long page_addr;
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)
169 return set_kjump_cb(regs, cb_check_and_install, NULL, 0);
172 static struct kprobe ctx_task_kprobe = {
173 .pre_handler = ctx_task_pre_handler,
176 static int register_ctx_task(void)
180 ret = swap_register_kprobe(&ctx_task_kprobe);
182 printk(KERN_INFO "swap_register_kprobe(workaround) ret=%d!\n",
188 static void unregister_ctx_task(void)
190 swap_unregister_kprobe(&ctx_task_kprobe);
192 #endif /* CONFIG_ARM */
199 ******************************************************************************
201 ******************************************************************************
203 static void func_uinst_creare(struct us_ip *ip, void *data)
205 struct hlist_head *head = (struct hlist_head *)data;
208 up = probe_info_get_uprobe(ip->info, ip);
210 struct uinst_info *uinst;
211 unsigned long vaddr = (unsigned long)up->kp.addr;
213 uinst = uinst_info_create(vaddr, up->kp.opcode);
215 hlist_add_head(&uinst->hlist, head);
219 static void disarm_for_task(struct task_struct *child, struct hlist_head *head)
221 struct uinst_info *uinst;
222 struct hlist_node *tmp;
223 DECLARE_NODE_PTR_FOR_HLIST(node);
225 swap_hlist_for_each_entry_safe(uinst, node, tmp, head, hlist) {
226 uinst_info_disarm(uinst, child);
227 hlist_del(&uinst->hlist);
228 uinst_info_destroy(uinst);
233 struct task_struct *task;
235 struct hlist_head head;
236 struct hlist_head rhead;
239 static atomic_t rm_uprobes_child_cnt = ATOMIC_INIT(0);
241 static unsigned long cb_clean_child(void *data)
243 struct clean_data *cdata = (struct clean_data *)data;
244 struct task_struct *child = cdata->task;
246 /* disarm up for child */
247 disarm_for_task(child, &cdata->head);
249 /* disarm urp for child */
250 urinst_info_put_current_hlist(&cdata->rhead, child);
252 atomic_dec(&rm_uprobes_child_cnt);
256 static void rm_uprobes_child(struct kretprobe_instance *ri,
257 struct pt_regs *regs, struct task_struct *child)
259 struct sspt_proc *proc;
260 struct clean_data cdata = {
262 .head = HLIST_HEAD_INIT,
263 .rhead = HLIST_HEAD_INIT
266 sspt_proc_write_lock();
267 proc = sspt_proc_get_by_task(current);
269 sspt_proc_on_each_ip(proc, func_uinst_creare, (void *)&cdata.head);
270 urinst_info_get_current_hlist(&cdata.rhead, false);
272 sspt_proc_write_unlock();
278 ret = set_jump_cb((unsigned long)ri->ret_addr, regs,
279 cb_clean_child, &cdata, sizeof(cdata));
281 atomic_inc(&rm_uprobes_child_cnt);
282 ri->ret_addr = (unsigned long *)get_jump_addr();
288 static atomic_t pre_handler_cp_cnt = ATOMIC_INIT(0);
290 static unsigned long cp_cb(void *data)
292 if (atomic_read(&stop_flag))
293 call_mm_release(current);
295 atomic_dec(&pre_handler_cp_cnt);
299 static int pre_handler_cp(struct kprobe *p, struct pt_regs *regs)
303 if (is_kthread(current))
306 if (!atomic_read(&stop_flag))
309 ret = set_kjump_cb(regs, cp_cb, NULL, 0);
311 pr_err("set_kjump_cp, ret=%d\n", ret);
314 atomic_inc(&pre_handler_cp_cnt);
321 static atomic_t copy_process_cnt = ATOMIC_INIT(0);
323 static int entry_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
325 atomic_inc(©_process_cnt);
330 /* Delete uprobs in children at fork */
331 static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
333 struct task_struct *task =
334 (struct task_struct *)regs_return_value(regs);
336 if (!task || IS_ERR(task))
339 if (task->mm != current->mm) { /* check flags CLONE_VM */
340 rm_uprobes_child(ri, regs, task);
343 atomic_dec(©_process_cnt);
348 static struct kretprobe cp_kretprobe = {
349 .entry_handler = entry_handler_cp,
350 .handler = ret_handler_cp,
353 static struct kprobe cp_kprobe = {
354 .pre_handler = pre_handler_cp
357 static int register_cp(void)
362 ret = swap_register_kprobe(&cp_kprobe);
364 pr_err("swap_register_kprobe(copy_process) ret=%d!\n", ret);
366 ret = swap_register_kretprobe(&cp_kretprobe);
368 pr_err("swap_register_kretprobe(copy_process) ret=%d!\n", ret);
369 swap_unregister_kprobe(&cp_kprobe);
375 static void unregister_cp(void)
377 swap_unregister_kretprobe_top(&cp_kretprobe, 0);
380 } while (atomic_read(©_process_cnt));
381 swap_unregister_kretprobe_bottom(&cp_kretprobe);
382 swap_unregister_kprobe(&cp_kprobe);
386 } while (atomic_read(&rm_uprobes_child_cnt)
387 || atomic_read(&pre_handler_cp_cnt));
395 ******************************************************************************
397 ******************************************************************************
400 static atomic_t mm_release_cnt = ATOMIC_INIT(0);
402 static unsigned long mr_cb(void *data)
404 struct task_struct *task = *(struct task_struct **)data;
405 struct mm_struct *mm = task->mm;
408 pr_err("mm is NULL\n");
412 /* TODO: this lock for synchronizing to disarm urp */
413 down_write(&mm->mmap_sem);
414 if (task->tgid != task->pid) {
415 struct sspt_proc *proc;
416 struct hlist_head head = HLIST_HEAD_INIT;
418 if (task != current) {
419 pr_err("call mm_release in isn't current context\n");
423 /* if the thread is killed we need to discard pending
424 * uretprobe instances which have not triggered yet */
425 sspt_proc_write_lock();
426 proc = sspt_proc_get_by_task(task);
428 urinst_info_get_current_hlist(&head, true);
430 sspt_proc_write_unlock();
433 /* disarm urp for task */
434 urinst_info_put_current_hlist(&head, task);
437 call_mm_release(task);
439 up_write(&mm->mmap_sem);
441 atomic_dec(&mm_release_cnt);
446 /* Detects when target process removes IPs. */
447 static int mr_pre_handler(struct kprobe *p, struct pt_regs *regs)
450 struct task_struct *task = (struct task_struct *)swap_get_karg(regs, 0);
452 if (is_kthread(task))
455 ret = set_kjump_cb(regs, mr_cb, (void *)&task, sizeof(task));
457 printk("##### ERROR: mr_pre_handler, ret=%d\n", ret);
459 atomic_inc(&mm_release_cnt);
466 static struct kprobe mr_kprobe = {
467 .pre_handler = mr_pre_handler
470 static int register_mr(void)
474 ret = swap_register_kprobe(&mr_kprobe);
477 "swap_register_kprobe(mm_release) ret=%d!\n", ret);
482 static void unregister_mr(void)
484 swap_unregister_kprobe(&mr_kprobe);
487 } while (atomic_read(&mm_release_cnt));
495 ******************************************************************************
497 ******************************************************************************
504 static atomic_t unmap_cnt = ATOMIC_INIT(0);
506 struct msg_unmap_data {
511 static void msg_unmap(struct sspt_filter *f, void *data)
513 if (f->pfg_is_inst) {
514 struct pfg_msg_cb *cb = pfg_msg_cb_get(f->pfg);
516 if (cb && cb->msg_unmap) {
517 struct msg_unmap_data *msg_data;
519 msg_data = (struct msg_unmap_data *)data;
520 cb->msg_unmap(msg_data->start, msg_data->end);
525 static void __remove_unmap_probes(struct sspt_proc *proc,
526 struct unmap_data *umd)
528 struct task_struct *task = proc->task;
529 unsigned long start = umd->start;
530 size_t len = PAGE_ALIGN(umd->len);
533 if (sspt_proc_get_files_by_region(proc, &head, start, len)) {
534 struct sspt_file *file, *n;
535 unsigned long end = start + len;
536 struct msg_unmap_data msg_data = {
541 list_for_each_entry_safe(file, n, &head, list) {
542 if (file->vm_start >= end)
545 if (file->vm_start >= start)
546 sspt_file_uninstall(file, task, US_UNINSTALL);
547 /* TODO: else: uninstall pages: * start..file->vm_end */
550 sspt_proc_insert_files(proc, &head);
552 sspt_proc_on_each_filter(proc, msg_unmap, (void *)&msg_data);
556 static void remove_unmap_probes(struct task_struct *task,
557 struct unmap_data *umd)
559 struct sspt_proc *proc;
561 sspt_proc_write_lock();
563 proc = sspt_proc_get_by_task(task);
565 __remove_unmap_probes(proc, umd);
567 sspt_proc_write_unlock();
570 static int entry_handler_unmap(struct kretprobe_instance *ri,
571 struct pt_regs *regs)
573 struct unmap_data *data = (struct unmap_data *)ri->data;
574 struct task_struct *task = current->group_leader;
576 atomic_inc(&unmap_cnt);
578 data->start = swap_get_karg(regs, 1);
579 data->len = (size_t)swap_get_karg(regs, 2);
581 if (!is_kthread(task) && atomic_read(&stop_flag))
582 remove_unmap_probes(task, data);
587 static int ret_handler_unmap(struct kretprobe_instance *ri,
588 struct pt_regs *regs)
590 struct task_struct *task;
592 task = current->group_leader;
593 if (is_kthread(task) || regs_return_value(regs))
596 remove_unmap_probes(task, (struct unmap_data *)ri->data);
599 atomic_dec(&unmap_cnt);
604 static struct kretprobe unmap_kretprobe = {
605 .entry_handler = entry_handler_unmap,
606 .handler = ret_handler_unmap,
607 .data_size = sizeof(struct unmap_data)
610 static int register_unmap(void)
614 ret = swap_register_kretprobe(&unmap_kretprobe);
616 printk(KERN_INFO "swap_register_kprobe(do_munmap) ret=%d!\n",
622 static void unregister_unmap(void)
624 swap_unregister_kretprobe_top(&unmap_kretprobe, 0);
627 } while (atomic_read(&unmap_cnt));
628 swap_unregister_kretprobe_bottom(&unmap_kretprobe);
636 ******************************************************************************
638 ******************************************************************************
640 static void msg_map(struct sspt_filter *f, void *data)
642 if (f->pfg_is_inst) {
643 struct pfg_msg_cb *cb = pfg_msg_cb_get(f->pfg);
645 if (cb && cb->msg_map)
646 cb->msg_map((struct vm_area_struct *)data);
650 static int ret_handler_mmap(struct kretprobe_instance *ri,
651 struct pt_regs *regs)
653 struct sspt_proc *proc;
654 struct task_struct *task;
655 unsigned long start_addr;
656 struct vm_area_struct *vma;
658 task = current->group_leader;
659 if (is_kthread(task))
662 start_addr = regs_return_value(regs);
663 if (IS_ERR_VALUE(start_addr))
666 proc = sspt_proc_get_by_task(task);
670 vma = find_vma_intersection(task->mm, start_addr, start_addr + 1);
671 if (vma && check_vma(vma))
672 sspt_proc_on_each_filter(proc, msg_map, (void *)vma);
677 static struct kretprobe mmap_kretprobe = {
678 .handler = ret_handler_mmap
681 static int register_mmap(void)
685 ret = swap_register_kretprobe(&mmap_kretprobe);
687 printk(KERN_INFO "swap_register_kretprobe(do_mmap_pgoff) ret=%d!\n",
693 static void unregister_mmap(void)
695 swap_unregister_kretprobe(&mmap_kretprobe);
703 ******************************************************************************
705 ******************************************************************************
708 struct task_struct *task;
711 static unsigned long cb_check_and_install(void *data)
713 check_task_and_install(current);
718 static int entry_handler_comm(struct kretprobe_instance *ri,
719 struct pt_regs *regs)
721 struct comm_data *data = (struct comm_data *)ri->data;
723 data->task = (struct task_struct *)swap_get_karg(regs, 0);
728 static int ret_handler_comm(struct kretprobe_instance *ri, struct pt_regs *regs)
730 struct task_struct *task;
733 if (is_kthread(current))
736 task = ((struct comm_data *)ri->data)->task;
740 ret = set_jump_cb((unsigned long)ri->ret_addr, regs,
741 cb_check_and_install, NULL, 0);
743 ri->ret_addr = (unsigned long *)get_jump_addr();
748 static struct kretprobe comm_kretprobe = {
749 .entry_handler = entry_handler_comm,
750 .handler = ret_handler_comm,
751 .data_size = sizeof(struct comm_data)
754 static int register_comm(void)
758 ret = swap_register_kretprobe(&comm_kretprobe);
760 printk(KERN_INFO "swap_register_kretprobe(set_task_comm) ret=%d!\n",
766 static void unregister_comm(void)
768 swap_unregister_kretprobe(&comm_kretprobe);
776 * @brief Registration of helper
780 int register_helper(void)
784 atomic_set(&stop_flag, 0);
787 * install probe on 'set_task_comm' to detect when field comm struct
788 * task_struct changes
790 ret = register_comm();
794 /* install probe on 'do_munmap' to detect when for remove US probes */
795 ret = register_unmap();
799 /* install probe on 'mm_release' to detect when for remove US probes */
804 /* install probe on 'copy_process' to disarm children process */
809 /* install probe on 'do_mmap_pgoff' to detect when mapping file */
810 ret = register_mmap();
815 * install probe on 'handle_mm_fault' to detect when US pages will be
823 /* install probe to detect already running process */
824 ret = register_ctx_task();
827 #endif /* CONFIG_ARM */
834 #endif /* CONFIG_ARM */
855 * @brief Unegistration of helper bottom
859 void unregister_helper_top(void)
862 unregister_ctx_task();
863 #endif /* CONFIG_ARM */
865 atomic_set(&stop_flag, 1);
869 * @brief Unegistration of helper top
873 void unregister_helper_bottom(void)
883 * @brief Initialization of helper
887 int once_helper(void)
891 sym = "do_page_fault";
892 mf_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
893 if (mf_kretprobe.kp.addr == NULL)
896 sym = "copy_process";
897 cp_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms_substr(sym);
898 if (cp_kretprobe.kp.addr == NULL)
900 cp_kprobe.addr = cp_kretprobe.kp.addr;
903 mr_kprobe.addr = (kprobe_opcode_t *)swap_ksyms(sym);
904 if (mr_kprobe.addr == NULL)
908 unmap_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
909 if (unmap_kretprobe.kp.addr == NULL)
912 sym = "do_mmap_pgoff";
913 mmap_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
914 if (mmap_kretprobe.kp.addr == NULL)
917 sym = "set_task_comm";
918 comm_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
919 if (comm_kretprobe.kp.addr == NULL)
924 ctx_task_kprobe.addr = (kprobe_opcode_t *)swap_ksyms(sym);
925 if (ctx_task_kprobe.addr == NULL)
927 #endif /* CONFIG_ARM */
932 printk(KERN_INFO "ERROR: symbol '%s' not found\n", sym);