msg_cmd.o \
features.o \
us_inst.o \
- cpu_ctrl.o
+ cpu_ctrl.o \
+ usm_msg.o
#include "us_inst.h"
#include "msg_buf.h"
#include "msg_cmd.h"
+#include "usm_msg.h"
#include "cpu_ctrl.h"
#include <driver/driver_to_msg.h>
return ret;
ret = init_cpu_deps();
+ if (ret)
+ return ret;
+
+ ret = usm_msg_once();
return ret;
}
#include "msg_parser.h"
#include "us_inst.h"
+#include "usm_msg.h"
struct pfg_item {
return 0;
}
+static struct pfg_msg_cb msg_cb = {
+ .msg_info = usm_msg_info,
+ .msg_status_info = usm_msg_status_info,
+ .msg_term = usm_msg_term,
+ .msg_map = usm_msg_map,
+ .msg_unmap = usm_msg_unmap
+};
+
static int mod_us_app_inst(struct app_inst_data *app_inst, enum MOD_TYPE mt)
{
int ret, i;
return ret;
}
+ ret = pfg_msg_cb_set(pfg, &msg_cb);
+ if (ret) {
+ put_pf_group(pfg);
+ printk(KERN_INFO "Cannot set path [%s], ret=%d\n",
+ app_inst->app_info->exec_path, ret);
+ return ret;
+ }
+
for (i = 0; i < app_inst->cnt_func; ++i) {
/* TODO: */
dentry = dentry_by_path(app_inst->app_info->exec_path);
img/img_proc.o img/img_file.o img/img_ip.o \
probes/probes.o \
probes/probe_info_new.o \
- usm_msg.o \
callbacks.o
#include <writer/kernel_operations.h>
#include "us_slot_manager.h"
#include "sspt/sspt.h"
-#include "usm_msg.h"
+#include "sspt/sspt_filter.h"
#include "helper.h"
struct task_struct;
static atomic_t unmap_cnt = ATOMIC_INIT(0);
+struct msg_unmap_data {
+ unsigned long start;
+ unsigned long end;
+};
+
+static void msg_unmap(struct sspt_filter *f, void *data)
+{
+ if (f->pfg_is_inst) {
+ struct pfg_msg_cb *cb = pfg_msg_cb_get(f->pfg);
+
+ if (cb && cb->msg_unmap) {
+ struct msg_unmap_data *msg_data;
+
+ msg_data = (struct msg_unmap_data *)data;
+ cb->msg_unmap(msg_data->start, msg_data->end);
+ }
+ }
+}
+
static void __remove_unmap_probes(struct sspt_proc *proc,
struct unmap_data *umd)
{
if (sspt_proc_get_files_by_region(proc, &head, start, len)) {
struct sspt_file *file, *n;
unsigned long end = start + len;
+ struct msg_unmap_data msg_data = {
+ .start = start,
+ .end = end
+ };
list_for_each_entry_safe(file, n, &head, list) {
if (file->vm_start >= end)
sspt_proc_insert_files(proc, &head);
- usm_msg_unmap(start, end);
+ sspt_proc_on_each_filter(proc, msg_unmap, (void *)&msg_data);
}
}
* do_mmap_pgoff() *
******************************************************************************
*/
+static void msg_map(struct sspt_filter *f, void *data)
+{
+ if (f->pfg_is_inst) {
+ struct pfg_msg_cb *cb = pfg_msg_cb_get(f->pfg);
+
+ if (cb && cb->msg_map)
+ cb->msg_map((struct vm_area_struct *)data);
+ }
+}
+
static int ret_handler_mmap(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
vma = find_vma_intersection(task->mm, start_addr, start_addr + 1);
if (vma && check_vma(vma))
- usm_msg_map(vma);
+ sspt_proc_on_each_filter(proc, msg_map, (void *)vma);
return 0;
}
#include <linux/list.h>
#include <linux/namei.h>
+#include "pf_group.h"
#include "proc_filters.h"
-#include <us_manager/usm_msg.h>
+#include "../sspt/sspt_filter.h"
#include <us_manager/img/img_proc.h>
#include <us_manager/img/img_file.h>
#include <us_manager/img/img_ip.h>
struct list_head list;
struct img_proc *i_proc;
struct proc_filter filter;
+ struct pfg_msg_cb *msg_cb;
atomic_t usage;
/* TODO: proc_list*/
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 *new_proc_by_pfg(struct pf_group *pfg,
- struct task_struct *task)
-{
- struct pl_struct *pls;
- struct sspt_proc *proc;
-
- proc = sspt_proc_get_by_task_or_new(task, pfg->filter.priv);
- img_proc_copy_to_sspt(pfg->i_proc, proc);
- sspt_proc_add_filter(proc, pfg);
-
- pls = create_pl_struct(proc);
- add_pl_struct(pfg, pls);
-
- return proc;
-}
/* struct pl_struct */
static struct pf_group *create_pfg(void)
INIT_LIST_HEAD(&pfg->list);
memset(&pfg->filter, 0, sizeof(pfg->filter));
INIT_LIST_HEAD(&pfg->proc_list);
+ pfg->msg_cb = NULL;
atomic_set(&pfg->usage, 1);
return pfg;
list_del(&pfg->list);
}
-static void first_install(struct task_struct *task, struct sspt_proc *proc,
- struct pf_group *pfg)
+
+static void msg_info(struct sspt_filter *f, void *data)
{
- struct dentry *dentry;
+ if (f->pfg_is_inst == false) {
+ struct pfg_msg_cb *cb;
+
+ f->pfg_is_inst = true;
+
+ cb = pfg_msg_cb_get(f->pfg);
+ if (cb) {
+ struct dentry *dentry;
+
+ dentry = (struct dentry *)f->pfg->filter.priv;
- dentry = (struct dentry *)get_pf_priv(&pfg->filter);
- if (dentry == NULL) {
- dentry = task->mm->exe_file ?
- task->mm->exe_file->f_dentry :
- NULL;
+ if (cb->msg_info)
+ cb->msg_info(f->proc->task, dentry);
+
+ if (cb->msg_status_info)
+ cb->msg_status_info(f->proc->task);
+ }
}
+}
+static void first_install(struct task_struct *task, struct sspt_proc *proc)
+{
down_write(&task->mm->mmap_sem);
- usm_msg_info(task, dentry);
- usm_msg_status_info(task);
+ sspt_proc_on_each_filter(proc, msg_info, NULL);
sspt_proc_install(proc);
up_write(&task->mm->mmap_sem);
}
}
EXPORT_SYMBOL_GPL(dentry_by_path);
+
+int pfg_msg_cb_set(struct pf_group *pfg, struct pfg_msg_cb *msg_cb)
+{
+ if (pfg->msg_cb)
+ return -EBUSY;
+
+ pfg->msg_cb = msg_cb;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pfg_msg_cb_set);
+
+struct pfg_msg_cb *pfg_msg_cb_get(struct pf_group *pfg)
+{
+ return pfg->msg_cb;
+}
+
/**
* @brief Get pf_group struct by dentry
*
unlock:
read_unlock(&pfg_list_lock);
+ return ret;
+}
+
+static int pfg_add_proc(struct pf_group *pfg, struct sspt_proc *proc)
+{
+ struct pl_struct *pls;
+
+ pls = create_pl_struct(proc);
+ if (pls == NULL)
+ return -ENOMEM;
+
+ add_pl_struct(pfg, pls);
+
return 0;
}
-/**
- * @brief Check task and install probes on demand
- *
- * @prarm task Pointer on the task_struct struct
- * @return Void
- */
-void check_task_and_install(struct task_struct *task)
+enum pf_inst_flag {
+ PIF_NONE,
+ PIF_FIRST,
+ PIF_SECOND,
+ PIF_ADD_PFG
+};
+
+static enum pf_inst_flag pfg_check_task(struct task_struct *task)
{
struct pf_group *pfg;
struct sspt_proc *proc = NULL;
+ enum pf_inst_flag flag = PIF_NONE;
read_lock(&pfg_list_lock);
list_for_each_entry(pfg, &pfg_list, list) {
if (check_task_f(&pfg->filter, task) == NULL)
continue;
- proc = get_proc_by_pfg(pfg, task);
+ if (proc == NULL)
+ proc = sspt_proc_get_by_task(task);
+
if (proc) {
- if (sspt_proc_is_filter_new(proc, pfg)) {
- img_proc_copy_to_sspt(pfg->i_proc, proc);
- sspt_proc_add_filter(proc, pfg);
- } else {
- printk(KERN_ERR "SWAP US_MANAGER: Error! Trying"
- " to first install filter that "
- "already exists in proc!\n");
- proc = NULL;
- goto unlock;
+ flag = flag == PIF_NONE ? PIF_SECOND : flag;
+ } else if (task->tgid == task->pid) {
+ proc = sspt_proc_get_by_task_or_new(task);
+ if (proc == NULL) {
+ printk(KERN_ERR "cannot create sspt_proc\n");
+ break;
}
- break;
+ flag = PIF_FIRST;
}
- if (task->tgid == task->pid) {
- proc = new_proc_by_pfg(pfg, task);
- break;
+ if (proc && sspt_proc_is_filter_new(proc, pfg)) {
+ img_proc_copy_to_sspt(pfg->i_proc, proc);
+ sspt_proc_add_filter(proc, pfg);
+ pfg_add_proc(pfg, proc);
+ flag = flag == PIF_FIRST ? flag : PIF_ADD_PFG;
}
}
-
-unlock:
read_unlock(&pfg_list_lock);
- if (proc)
- first_install(task, proc, pfg);
+ return flag;
}
/**
* @brief Check task and install probes on demand
*
* @prarm task Pointer on the task_struct struct
- * @param page_addr Page fault address
* @return Void
*/
-void call_page_fault(struct task_struct *task, unsigned long page_addr)
+void check_task_and_install(struct task_struct *task)
{
- struct pf_group *pfg, *pfg_first = NULL;
- struct sspt_proc *proc = NULL;
-
- read_lock(&pfg_list_lock);
- list_for_each_entry(pfg, &pfg_list, list) {
- if ((check_task_f(&pfg->filter, task) == NULL))
- continue;
-
- proc = get_proc_by_pfg(pfg, task);
- if (proc) {
- if (sspt_proc_is_filter_new(proc, pfg)) {
- img_proc_copy_to_sspt(pfg->i_proc, proc);
- sspt_proc_add_filter(proc, pfg);
- }
- break;
- }
-
- if (task->tgid == task->pid) {
- proc = new_proc_by_pfg(pfg, task);
- pfg_first = pfg;
- break;
- }
+ struct sspt_proc *proc;
+ enum pf_inst_flag flag;
+
+ flag = pfg_check_task(task);
+ switch (flag) {
+ case PIF_FIRST:
+ case PIF_ADD_PFG:
+ proc = sspt_proc_get_by_task(task);
+ first_install(task, proc);
+ break;
+
+ case PIF_NONE:
+ case PIF_SECOND:
+ break;
}
- read_unlock(&pfg_list_lock);
+}
- if (proc) {
- if (pfg_first)
- first_install(task, proc, pfg_first);
- else
- subsequent_install(task, proc, page_addr);
+/**
+ * @brief Check task and install probes on demand
+ *
+ * @prarm task Pointer on the task_struct struct
+ * @param page_addr Page fault address
+ * @return Void
+ */
+void call_page_fault(struct task_struct *task, unsigned long page_addr)
+{
+ struct sspt_proc *proc;
+ enum pf_inst_flag flag;
+
+ flag = pfg_check_task(task);
+ switch (flag) {
+ case PIF_FIRST:
+ case PIF_ADD_PFG:
+ proc = sspt_proc_get_by_task(task);
+ first_install(task, proc);
+ break;
+
+ case PIF_SECOND:
+ proc = sspt_proc_get_by_task(task);
+ subsequent_install(task, proc, page_addr);
+ break;
+
+ case PIF_NONE:
+ break;
}
}
struct sspt_proc;
struct probe_info;
+
+struct pfg_msg_cb {
+ void (*msg_info)(struct task_struct *task, struct dentry *dentry);
+ void (*msg_status_info)(struct task_struct *task);
+ void (*msg_term)(struct task_struct *task);
+ void (*msg_map)(struct vm_area_struct *vma);
+ void (*msg_unmap)(unsigned long start, unsigned long end);
+};
+
+
/* FIXME: create and use get_dentry() and put_dentry() */
struct dentry *dentry_by_path(const char *path);
struct pf_group *get_pf_group_dumb(void *priv);
void put_pf_group(struct pf_group *pfg);
+int pfg_msg_cb_set(struct pf_group *pfg, struct pfg_msg_cb *msg_cb);
+struct pfg_msg_cb *pfg_msg_cb_get(struct pf_group *pfg);
+
int pf_register_probe(struct pf_group *pfg, struct dentry *dentry,
unsigned long offset, struct probe_info *probe_i);
int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry,
#include <linux/slab.h>
#include "sspt_filter.h"
#include "sspt_proc.h"
+#include "../pf/pf_group.h"
-struct sspt_filter *sspt_filter_create(struct pf_group *pfg)
+
+struct sspt_filter *sspt_filter_create(struct sspt_proc *proc,
+ struct pf_group *pfg)
{
struct sspt_filter *fl;
return NULL;
INIT_LIST_HEAD(&fl->list);
+ list_add(&fl->list, &proc->filter_list);
+
+ fl->proc = proc;
fl->pfg = pfg;
+ fl->pfg_is_inst = false;
return fl;
}
void sspt_filter_free(struct sspt_filter *fl)
{
+ if (fl->pfg_is_inst) {
+ struct pfg_msg_cb *cb = pfg_msg_cb_get(fl->pfg);
+
+ if (cb && cb->msg_term)
+ cb->msg_term(fl->proc->task);
+ }
+
kfree(fl);
}
#ifndef __SSPT_FILTER_H__
#define __SSPT_FILTER_H__
+#include <linux/types.h>
+
struct pf_group;
+struct sspt_proc;
struct sspt_filter {
struct list_head list;
+ struct sspt_proc *proc;
struct pf_group *pfg;
+ bool pfg_is_inst;
};
-struct sspt_filter *sspt_filter_create(struct pf_group *pfg);
+struct sspt_filter *sspt_filter_create(struct sspt_proc *proc,
+ struct pf_group *pfg);
void sspt_filter_free(struct sspt_filter *fl);
#endif /* __SSPT_FILTER_H__ */
#include "sspt_page.h"
#include "sspt_feature.h"
#include "sspt_filter.h"
+#include "../pf/proc_filters.h"
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/list.h>
-#include <us_manager/usm_msg.h>
#include <us_manager/us_slot_manager.h>
* @param priv Private data
* @return Pointer to the created sspt_proc struct
*/
-struct sspt_proc *sspt_proc_create(struct task_struct *task, void *priv)
+struct sspt_proc *sspt_proc_create(struct task_struct *task)
{
struct sspt_proc *proc = kmalloc(sizeof(*proc), GFP_ATOMIC);
sspt_destroy_feature(proc->feature);
- usm_msg_term(proc->task);
free_sm_us(proc->sm);
kfree(proc);
}
* @param priv Private data
* @return Pointer on the sspt_proc struct
*/
-struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task,
- void *priv)
+struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
{
struct sspt_proc *proc = sspt_proc_get_by_task(task);
if (proc == NULL)
- proc = sspt_proc_create(task, priv);
+ proc = sspt_proc_create(task);
return proc;
}
*/
void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg)
{
- struct sspt_filter *fl;
-
- fl = sspt_filter_create(pfg);
- if (fl == NULL)
- return;
-
- list_add(&fl->list, &proc->filter_list);
+ sspt_filter_create(proc, pfg);
}
/**
* @param pfg Pointer to pf_group struct
* @return Boolean
*/
-int sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg)
+bool sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg)
{
struct sspt_filter *fl;
list_for_each_entry(fl, &proc->filter_list, list)
if (fl->pfg == pfg)
- return 0;
+ return false;
+
+ return true;
+}
- return 1;
+void sspt_proc_on_each_filter(struct sspt_proc *proc,
+ void (*func)(struct sspt_filter *, void *),
+ void *data)
+{
+ struct sspt_filter *fl;
+
+ list_for_each_entry(fl, &proc->filter_list, list)
+ func(fl, data);
}
struct slot_manager;
struct task_struct;
struct pf_group;
+struct sspt_filter;
/** Flags for sspt_*_uninstall() */
enum US_FLAGS {
};
-struct sspt_proc *sspt_proc_create(struct task_struct *task, void *priv);
+struct sspt_proc *sspt_proc_create(struct task_struct *task);
void sspt_proc_free(struct sspt_proc *proc);
void on_each_proc_no_lock(void (*func)(struct sspt_proc *, void *),
void on_each_proc(void (*func)(struct sspt_proc *, void *), void *data);
struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task);
-struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task,
- void *priv);
+struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task);
void sspt_proc_free_all(void);
struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc,
void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg);
void sspt_proc_del_filter(struct sspt_proc *proc, struct pf_group *pfg);
void sspt_proc_del_all_filters(struct sspt_proc *proc);
-int sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg);
+bool sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg);
+
+void sspt_proc_on_each_filter(struct sspt_proc *proc,
+ void (*func)(struct sspt_filter *, void *),
+ void *data);
#endif /* __SSPT_PROC__ */
#include "probes/probe_info_new.h"
#include "helper.h"
#include "us_manager.h"
-#include "usm_msg.h"
#include "debugfs_us_manager.h"
#include "callbacks.h"
#include <writer/event_filter.h>
int ret;
ret = once_helper();
- if (ret)
- return ret;
- return usm_msg_once();
+ return ret;
}
static int init_us_manager(void)