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_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);
147 ******************************************************************************
149 ******************************************************************************
151 static void disarm_ip(struct sspt_ip *ip, void *data)
153 struct task_struct *child = (struct task_struct *)data;
156 up = probe_info_get_uprobe(ip->desc->type, ip);
158 disarm_uprobe(up, child);
161 static atomic_t rm_uprobes_child_cnt = ATOMIC_INIT(0);
163 static unsigned long cb_clean_child(void *data)
165 struct task_struct *parent = current;
166 struct sspt_proc *proc;
168 proc = sspt_proc_by_task(parent);
170 struct task_struct *child = *(struct task_struct **)data;
172 /* disarm up for child */
173 sspt_proc_on_each_ip(proc, disarm_ip, (void *)child);
175 /* disarm urp for child */
176 swap_uretprobe_free_task(parent, child, false);
179 atomic_dec(&rm_uprobes_child_cnt);
182 static void rm_uprobes_child(struct kretprobe_instance *ri,
183 struct pt_regs *regs, struct task_struct *child)
187 if (!sspt_proc_by_task(current))
191 ret = set_jump_cb((unsigned long)ri->ret_addr, regs,
192 cb_clean_child, &child, sizeof(child));
194 atomic_inc(&rm_uprobes_child_cnt);
195 ri->ret_addr = (unsigned long *)get_jump_addr();
202 static atomic_t pre_handler_cp_cnt = ATOMIC_INIT(0);
204 static unsigned long cp_cb(void *data)
206 if (atomic_read(&stop_flag))
207 call_mm_release(current);
209 atomic_dec(&pre_handler_cp_cnt);
213 static int pre_handler_cp(struct kprobe *p, struct pt_regs *regs)
217 if (is_kthread(current))
220 if (!atomic_read(&stop_flag))
223 ret = set_kjump_cb(regs, cp_cb, NULL, 0);
225 pr_err("set_kjump_cp, ret=%d\n", ret);
228 atomic_inc(&pre_handler_cp_cnt);
235 static atomic_t copy_process_cnt = ATOMIC_INIT(0);
237 static int entry_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
239 atomic_inc(©_process_cnt);
244 /* Delete uprobs in children at fork */
245 static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
247 struct task_struct *task =
248 (struct task_struct *)regs_return_value(regs);
250 if (!task || IS_ERR(task))
253 if (task->mm != current->mm) { /* check flags CLONE_VM */
254 rm_uprobes_child(ri, regs, task);
257 atomic_dec(©_process_cnt);
262 static struct kretprobe cp_kretprobe = {
263 .entry_handler = entry_handler_cp,
264 .handler = ret_handler_cp,
267 static struct kprobe cp_kprobe = {
268 .pre_handler = pre_handler_cp
271 static int register_cp(void)
276 ret = swap_register_kprobe(&cp_kprobe);
278 pr_err("swap_register_kprobe(copy_process) ret=%d!\n", ret);
280 ret = swap_register_kretprobe(&cp_kretprobe);
282 pr_err("swap_register_kretprobe(copy_process) ret=%d!\n", ret);
283 swap_unregister_kprobe(&cp_kprobe);
289 static void unregister_cp(void)
291 swap_unregister_kretprobe_top(&cp_kretprobe, 0);
294 } while (atomic_read(©_process_cnt));
295 swap_unregister_kretprobe_bottom(&cp_kretprobe);
296 swap_unregister_kprobe(&cp_kprobe);
300 } while (atomic_read(&rm_uprobes_child_cnt)
301 || atomic_read(&pre_handler_cp_cnt));
309 ******************************************************************************
311 ******************************************************************************
314 static atomic_t mm_release_cnt = ATOMIC_INIT(0);
316 static unsigned long mr_cb(void *data)
318 struct task_struct *task = *(struct task_struct **)data;
319 struct mm_struct *mm = task->mm;
322 pr_err("mm is NULL\n");
326 /* TODO: this lock for synchronizing to disarm urp */
327 down_write(&mm->mmap_sem);
328 if (task != task->group_leader) {
329 struct sspt_proc *proc;
331 if (task != current) {
332 pr_err("call mm_release in isn't current context\n");
336 /* if the thread is killed we need to discard pending
337 * uretprobe instances which have not triggered yet */
338 proc = sspt_proc_by_task(task);
340 swap_uretprobe_free_task(task, task, true);
342 call_mm_release(task);
344 up_write(&mm->mmap_sem);
346 atomic_dec(&mm_release_cnt);
351 /* Detects when target process removes IPs. */
352 static int mr_pre_handler(struct kprobe *p, struct pt_regs *regs)
355 struct task_struct *task = (struct task_struct *)swap_get_karg(regs, 0);
357 if (is_kthread(task))
360 ret = set_kjump_cb(regs, mr_cb, (void *)&task, sizeof(task));
362 printk("##### ERROR: mr_pre_handler, ret=%d\n", ret);
365 atomic_inc(&mm_release_cnt);
372 static struct kprobe mr_kprobe = {
373 .pre_handler = mr_pre_handler
376 static int register_mr(void)
380 ret = swap_register_kprobe(&mr_kprobe);
383 "swap_register_kprobe(mm_release) ret=%d!\n", ret);
388 static void unregister_mr(void)
390 swap_unregister_kprobe(&mr_kprobe);
393 } while (atomic_read(&mm_release_cnt));
401 ******************************************************************************
403 ******************************************************************************
410 static atomic_t unmap_cnt = ATOMIC_INIT(0);
412 struct msg_unmap_data {
417 static void msg_unmap(struct sspt_filter *f, void *data)
419 if (f->pfg_is_inst) {
420 struct pfg_msg_cb *cb = pfg_msg_cb_get(f->pfg);
422 if (cb && cb->msg_unmap) {
423 struct msg_unmap_data *msg_data;
425 msg_data = (struct msg_unmap_data *)data;
426 cb->msg_unmap(msg_data->start, msg_data->end);
431 static void __remove_unmap_probes(struct sspt_proc *proc,
432 struct unmap_data *umd)
434 unsigned long start = umd->start;
435 size_t len = umd->len;
438 if (sspt_proc_get_files_by_region(proc, &head, start, len)) {
439 struct sspt_file *file, *n;
440 unsigned long end = start + len;
441 struct task_struct *task = proc->leader;
443 list_for_each_entry_safe(file, n, &head, list) {
444 if (file->vm_start >= end)
447 if (file->vm_start >= start)
448 sspt_file_uninstall(file, task, US_UNINSTALL);
449 /* TODO: else: uninstall pages: * start..file->vm_end */
452 sspt_proc_insert_files(proc, &head);
456 static void remove_unmap_probes(struct task_struct *task,
457 struct unmap_data *umd)
459 struct sspt_proc *proc;
461 sspt_proc_write_lock();
463 proc = sspt_proc_by_task(task);
465 struct msg_unmap_data msg_data = {
467 .end = umd->start + umd->len,
470 __remove_unmap_probes(proc, umd);
472 /* send unmap region */
473 sspt_proc_on_each_filter(proc, msg_unmap, (void *)&msg_data);
476 sspt_proc_write_unlock();
479 static int entry_handler_unmap(struct kretprobe_instance *ri,
480 struct pt_regs *regs)
482 struct unmap_data *data = (struct unmap_data *)ri->data;
483 struct task_struct *task = current->group_leader;
485 atomic_inc(&unmap_cnt);
487 data->start = swap_get_karg(regs, 1);
488 data->len = (size_t)PAGE_ALIGN(swap_get_karg(regs, 2));
490 if (!is_kthread(task) && atomic_read(&stop_flag))
491 remove_unmap_probes(task, data);
496 static int ret_handler_unmap(struct kretprobe_instance *ri,
497 struct pt_regs *regs)
499 struct task_struct *task;
501 task = current->group_leader;
502 if (is_kthread(task) || regs_return_value(regs))
505 remove_unmap_probes(task, (struct unmap_data *)ri->data);
508 atomic_dec(&unmap_cnt);
513 static struct kretprobe unmap_kretprobe = {
514 .entry_handler = entry_handler_unmap,
515 .handler = ret_handler_unmap,
516 .data_size = sizeof(struct unmap_data)
519 static int register_unmap(void)
523 ret = swap_register_kretprobe(&unmap_kretprobe);
525 printk(KERN_INFO "swap_register_kprobe(do_munmap) ret=%d!\n",
531 static void unregister_unmap(void)
533 swap_unregister_kretprobe_top(&unmap_kretprobe, 0);
536 } while (atomic_read(&unmap_cnt));
537 swap_unregister_kretprobe_bottom(&unmap_kretprobe);
545 ******************************************************************************
547 ******************************************************************************
549 static void msg_map(struct sspt_filter *f, void *data)
551 if (f->pfg_is_inst) {
552 struct pfg_msg_cb *cb = pfg_msg_cb_get(f->pfg);
554 if (cb && cb->msg_map)
555 cb->msg_map((struct vm_area_struct *)data);
559 static int ret_handler_mmap(struct kretprobe_instance *ri,
560 struct pt_regs *regs)
562 struct sspt_proc *proc;
563 struct task_struct *task;
564 unsigned long start_addr;
565 struct vm_area_struct *vma;
567 task = current->group_leader;
568 if (is_kthread(task))
571 start_addr = regs_return_value(regs);
572 if (IS_ERR_VALUE(start_addr))
575 proc = sspt_proc_by_task(task);
579 vma = find_vma_intersection(task->mm, start_addr, start_addr + 1);
580 if (vma && check_vma(vma))
581 sspt_proc_on_each_filter(proc, msg_map, (void *)vma);
586 static struct kretprobe mmap_kretprobe = {
587 .handler = ret_handler_mmap
590 static int register_mmap(void)
594 ret = swap_register_kretprobe(&mmap_kretprobe);
596 printk(KERN_INFO "swap_register_kretprobe(do_mmap_pgoff) ret=%d!\n",
602 static void unregister_mmap(void)
604 swap_unregister_kretprobe(&mmap_kretprobe);
612 ******************************************************************************
614 ******************************************************************************
617 struct task_struct *task;
620 static unsigned long cb_check_and_install(void *data)
622 check_task_and_install(current);
627 static int entry_handler_comm(struct kretprobe_instance *ri,
628 struct pt_regs *regs)
630 struct comm_data *data = (struct comm_data *)ri->data;
632 data->task = (struct task_struct *)swap_get_karg(regs, 0);
637 static int ret_handler_comm(struct kretprobe_instance *ri, struct pt_regs *regs)
639 struct task_struct *task;
642 if (is_kthread(current))
645 task = ((struct comm_data *)ri->data)->task;
649 ret = set_jump_cb((unsigned long)ri->ret_addr, regs,
650 cb_check_and_install, NULL, 0);
652 ri->ret_addr = (unsigned long *)get_jump_addr();
657 static struct kretprobe comm_kretprobe = {
658 .entry_handler = entry_handler_comm,
659 .handler = ret_handler_comm,
660 .data_size = sizeof(struct comm_data)
663 static int register_comm(void)
667 ret = swap_register_kretprobe(&comm_kretprobe);
669 printk(KERN_INFO "swap_register_kretprobe(set_task_comm) ret=%d!\n",
675 static void unregister_comm(void)
677 swap_unregister_kretprobe(&comm_kretprobe);
684 ******************************************************************************
686 ******************************************************************************
688 static int release_task_h(struct kprobe *p, struct pt_regs *regs)
690 struct task_struct *task = (struct task_struct *)swap_get_karg(regs, 0);
691 struct task_struct *cur = current;
693 if (cur->flags & PF_KTHREAD)
696 /* EXEC: change group leader */
697 if (cur != task && task->pid == cur->pid)
698 sspt_change_leader(task, cur);
703 struct kprobe release_task_kp = {
704 .pre_handler = release_task_h,
707 static int reg_release_task(void)
709 return swap_register_kprobe(&release_task_kp);
712 static void unreg_release_task(void)
714 swap_unregister_kprobe(&release_task_kp);
722 * @brief Registration of helper
726 int register_helper(void)
730 atomic_set(&stop_flag, 0);
732 /* tracking group leader changing */
733 ret = reg_release_task();
738 * install probe on 'set_task_comm' to detect when field comm struct
739 * task_struct changes
741 ret = register_comm();
745 /* install probe on 'do_munmap' to detect when for remove US probes */
746 ret = register_unmap();
750 /* install probe on 'mm_release' to detect when for remove US probes */
755 /* install probe on 'copy_process' to disarm children process */
760 /* install probe on 'do_mmap_pgoff' to detect when mapping file */
761 ret = register_mmap();
766 * install probe on 'handle_mm_fault' to detect when US pages will be
791 unreg_release_task();
797 * @brief Unegistration of helper bottom
801 void unregister_helper_top(void)
804 atomic_set(&stop_flag, 1);
808 * @brief Unegistration of helper top
812 void unregister_helper_bottom(void)
819 unreg_release_task();
823 * @brief Initialization of helper
827 int once_helper(void)
831 sym = "do_page_fault";
832 mf_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
833 if (mf_kretprobe.kp.addr == NULL)
836 sym = "copy_process";
837 cp_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms_substr(sym);
838 if (cp_kretprobe.kp.addr == NULL)
840 cp_kprobe.addr = cp_kretprobe.kp.addr;
843 mr_kprobe.addr = (kprobe_opcode_t *)swap_ksyms(sym);
844 if (mr_kprobe.addr == NULL)
848 unmap_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
849 if (unmap_kretprobe.kp.addr == NULL)
852 sym = "do_mmap_pgoff";
853 mmap_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
854 if (mmap_kretprobe.kp.addr == NULL)
857 sym = "set_task_comm";
858 comm_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
859 if (comm_kretprobe.kp.addr == NULL)
862 sym = "release_task";
863 release_task_kp.addr = (kprobe_opcode_t *)swap_ksyms(sym);
864 if (release_task_kp.addr == NULL)
870 printk(KERN_INFO "ERROR: symbol '%s' not found\n", sym);