summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>2013-06-06 12:54:08 +0400
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>2013-06-06 12:54:08 +0400
commit265a988f7583a9c8846ee814a4988fb271bc62c6 (patch)
treec9de9fddc777fd31cb65e732b172a77ca551faf6
parent8111d6f8e534bc14d13fc0c14081f2be3c16698a (diff)
downloadswap-modules-265a988f7583a9c8846ee814a4988fb271bc62c6.tar.gz
swap-modules-265a988f7583a9c8846ee814a4988fb271bc62c6.tar.bz2
swap-modules-265a988f7583a9c8846ee814a4988fb271bc62c6.zip
[FEATURE] new filters
-rw-r--r--driver/us_proc_inst.c2
-rw-r--r--us_manager/Kbuild2
-rw-r--r--us_manager/filters/filter_by_path.c86
-rw-r--r--us_manager/filters/filter_by_path.h32
-rw-r--r--us_manager/filters/filters_core.c158
-rw-r--r--us_manager/filters/filters_core.h52
-rw-r--r--us_manager/helper.c5
-rw-r--r--us_manager/pf/proc_filters.c77
-rw-r--r--us_manager/pf/proc_filters.h17
-rw-r--r--us_manager/us_manager.c30
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) {