diff options
-rw-r--r-- | driver/us_proc_inst.c | 2 | ||||
-rw-r--r-- | us_manager/Kbuild | 2 | ||||
-rw-r--r-- | us_manager/filters/filter_by_path.c | 86 | ||||
-rw-r--r-- | us_manager/filters/filter_by_path.h | 32 | ||||
-rw-r--r-- | us_manager/filters/filters_core.c | 158 | ||||
-rw-r--r-- | us_manager/filters/filters_core.h | 52 | ||||
-rw-r--r-- | us_manager/helper.c | 5 | ||||
-rw-r--r-- | us_manager/pf/proc_filters.c | 77 | ||||
-rw-r--r-- | us_manager/pf/proc_filters.h | 17 | ||||
-rw-r--r-- | us_manager/us_manager.c | 30 |
10 files changed, 111 insertions, 350 deletions
diff --git a/driver/us_proc_inst.c b/driver/us_proc_inst.c index 7b3d4647..f7e894e2 100644 --- a/driver/us_proc_inst.c +++ b/driver/us_proc_inst.c @@ -22,8 +22,6 @@ #include "../uprobe/swap_uprobes.h" #include "sspt/sspt.h" -#include "filters/filters_core.h" -#include "filters/filter_by_path.h" #include "helper.h" #include "us_slot_manager.h" diff --git a/us_manager/Kbuild b/us_manager/Kbuild index d90669b5..ebdf08d0 100644 --- a/us_manager/Kbuild +++ b/us_manager/Kbuild @@ -3,4 +3,4 @@ EXTRA_CFLAGS := $(extra_cflags) obj-m := swap_us_manager.o swap_us_manager-y := us_manager.o us_slot_manager.o helper.o \ sspt/ip.o sspt/sspt_page.o sspt/sspt_file.o sspt/sspt_proc.o \ - filters/filters_core.o filters/filter_by_path.o + pf/proc_filters.o diff --git a/us_manager/filters/filter_by_path.c b/us_manager/filters/filter_by_path.c deleted file mode 100644 index 83719866..00000000 --- a/us_manager/filters/filter_by_path.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Dynamic Binary Instrumentation Module based on KProbes - * modules/driver/filters/filter_by_path.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) Samsung Electronics, 2013 - * - * 2013 Vyacheslav Cherkashin <v.cherkashin@samsung.com> - * - */ - -#include <linux/sched.h> -#include <linux/mm_types.h> -#include <linux/fs.h> -#include <us_proc_inst.h> -#include "filters_core.h" -#include <sspt/sspt.h> - -struct dentry; -static struct dentry *dentry = NULL; - -static int check_dentry(struct task_struct *task, struct dentry *dentry) -{ - struct vm_area_struct *vma; - struct mm_struct *mm = task->mm; - - if (mm == NULL) { - return 0; - } - - for (vma = mm->mmap; vma; vma = vma->vm_next) { - if (check_vma(vma) && vma->vm_file->f_dentry == dentry) { - return 1; - } - } - - return 0; -} - -static int init_by_path(void *data, size_t size) -{ - if (dentry) { - return -EPERM; - } - - dentry = (struct dentry *)data; - - return 0; -} - -static void uninit_by_path(void) -{ - dentry = NULL; -} - -static struct task_struct *call_by_path(struct task_struct *task) -{ - if (dentry && check_dentry(task, dentry)) - return task; - - return NULL; -} - -static struct task_filter ts_filter = { - .init = init_by_path, - .uninit = uninit_by_path, - .call = call_by_path -}; - -struct task_filter *get_filter_by_path(void) -{ - return &ts_filter; -} diff --git a/us_manager/filters/filter_by_path.h b/us_manager/filters/filter_by_path.h deleted file mode 100644 index fdc7ca58..00000000 --- a/us_manager/filters/filter_by_path.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _FILTER_BY_PACH_H -#define _FILTER_BY_PACH_H - -/* - * Dynamic Binary Instrumentation Module based on KProbes - * modules/driver/filters/filter_by_path.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) Samsung Electronics, 2013 - * - * 2013 Vyacheslav Cherkashin <v.cherkashin@samsung.com> - * - */ - -struct task_filter; - -struct task_filter *get_filter_by_path(void); - -#endif /* _FILTER_BY_PACH_H */ diff --git a/us_manager/filters/filters_core.c b/us_manager/filters/filters_core.c deleted file mode 100644 index cb72cd84..00000000 --- a/us_manager/filters/filters_core.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Dynamic Binary Instrumentation Module based on KProbes - * modules/driver/filters/filters_core.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) Samsung Electronics, 2013 - * - * 2013 Vyacheslav Cherkashin <v.cherkashin@samsung.com> - * - */ - -#include "filters_core.h" -#include <linux/list.h> -#include <linux/slab.h> -#include <linux/sched.h> - -struct filter_node { - struct list_head list; - char *name; - struct task_filter *tf; -}; - -static struct task_filter *ts_filter = NULL; -static LIST_HEAD(ts_filter_list); - -static struct filter_node *create_filter_node(const char *name, struct task_filter *tf) -{ - struct filter_node *fn = kmalloc(sizeof(*fn), GFP_ATOMIC); - - if (fn) { - int len = strlen(name) + 1; - - fn->name = kmalloc(len, GFP_ATOMIC); - if (fn->name == NULL) - goto free_fn; - - memcpy(fn->name, name, len); - fn->tf = tf; - INIT_LIST_HEAD(&fn->list); - } - - return fn; - -free_fn: - kfree(fn); - return NULL; -} - -static void free_filter_node(struct filter_node *fn) -{ - kfree(fn->name); - kfree(fn); -} - -static struct task_filter *find_filter(const char *name) -{ - struct filter_node *fn, *tmp; - - list_for_each_entry_safe(fn, tmp, &ts_filter_list, list) { - if (!strcmp(fn->name, name)) { - return fn->tf; - } - } - - return NULL; -} - -int register_filter(const char *name, struct task_filter *tf) -{ - struct filter_node *fn; - - if (find_filter(name)) - return -EINVAL; - - fn = create_filter_node(name, tf); - if (!fn) - return -ENOMEM; - - list_add_tail(&fn->list, &ts_filter_list); - - return 0; -} - -void unregister_filter(const char *name) -{ - struct filter_node *fn, *tmp; - - list_for_each_entry_safe(fn, tmp, &ts_filter_list, list) { - if (!strcmp(fn->name, name)) { - struct task_filter *tf = fn->tf; - if (tf == ts_filter) { - ts_filter = NULL; - } - - list_del(&fn->list); - free_filter_node(fn); - - break; - } - } -} - -int set_filter(const char *name) -{ - if (name) { - struct task_filter *tf; - - tf = find_filter(name); - if (!tf) - return -EINVAL; - - ts_filter = tf; - } else { - ts_filter = NULL; - } - - return 0; -} - -int init_filter(void *data, size_t size) -{ - if (ts_filter) { - return ts_filter->init(data, size); - } - - return -EPERM; -} - -void uninit_filter(void) -{ - if (ts_filter) { - ts_filter->uninit(); - } -} - -struct task_struct *check_task(struct task_struct *task) -{ - if (task->flags & PF_KTHREAD) - return NULL; - - if (ts_filter) - return ts_filter->call(task); - - return task; -} diff --git a/us_manager/filters/filters_core.h b/us_manager/filters/filters_core.h deleted file mode 100644 index f2bbaa67..00000000 --- a/us_manager/filters/filters_core.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _FILTERS_CORE_H -#define _FILTERS_CORE_H - -/* - * Dynamic Binary Instrumentation Module based on KProbes - * modules/driver/filters/filters_core.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) Samsung Electronics, 2013 - * - * 2013 Vyacheslav Cherkashin <v.cherkashin@samsung.com> - * - */ - -#include <linux/types.h> - -struct task_struct; - -typedef int (*tf_init)(void *data, size_t size); -typedef void (*tf_uninit)(void); -typedef struct task_struct *(*tf_call)(struct task_struct *task); - -struct task_filter { - tf_init init; - tf_uninit uninit; - tf_call call; -}; - -int register_filter(const char *name, struct task_filter *tf); -void unregister_filter(const char *name); - - -int init_filter(void *data, size_t size); -void uninit_filter(void); - -int set_filter(const char *name); -struct task_struct *check_task(struct task_struct *task); - -#endif /* _FILTERS_CORE_H */ diff --git a/us_manager/helper.c b/us_manager/helper.c index 5073b01a..69458d8f 100644 --- a/us_manager/helper.c +++ b/us_manager/helper.c @@ -5,9 +5,12 @@ #include "us_slot_manager.h" #include "storage.h" #include "sspt/sspt.h" -#include "filters/filters_core.h" #include "helper.h" +struct task_struct; + +struct task_struct *check_task(struct task_struct *task); + /* ****************************************************************************** * do_page_fault() * diff --git a/us_manager/pf/proc_filters.c b/us_manager/pf/proc_filters.c new file mode 100644 index 00000000..29ae5077 --- /dev/null +++ b/us_manager/pf/proc_filters.c @@ -0,0 +1,77 @@ +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/mm_types.h> +#include <linux/fs.h> +#include "proc_filters.h" +#include <sspt/sspt.h> + +static int check_dentry(struct task_struct *task, struct dentry *dentry) +{ + struct vm_area_struct *vma; + struct mm_struct *mm = task->mm; + + if (mm == NULL) { + return 0; + } + + for (vma = mm->mmap; vma; vma = vma->vm_next) { + if (check_vma(vma) && vma->vm_file->f_dentry == dentry) { + return 1; + } + } + + return 0; +} + +static struct task_struct *call_by_dentry(struct proc_filter *self, + struct task_struct *task) +{ + struct dentry *dentry = (struct dentry *)self->data; + + if (!dentry || check_dentry(task, dentry)) + return task; + + return NULL; +} + +static struct task_struct *call_by_tgid(struct proc_filter *self, + struct task_struct *task) +{ + pid_t tgid = (pid_t)self->data; + + if (task->tgid == tgid) + return task; + + return NULL; +} + +static struct proc_filter *create_pf(void) +{ + struct proc_filter *pf = kmalloc(sizeof(*pf), GFP_KERNEL); + + return pf; +} + +struct proc_filter *create_pf_by_dentry(struct dentry *dentry) +{ + struct proc_filter *pf = create_pf(); + + pf->call = &call_by_dentry; + pf->data = (void *)dentry; + + return pf; +} +struct proc_filter *create_pf_by_tgid(pid_t tgid) +{ + struct proc_filter *pf = create_pf(); + + pf->call = &call_by_tgid; + pf->data = (void *)tgid; + + return pf; +} + +void free_pf(struct proc_filter *pf) +{ + kfree(pf); +} diff --git a/us_manager/pf/proc_filters.h b/us_manager/pf/proc_filters.h new file mode 100644 index 00000000..6b68ca2e --- /dev/null +++ b/us_manager/pf/proc_filters.h @@ -0,0 +1,17 @@ +#ifndef _PROC_FILTERS_H +#define _PROC_FILTERS_H + +#include <linux/types.h> + +struct task_struct; + +struct proc_filter { + struct task_struct *(*call)(struct proc_filter *self, struct task_struct *task); + void *data; +}; + +struct proc_filter *create_pf_by_dentry(struct dentry *dentry); +struct proc_filter *create_pf_by_tgid(pid_t tgid); +void free_pf(struct proc_filter *pf); + +#endif /* _PROC_FILTERS_H */ diff --git a/us_manager/us_manager.c b/us_manager/us_manager.c index 0c8f41d4..e482dd1c 100644 --- a/us_manager/us_manager.c +++ b/us_manager/us_manager.c @@ -2,11 +2,10 @@ #include <sspt/sspt.h> #include <sspt/sspt_proc.h> #include <sspt/sspt_page.h> -#include <filters/filters_core.h> -#include <filters/filter_by_path.h> #include <helper.h> +#include "pf/proc_filters.h" -static const char *app_filter = "app"; +struct proc_filter *pf; struct sspt_proc *proc_base; void (*ptr_pack_task_event_info)(struct task_struct *task, @@ -16,6 +15,14 @@ void (*ptr_pack_task_event_info)(struct task_struct *task, EXPORT_SYMBOL_GPL(ptr_pack_task_event_info); +struct task_struct *check_task(struct task_struct *task) +{ + if (is_kthread(task)) + return NULL; + + return pf->call(pf, task); +} + int usm_register_probe(struct dentry *dentry, unsigned long offset, void *pre_handler, void *jp_handler, void *rp_handler) { @@ -106,8 +113,7 @@ int usm_stop(void) rcu_read_unlock(); oops_in_progress = tmp_oops_in_progress; - uninit_filter(); - unregister_filter(app_filter); + free_pf(pf); sspt_proc_free_all(); @@ -122,19 +128,7 @@ int usm_start(void) struct sspt_proc *proc; int tmp_oops_in_progress; - ret = register_filter(app_filter, get_filter_by_path()); - if (ret) - return ret; - - if (proc_base->dentry) { - ret = set_filter(app_filter); - if (ret) - return ret; - - ret = init_filter(proc_base->dentry, 0); - if (ret) - return ret; - } + pf = create_pf_by_dentry(proc_base->dentry); ret = register_helper(); if (ret) { |