From 8ad12713900e07a4a6214657c2c50fe4563053e3 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Tue, 11 Jun 2013 17:14:35 +0400 Subject: [PATCH] [FEATURE] create call_mm_release() --- us_manager/helper.c | 9 +++++++- us_manager/pf/pf_group.c | 55 ++++++++++++++++++++++++++++++++++++--------- us_manager/pf/pf_group.h | 4 +++- us_manager/sspt/sspt.h | 7 ------ us_manager/sspt/sspt_proc.c | 18 +++++++-------- us_manager/sspt/sspt_proc.h | 5 +++++ us_manager/us_manager.c | 26 +++++++-------------- 7 files changed, 77 insertions(+), 47 deletions(-) diff --git a/us_manager/helper.c b/us_manager/helper.c index 7fbe6b0..db4bec5 100644 --- a/us_manager/helper.c +++ b/us_manager/helper.c @@ -42,7 +42,7 @@ static int ret_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs) struct task_struct *task; struct sspt_proc *proc; - install_page(((struct pf_data *)ri->data)->addr); + call_page_fault(((struct pf_data *)ri->data)->addr); return 0; /* @@ -110,6 +110,8 @@ static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs) { struct task_struct *task = (struct task_struct *)regs_return_value(regs); + return 0; + if(!task || IS_ERR(task)) goto out; @@ -160,6 +162,9 @@ static int mr_pre_handler(struct kprobe *p, struct pt_regs *regs) goto out; } + call_mm_release(task); + return 0; + proc = sspt_proc_get_by_task(task); if (proc) { int ret = sspt_proc_uninstall(proc, task, US_UNREGS_PROBE); @@ -191,6 +196,8 @@ static int remove_unmap_probes(struct task_struct *task, struct sspt_proc *proc, struct mm_struct *mm = task->mm; struct vm_area_struct *vma; + return 0; + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) { return -EINVAL; } diff --git a/us_manager/pf/pf_group.c b/us_manager/pf/pf_group.c index 8428a1b..f2606d7 100644 --- a/us_manager/pf/pf_group.c +++ b/us_manager/pf/pf_group.c @@ -24,7 +24,7 @@ struct pl_struct { struct sspt_proc *proc; }; -static LIST_HEAD(proc_list); +static LIST_HEAD(pfg_list); /* struct pl_struct */ static struct pl_struct *create_pl_struct(struct sspt_proc *proc) @@ -80,19 +80,31 @@ void copy_proc_form_img_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc) } } -static struct sspt_proc *get_proc_by_pfg(struct pf_group *pfg, - struct task_struct *task) +static struct pl_struct *find_pl_struct(struct pf_group *pfg, + struct task_struct *task) { struct pl_struct *pls; list_for_each_entry(pls, &pfg->proc_list, list) { if (pls->proc->tgid == task->tgid) - return pls->proc; + return pls; } return NULL; } +static struct sspt_proc *get_proc_by_pfg(struct pf_group *pfg, + struct task_struct *task) +{ + struct pl_struct *pls; + + pls = find_pl_struct(pfg, task); + if (pls) + return pls->proc; + + return NULL; +} + static struct sspt_proc *get_proc_by_pfg_or_new(struct pf_group *pfg, struct task_struct *task) { @@ -134,7 +146,7 @@ static void free_pfg(struct pf_group *pfg) static void add_pfg_by_list(struct pf_group *pfg) { - list_add(&pfg->list, &proc_list); + list_add(&pfg->list, &pfg_list); } static void del_pfg_by_list(struct pf_group *pfg) @@ -147,7 +159,7 @@ struct pf_group *get_pf_group_by_dentry(struct dentry *dentry) struct pf_group *pfg; struct proc_filter *filter; - list_for_each_entry(pfg, &proc_list, list) { + list_for_each_entry(pfg, &pfg_list, list) { if (check_pf_by_dentry(pfg->filter, dentry)) return pfg; } @@ -166,7 +178,7 @@ struct pf_group *get_pf_group_by_tgid(pid_t tgid) struct pf_group *pfg; struct proc_filter *filter; - list_for_each_entry(pfg, &proc_list, list) { + list_for_each_entry(pfg, &pfg_list, list) { if (check_pf_by_tgid(pfg->filter, tgid)) return pfg; } @@ -206,7 +218,7 @@ void install_all(void) void uninstall_all(void) { // struct pf_group *pfg; -// list_for_each_entry(pfg, &proc_list, list) { +// list_for_each_entry(pfg, &pfg_list, list) { // struct task_struct *task, ts; // // rcu_read_lock(); @@ -253,7 +265,7 @@ install_proc: sspt_proc_install(proc); } -void install_page(unsigned long addr) +void call_page_fault(unsigned long addr) { struct pf_group *pfg; struct task_struct *task, *ts; @@ -262,11 +274,34 @@ void install_page(unsigned long addr) if (is_kthread(task)) return; - list_for_each_entry(pfg, &proc_list, list) { + list_for_each_entry(pfg, &pfg_list, list) { install_page_by_pfg(addr, task, pfg); } } +void call_mm_release(struct task_struct *task) +{ + struct sspt_struct *proc; + struct pf_group *pfg; + struct pls_struct *pls; + + proc = sspt_proc_get_by_task(task); + if (proc == NULL) + return; + + list_for_each_entry(pfg, &pfg_list, list) { + pls = find_pl_struct(pfg, task); + if (pls == NULL) + continue; + + sspt_proc_uninstall(proc, task, US_UNREGS_PROBE); + + /* FIXME: for many filters */ + sspt_proc_free(proc); + free_pl_struct(pls); + } +} + void uninstall_page(unsigned long addr) { diff --git a/us_manager/pf/pf_group.h b/us_manager/pf/pf_group.h index 1e3c3b4..ffa37f9 100644 --- a/us_manager/pf/pf_group.h +++ b/us_manager/pf/pf_group.h @@ -19,7 +19,9 @@ int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry, void install_all(void); void uninstall_all(void); -void install_page(unsigned long addr); +void call_page_fault(unsigned long addr); +void call_mm_release(struct task_struct *task); + void uninstall_page(unsigned long addr); /* debug */ diff --git a/us_manager/sspt/sspt.h b/us_manager/sspt/sspt.h index e1de782..c8829dc 100644 --- a/us_manager/sspt/sspt.h +++ b/us_manager/sspt/sspt.h @@ -90,8 +90,6 @@ static inline struct sspt_proc *get_file_probes(inst_us_proc_t *task_inst_info) } } - usm_set_dentry(task_inst_info->m_f_dentry); - printk("####### get END #######\n"); pfg_print(pfg); @@ -106,11 +104,6 @@ static int check_vma(struct vm_area_struct *vma) !(vma->vm_flags & (VM_READ | VM_MAYREAD))); } -enum US_FLAGS { - US_UNREGS_PROBE, - US_DISARM -}; - static inline int sspt_register_usprobe(struct us_ip *ip) { int ret = 0; diff --git a/us_manager/sspt/sspt_proc.c b/us_manager/sspt/sspt_proc.c index a717aa7..2e75589 100644 --- a/us_manager/sspt/sspt_proc.c +++ b/us_manager/sspt/sspt_proc.c @@ -55,8 +55,6 @@ static LIST_HEAD(proc_probes_list); -extern struct sspt_proc *proc_base; - struct sspt_proc *sspt_proc_create(struct dentry* dentry, struct task_struct *task) { struct sspt_proc *proc = kmalloc(sizeof(*proc), GFP_ATOMIC); @@ -69,6 +67,9 @@ struct sspt_proc *sspt_proc_create(struct dentry* dentry, struct task_struct *ta proc->sm = create_sm_us(task); proc->first_install = 0; INIT_LIST_HEAD(&proc->file_list); + + /* add to list */ + list_add(&proc->list, &proc_probes_list); } return proc; @@ -77,6 +78,10 @@ struct sspt_proc *sspt_proc_create(struct dentry* dentry, struct task_struct *ta void sspt_proc_free(struct sspt_proc *proc) { struct sspt_file *file, *n; + + /* delete from list */ + list_del(&proc->list); + list_for_each_entry_safe(file, n, &proc->file_list, list) { list_del(&file->list); sspt_file_free(file); @@ -98,17 +103,11 @@ struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task) return NULL; } -static void add_proc_probes(struct sspt_proc *proc) -{ - list_add_tail(&proc->list, &proc_probes_list); -} - struct sspt_proc *sspt_proc_get_new(struct task_struct *task) { struct sspt_proc *proc; - proc = sspt_proc_copy(proc_base, task); - add_proc_probes(proc); + proc = sspt_proc_create(NULL, task); return proc; } @@ -127,7 +126,6 @@ void sspt_proc_free_all(void) { struct sspt_proc *proc, *n; list_for_each_entry_safe(proc, n, &proc_probes_list, list) { - list_del(&proc->list); sspt_proc_free(proc); } } diff --git a/us_manager/sspt/sspt_proc.h b/us_manager/sspt/sspt_proc.h index cbd151e..600d2d8 100644 --- a/us_manager/sspt/sspt_proc.h +++ b/us_manager/sspt/sspt_proc.h @@ -31,6 +31,11 @@ struct slot_manager; struct task_struct; +enum US_FLAGS { + US_UNREGS_PROBE, + US_DISARM +}; + struct sspt_proc { struct list_head list; pid_t tgid; diff --git a/us_manager/us_manager.c b/us_manager/us_manager.c index e482dd1..737437f 100644 --- a/us_manager/us_manager.c +++ b/us_manager/us_manager.c @@ -7,7 +7,6 @@ struct proc_filter *pf; -struct sspt_proc *proc_base; void (*ptr_pack_task_event_info)(struct task_struct *task, int probe_id, int record_type, @@ -26,6 +25,7 @@ struct task_struct *check_task(struct task_struct *task) int usm_register_probe(struct dentry *dentry, unsigned long offset, void *pre_handler, void *jp_handler, void *rp_handler) { +/* char *file_name; struct sspt_file *file; struct ip_data ip_d; @@ -41,6 +41,7 @@ int usm_register_probe(struct dentry *dentry, unsigned long offset, ip_d.rp_handler = rp_handler; sspt_file_add_ip(file, &ip_d); +*/ return 0; } @@ -48,6 +49,7 @@ EXPORT_SYMBOL_GPL(usm_register_probe); int usm_unregister_probe(struct dentry *dentry, unsigned long offset) { +/* struct sspt_file *file; struct sspt_page *page; struct us_ip *ip; @@ -68,19 +70,12 @@ int usm_unregister_probe(struct dentry *dentry, unsigned long offset) sspt_del_ip(ip); sspt_put_page(page); +*/ return 0; } EXPORT_SYMBOL_GPL(usm_unregister_probe); -int usm_set_dentry(struct dentry *dentry) -{ - proc_base->dentry = dentry; - - return 0; -} -EXPORT_SYMBOL_GPL(usm_set_dentry); - int usm_stop(void) { int iRet = 0, found = 0; @@ -93,7 +88,7 @@ int usm_stop(void) if (iRet) printk("uninstall_kernel_probe(do_munmap) result=%d!\n", iRet); - +/* tmp_oops_in_progress = oops_in_progress; oops_in_progress = 1; rcu_read_lock(); @@ -114,6 +109,7 @@ int usm_stop(void) oops_in_progress = tmp_oops_in_progress; free_pf(pf); +*/ sspt_proc_free_all(); @@ -128,13 +124,12 @@ int usm_start(void) struct sspt_proc *proc; int tmp_oops_in_progress; - pf = create_pf_by_dentry(proc_base->dentry); - ret = register_helper(); if (ret) { return ret; } +/* tmp_oops_in_progress = oops_in_progress; oops_in_progress = 1; rcu_read_lock(); @@ -151,7 +146,7 @@ int usm_start(void) } rcu_read_unlock(); oops_in_progress = tmp_oops_in_progress; - +*/ return 0; } EXPORT_SYMBOL_GPL(usm_start); @@ -164,16 +159,11 @@ static int __init init_us_manager(void) if (ret) return ret; - proc_base = sspt_proc_create(NULL, NULL); - if (proc_base == NULL) - return -ENOMEM; - return 0; } static void __exit exit_us_manager(void) { - sspt_proc_free(proc_base); uninit_helper(); } -- 2.7.4