us_manager: fix sspt_proc private data creation/destruction 12/169712/9
authorAlexander Aksenov <a.aksenov@samsung.com>
Wed, 7 Feb 2018 15:09:19 +0000 (18:09 +0300)
committerAlexander Aksenov <a.aksenov@samsung.com>
Mon, 19 Feb 2018 13:32:19 +0000 (16:32 +0300)
- Add calling creation callback on each first and subsequent install;
- Redesign sspt_proc private data storing;
- Add sspt_proc destruction calling;
- Make mmap handler to be called only when proc priv data is inited.

Change-Id: I676566d013a7ebbc7851862d136c6803c4371b66
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
modules/loader/loader_pd.c
modules/us_manager/pf/pf_group.c
modules/us_manager/sspt/sspt_proc.c
modules/us_manager/sspt/sspt_proc.h
modules/us_manager/usm_hook.c

index a7b6e5430748a2811d12f8df97f84486da17da10..e27730b569fc045617dc57e70e48c189037f3906 100644 (file)
@@ -426,27 +426,17 @@ EXPORT_SYMBOL_GPL(lpd_get_parent_pd);
 
 struct pd_t *lpd_get(struct sspt_proc *proc)
 {
-       return (struct pd_t *)proc->private_data;
+       return (struct pd_t *)sspt_proc_priv_get(proc);
 }
 EXPORT_SYMBOL_GPL(lpd_get);
 
-void lpd_set(struct sspt_proc *proc, struct pd_t *pd)
-{
-       proc->private_data = pd;
-}
-EXPORT_SYMBOL_GPL(lpd_set);
-
 struct pd_t *lpd_get_by_task(struct task_struct *task)
 {
-       struct sspt_proc *proc;
+       struct sspt_proc *proc = sspt_proc_by_task(task);
        struct pd_t *pd;
 
-       proc = sspt_proc_by_task(task);
        pd = lpd_get(proc);
-       if (!pd) {
-               pd = do_create_pd(task);
-               lpd_set(proc, pd);
-       }
+       BUG_ON(!pd);
 
        return pd;
 }
index faed4acc027f99fb0c3affc324cb3621e883af84..26684ff5d31ad3b3b7683a1eeaf1e76c19c40f73 100644 (file)
@@ -611,6 +611,7 @@ void check_task_and_install(struct task_struct *task)
        case PIF_ADD_PFG:
                proc = sspt_proc_get_by_task(task);
                if (proc) {
+                       sspt_proc_priv_create(proc);
                        first_install(task, proc);
                        sspt_proc_put(proc);
                }
@@ -655,6 +656,7 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr)
        case PIF_ADD_PFG:
                proc = sspt_proc_get_by_task(task);
                if (proc) {
+                       sspt_proc_priv_create(proc);
                        first_install(task, proc);
                        sspt_proc_put(proc);
                }
@@ -663,6 +665,7 @@ void call_page_fault(struct task_struct *task, unsigned long page_addr)
        case PIF_SECOND:
                proc = sspt_proc_get_by_task(task);
                if (proc) {
+                       sspt_proc_priv_create(proc);
                        subsequent_install(task, proc, page_addr);
                        sspt_proc_put(proc);
                }
index c5d630c23923a71c9b0a7c606eda027c083d985d..c06e26ee1f9baadb0acae123ac20f7e12d2daa3f 100644 (file)
@@ -38,6 +38,9 @@
 #include <kprobe/swap_ktd.h>
 #include <us_manager/us_slot_manager.h>
 
+
+#define UNINIT_PRIV_DATA (void *)0xbadbeef
+
 static LIST_HEAD(proc_probes_list);
 static DEFINE_RWLOCK(sspt_proc_rwlock);
 
@@ -191,6 +194,9 @@ static struct sspt_proc *sspt_proc_create(struct task_struct *leader)
                mutex_init(&proc->filters.mtx);
                INIT_LIST_HEAD(&proc->filters.head);
                atomic_set(&proc->usage, 1);
+               proc->priv_data.is_init = 0;
+               mutex_init(&proc->priv_data.lock);
+               proc->priv_data.data = UNINIT_PRIV_DATA;
 
                get_task_struct(proc->leader);
 
@@ -676,13 +682,38 @@ EXPORT_SYMBOL_GPL(sspt_proc_cb_set);
 
 void sspt_proc_priv_create(struct sspt_proc *proc)
 {
-       if (proc_cb && proc_cb->priv_create)
-               proc->private_data = proc_cb->priv_create(proc);
+       if (proc->priv_data.is_init)
+               return;
+
+       mutex_lock(&proc->priv_data.lock);
+       if (!proc->priv_data.is_init) {
+               if (proc_cb && proc_cb->priv_create)
+                       proc->priv_data.data = proc_cb->priv_create(proc);
+               proc->priv_data.is_init = 1;
+       }
+       mutex_unlock(&proc->priv_data.lock);
 }
 
 void sspt_proc_priv_destroy(struct sspt_proc *proc)
 {
-       if (proc->first_install && proc_cb && proc_cb->priv_destroy)
-               proc_cb->priv_destroy(proc, proc->private_data);
-       proc->private_data = NULL;
+       mutex_lock(&proc->priv_data.lock);
+       if (proc->priv_data.is_init && proc_cb && proc_cb->priv_destroy) {
+               proc->priv_data.is_init = 0;
+               proc_cb->priv_destroy(proc, proc->priv_data.data);
+               proc->priv_data.data = UNINIT_PRIV_DATA;
+       }
+       mutex_unlock(&proc->priv_data.lock);
+}
+
+void *sspt_proc_priv_get(struct sspt_proc *proc)
+{
+       BUG_ON(proc->priv_data.data == UNINIT_PRIV_DATA);
+
+       return proc->priv_data.data;
+}
+EXPORT_SYMBOL_GPL(sspt_proc_priv_get);
+
+bool sspt_proc_priv_check(struct sspt_proc *proc)
+{
+       return proc->priv_data.data == UNINIT_PRIV_DATA ? false : true;
 }
index aaaa469b871c3392681a3bd91cfa3191a8f2d966..24162afe7384592a18358d7e4a1ac18ac99ed570 100644 (file)
@@ -77,7 +77,12 @@ struct sspt_proc {
 
        /* FIXME: for preload (remove those fields) */
        unsigned long r_state_addr;     /**< address of r_state */
-       void *private_data;             /**< Process private data */
+
+       struct {
+               unsigned is_init:1;             /**< private data init flag */
+               struct mutex lock;              /**< lock for create/destroy priv_data */
+               void *data;                     /**< Process private data */
+       } priv_data;
 };
 
 struct sspt_proc_cb {
@@ -138,6 +143,8 @@ bool sspt_proc_is_send_event(struct sspt_proc *proc);
 int sspt_proc_cb_set(struct sspt_proc_cb *cb);
 void sspt_proc_priv_create(struct sspt_proc *proc);
 void sspt_proc_priv_destroy(struct sspt_proc *proc);
+void *sspt_proc_priv_get(struct sspt_proc *proc);
+bool sspt_proc_priv_check(struct sspt_proc *proc);
 
 void sspt_change_leader(struct task_struct *prev, struct task_struct *next);
 int sspt_proc_init(void);
index c41fd947564e0f9d222f0d9c04955281050f69c7..831d42edd5b13e4c39b6be2364ca8b98dcc4ec94 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <kprobe/swap_kprobes_deps.h> // for swap_hlist_for_each_entry
 #include "usm_hook.h"
+#include "sspt/sspt_proc.h"
 
 
 static HLIST_HEAD(hook_head);
@@ -61,6 +62,9 @@ void usm_hook_mmap(struct sspt_proc *proc, struct vm_area_struct *vma)
        struct usm_hook *hook;
        DECLARE_NODE_PTR_FOR_HLIST(node);
 
+       if (!sspt_proc_priv_check(proc))
+               return;
+
        down_read(&hook_sem);
        swap_hlist_for_each_entry(hook, node, &hook_head, node) {
                if (hook->mmap)