obj-m := swap_driver.o
swap_driver-y := error_storage.o device_driver.o ec.o legacy.o module.o probes.o \
- probes_manager.o storage.o us_proc_inst.o java_inst.o \
- sspt/ip.o sspt/sspt_page.o sspt/sspt_file.o sspt/sspt_proc.o
+ probes_manager.o storage.o us_proc_inst.o helper.o us_slot_manager.o \
- sspt/ip.o sspt/sspt_page.o sspt/sspt_file.o sspt/sspt_procs.o \
++ sspt/ip.o sspt/sspt_page.o sspt/sspt_file.o sspt/sspt_proc.o \
+ filters/filters_core.o filters/filter_by_pach.o
#include "device_driver.h" // device driver
#include "handlers_core.h"
#include <linux/notifier.h>
- #include "sspt/sspt_procs.h"
+ #include "sspt/sspt_proc.h"
-#ifdef OVERHEAD_DEBUG
-extern unsigned long swap_sum_time;
-extern unsigned long swap_sum_hit;
-#endif
-
-
-extern unsigned long imi_sum_time;
-extern unsigned long imi_sum_hit;
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
static BLOCKING_NOTIFIER_HEAD(swap_notifier_list);
--- /dev/null
- struct sspt_procs *procs;
- procs = sspt_procs_get_by_task_or_new(task);
- if (procs) {
- if (procs->first_install) {
+#include <dbi_kprobes.h>
+#include <dbi_kprobes_deps.h>
+#include <ksyms.h>
+#include "us_proc_inst.h"
+#include "us_slot_manager.h"
+#include "storage.h"
+#include "sspt/sspt.h"
+#include "filters/filters_core.h"
+
+/*
+ ******************************************************************************
+ * do_page_fault() *
+ ******************************************************************************
+ */
+
+struct pf_data {
+ unsigned long addr;
+};
+
+static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct pf_data *data = (struct pf_data *)ri->data;
+
+#ifdef CONFIG_X86
+ data->addr = read_cr2();
+#elif CONFIG_ARM
+ data->addr = regs->ARM_r0;
+#else
+#error this architecture is not supported
+#endif
+
+ return 0;
+}
+
+/* Detects when IPs are really loaded into phy mem and installs probes. */
+static int ret_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct task_struct *task = current->group_leader;
+ struct mm_struct *mm = task->mm;
+ /*
+ * Because process threads have same address space
+ * we instrument only group_leader of all this threads
+ */
+ struct pf_data *data;
+ unsigned long addr = 0;
+ int valid_addr;
+
+ if (task->flags & PF_KTHREAD) {
+ goto out;
+ }
+
+ if (!is_us_instrumentation()) {
+ goto out;
+ }
+
+ data = (struct pf_data *)ri->data;
+ addr = data->addr;
+
+ valid_addr = mm && page_present(mm, addr);
+ if (!valid_addr) {
+ goto out;
+ }
+
+ task = check_task(task);
+ if (task) {
- sspt_procs_install_page(procs, page);
++ struct sspt_proc *proc;
++ proc = sspt_proc_get_by_task_or_new(task);
++ if (proc) {
++ if (proc->first_install) {
+ unsigned long page = addr & PAGE_MASK;
- sspt_procs_install(procs);
++ sspt_proc_install_page(proc, page);
+ } else {
- static void recover_child(struct task_struct *child_task, struct sspt_procs *procs)
++ sspt_proc_install(proc);
+ }
+ }
+ }
+
+out:
+ return 0;
+}
+
+static struct kretprobe pf_kretprobe = {
+ .entry_handler = entry_handler_pf,
+ .handler = ret_handler_pf,
+ .data_size = sizeof(struct pf_data)
+};
+
+
+
+/*
+ ******************************************************************************
+ * copy_process() *
+ ******************************************************************************
+ */
+
- uninstall_us_proc_probes(child_task, procs, US_DISARM);
++static void recover_child(struct task_struct *child_task, struct sspt_proc *proc)
+{
- struct sspt_procs *procs = sspt_procs_get_by_task(current);
- if(procs) {
- recover_child(task, procs);
++ uninstall_us_proc_probes(child_task, proc, US_DISARM);
+ dbi_disarm_urp_inst_for_task(current, child_task);
+}
+
+static void rm_uprobes_child(struct task_struct *task)
+{
- struct sspt_procs *procs = NULL;
++ struct sspt_proc *proc = sspt_proc_get_by_task(current);
++ if(proc) {
++ recover_child(task, proc);
+ }
+}
+
+/* Delete uprobs in children at fork */
+static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct task_struct* task = (struct task_struct *)regs_return_value(regs);
+
+ if(!task || IS_ERR(task))
+ goto out;
+
+ if(task->mm != current->mm) /* check flags CLONE_VM */
+ rm_uprobes_child(task);
+
+out:
+ return 0;
+}
+
+static struct kretprobe cp_kretprobe = {
+ .handler = ret_handler_cp,
+};
+
+
+
+/*
+ ******************************************************************************
+ * mm_release() *
+ ******************************************************************************
+ */
+
+/* Detects when target process removes IPs. */
+static int mr_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
- procs = sspt_procs_get_by_task(task);
- if (procs) {
- int ret = uninstall_us_proc_probes(task, procs, US_UNREGS_PROBE);
++ struct sspt_proc *proc = NULL;
+ struct task_struct *task = (struct task_struct *)regs->ARM_r0; /* for ARM */
+
+ if (!is_us_instrumentation() || task->tgid != task->pid) {
+ goto out;
+ }
+
- static int remove_unmap_probes(struct task_struct *task, struct sspt_procs *procs, unsigned long start, size_t len)
++ proc = sspt_proc_get_by_task(task);
++ if (proc) {
++ int ret = uninstall_us_proc_probes(task, proc, US_UNREGS_PROBE);
+ if (ret != 0) {
+ printk("failed to uninstall IPs (%d)!\n", ret);
+ }
+
+ dbi_unregister_all_uprobes(task);
+ }
+
+out:
+ return 0;
+}
+
+static struct kprobe mr_kprobe = {
+ .pre_handler = mr_pre_handler
+};
+
+
+
+/*
+ ******************************************************************************
+ * do_munmap() *
+ ******************************************************************************
+ */
+
- file = sspt_procs_find_file(procs, dentry);
++static int remove_unmap_probes(struct task_struct *task, struct sspt_proc *proc, unsigned long start, size_t len)
+{
+ struct mm_struct *mm = task->mm;
+ struct vm_area_struct *vma;
+
+ if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) {
+ return -EINVAL;
+ }
+
+ if ((len = PAGE_ALIGN(len)) == 0) {
+ return -EINVAL;
+ }
+
+ vma = find_vma(mm, start);
+ if (vma && check_vma(vma)) {
+ struct sspt_file *file;
+ unsigned long end = start + len;
+ struct dentry *dentry = vma->vm_file->f_dentry;
+
- struct sspt_procs *procs = NULL;
++ file = sspt_proc_find_file(proc, dentry);
+ if (file) {
+ if (vma->vm_start == start || vma->vm_end == end) {
+ unregister_us_file_probes(task, file, US_UNREGS_PROBE);
+ file->loaded = 0;
+ } else {
+ unsigned long page_addr;
+ struct sspt_page *page;
+
+ for (page_addr = vma->vm_start; page_addr < vma->vm_end; page_addr += PAGE_SIZE) {
+ page = sspt_find_page_mapped(file, page_addr);
+ if (page) {
+ sspt_unregister_page(page, US_UNREGS_PROBE, task);
+ }
+ }
+
+ if (sspt_file_check_install_pages(file)) {
+ file->loaded = 0;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Detects when target removes IPs. */
+static int unmap_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ /* for ARM */
+ struct mm_struct *mm = (struct mm_struct *)regs->ARM_r0;
+ unsigned long start = regs->ARM_r1;
+ size_t len = (size_t)regs->ARM_r2;
+
- procs = sspt_procs_get_by_task(task);
- if (procs) {
- if (remove_unmap_probes(task, procs, start, len)) {
++ struct sspt_proc *proc = NULL;
+ struct task_struct *task = current;
+
+ //if user-space instrumentation is not set
+ if (!is_us_instrumentation()) {
+ goto out;
+ }
+
++ proc = sspt_proc_get_by_task(task);
++ if (proc) {
++ if (remove_unmap_probes(task, proc, start, len)) {
+ printk("ERROR do_munmap: start=%lx, len=%x\n", start, len);
+ }
+ }
+
+out:
+ return 0;
+}
+
+static struct kprobe unmap_kprobe = {
+ .pre_handler = unmap_pre_handler
+};
+
+
+
+int register_helper(void)
+{
+ int ret = 0;
+
+ /* install kprobe on 'do_munmap' to detect when for remove user space probes */
+ ret = dbi_register_kprobe(&unmap_kprobe);
+ if (ret) {
+ printk("dbi_register_kprobe(do_munmap) result=%d!\n", ret);
+ return ret;
+ }
+
+ /* install kprobe on 'mm_release' to detect when for remove user space probes */
+ ret = dbi_register_kprobe(&mr_kprobe);
+ if (ret != 0) {
+ printk("dbi_register_kprobe(mm_release) result=%d!\n", ret);
+ goto unregister_unmap;
+ }
+
+
+ /* install kretprobe on 'copy_process' */
+ ret = dbi_register_kretprobe(&cp_kretprobe);
+ if (ret) {
+ printk("dbi_register_kretprobe(copy_process) result=%d!\n", ret);
+ goto unregister_mr;
+ }
+
+ /* install kretprobe on 'do_page_fault' to detect when they will be loaded */
+ ret = dbi_register_kretprobe(&pf_kretprobe);
+ if (ret) {
+ printk("dbi_register_kretprobe(do_page_fault) result=%d!\n", ret);
+ goto unregister_cp;
+ }
+
+ return ret;
+
+unregister_cp:
+ dbi_unregister_kretprobe(&cp_kretprobe);
+
+unregister_mr:
+ dbi_unregister_kprobe(&mr_kprobe, NULL);
+
+unregister_unmap:
+ dbi_unregister_kprobe(&unmap_kprobe, NULL);
+
+ return ret;
+}
+
+void unregister_helper(void)
+{
+ /* uninstall kretprobe with 'do_page_fault' */
+ dbi_unregister_kretprobe(&pf_kretprobe);
+
+ /* uninstall kretprobe with 'copy_process' */
+ dbi_unregister_kretprobe(&cp_kretprobe);
+
+ /* uninstall kprobe with 'mm_release' */
+ dbi_unregister_kprobe(&mr_kprobe, NULL);
+
+ /* uninstall kprobe with 'do_munmap' */
+ dbi_unregister_kprobe(&unmap_kprobe, NULL);
+}
+
+int init_helper(void)
+{
+ unsigned long addr;
+ addr = swap_ksyms("do_page_fault");
+ if (addr == 0) {
+ printk("Cannot find address for page fault function!\n");
+ return -EINVAL;
+ }
+ pf_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+ addr = swap_ksyms("copy_process");
+ if (addr == 0) {
+ printk("Cannot find address for copy_process function!\n");
+ return -EINVAL;
+ }
+ cp_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+ addr = swap_ksyms("mm_release");
+ if (addr == 0) {
+ printk("Cannot find address for mm_release function!\n");
+ return -EINVAL;
+ }
+ mr_kprobe.addr = (kprobe_opcode_t *)addr;
+
+ addr = swap_ksyms("do_munmap");
+ if (addr == 0) {
+ printk("Cannot find address for do_munmap function!\n");
+ return -EINVAL;
+ }
+ unmap_kprobe.addr = (kprobe_opcode_t *)addr;
+
+ return 0;
+}
+
+void uninit_helper(void)
+{
+}
#include "ip.h"
#include "sspt_page.h"
#include "sspt_file.h"
- #include "sspt_procs.h"
+ #include "sspt_proc.h"
#include "sspt_debug.h"
#include "../us_proc_inst.h"
+#include <swap_uprobes.h>
#include "../storage.h"
-#include "../java_inst.h"
- static void print_proc_probes(const struct sspt_procs *procs);
+ static void print_proc_probes(const struct sspt_proc *proc);
- static inline struct sspt_procs *get_file_probes(const inst_us_proc_t *task_inst_info)
+ static inline struct sspt_proc *get_file_probes(const inst_us_proc_t *task_inst_info)
{
- struct sspt_procs *procs = sspt_procs_create(task_inst_info->m_f_dentry, 0);
+ struct sspt_proc *proc = sspt_proc_create(task_inst_info->m_f_dentry, 0);
printk("####### get START #######\n");
}
}
- // print_proc_probes(procs);
- add_java_inst(proc);
-
+ // print_proc_probes(proc);
printk("####### get END #######\n");
#include "sspt_file.h"
#include "sspt_page.h"
- #include "sspt_procs.h"
++#include "sspt_proc.h"
+#include <storage.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/hash.h>
if (obj) {
int i, table_size;
- obj->procs = NULL;
+ INIT_LIST_HEAD(&obj->list);
++ obj->proc = NULL;
obj->name = name;
obj->dentry = dentry;
obj->loaded = 0;
struct hlist_head *head = NULL;
int i, table_size;
INIT_LIST_HEAD(&file_out->list);
- file_out->procs = NULL;
++ file_out->proc = NULL;
file_out->dentry = file->dentry;
file_out->name = file->name;
file_out->loaded = 0;
{
spin_unlock(&page->lock);
}
- struct task_struct *task = file->procs->task;
- int app_flag = (vma->vm_file->f_dentry == file->procs->dentry);
+
+int sspt_file_check_install_pages(struct sspt_file *file)
+{
+ int i, table_size;
+ struct sspt_page *page;
+ struct hlist_node *node, *tmp;
+ struct hlist_head *head;
+
+ table_size = (1 << file->page_probes_hash_bits);
+ for (i = 0; i < table_size; ++i) {
+ head = &file->page_probes_table[i];
+ swap_hlist_for_each_entry_safe(page, node, tmp, head, hlist) {
+ if (sspt_page_is_install(page)) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void sspt_file_install(struct sspt_file *file)
+{
+ struct sspt_page *page = NULL;
+ struct hlist_node *node = NULL;
+ struct hlist_head *head = NULL;
+ int i, table_size = (1 << file->page_probes_hash_bits);
+
+ for (i = 0; i < table_size; ++i) {
+ head = &file->page_probes_table[i];
+ swap_hlist_for_each_entry_rcu(page, node, head, hlist) {
+ sspt_register_page(page, file);
+ }
+ }
+}
+
+void sspt_file_set_mapping(struct sspt_file *file, struct vm_area_struct *vma)
+{
++ struct task_struct *task = file->proc->task;
++ int app_flag = (vma->vm_file->f_dentry == file->proc->dentry);
+
+ file->vm_start = vma->vm_start;
+ file->vm_end = vma->vm_end;
+
+ pack_event_info(DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
+ task->tgid, file->name, vma->vm_start,
+ vma->vm_end - vma->vm_start, app_flag);
+}
struct sspt_file {
struct list_head list; // for proc_probes
- struct sspt_procs *procs;
++ struct sspt_proc *proc;
struct dentry *dentry;
char *name;
int loaded;
list_for_each_entry(ip, &page->ip_list, list) {
addr = file->vm_start + page->offset + ip->offset;
- ip->retprobe.kp.addr = ip->jprobe.kp.addr = (kprobe_opcode_t *)addr;
+ ip->retprobe.up.kp.addr = ip->jprobe.up.kp.addr = (kprobe_opcode_t *)addr;
+ }
+}
+
+int sspt_register_page(struct sspt_page *page, struct sspt_file *file)
+{
+ int err = 0;
+ struct us_ip *ip, *n;
+
+ spin_lock(&page->lock);
+
+ if (sspt_page_is_install(page)) {
- struct task_struct *task = page->file->procs->task;
++ struct task_struct *task = page->file->proc->task;
+
+ printk("page %lx in %s task[tgid=%u, pid=%u] already installed\n",
+ page->offset, file->dentry->d_iname, task->tgid, task->pid);
+ goto unlock;
+ }
+
+ sspt_page_assert_install(page);
+ sspt_set_all_ip_addr(page, file);
+
+ list_for_each_entry_safe(ip, n, &page->ip_list, list) {
+ err = sspt_register_usprobe(ip);
+ if (err == -ENOEXEC) {
+ list_del(&ip->list);
+ free_ip(ip);
+ continue;
+ } else if (err) {
+ printk("Failed to install probe\n");
+ }
+ }
+unlock:
+ sspt_page_installed(page);
+ spin_unlock(&page->lock);
+
+ return 0;
+}
+
+int sspt_unregister_page(struct sspt_page *page,
+ enum US_FLAGS flag,
+ struct task_struct *task)
+{
+ int err = 0;
+ struct us_ip *ip;
+
+ spin_lock(&page->lock);
+ if (!sspt_page_is_install(page)) {
+ spin_unlock(&page->lock);
+ return 0;
+ }
+
+ list_for_each_entry(ip, &page->ip_list, list) {
+ err = sspt_unregister_usprobe(task, ip, flag);
+ if (err != 0) {
+ //TODO: ERROR
+ break;
+ }
+ }
+
+ if (flag != US_DISARM) {
+ sspt_page_uninstalled(page);
}
+ spin_unlock(&page->lock);
+
+ return err;
}
*
*/
- #include "sspt_procs.h"
+ #include "sspt_proc.h"
+#include "sspt_page.h"
#include <linux/slab.h>
#include <linux/list.h>
+#include <us_slot_manager.h>
+#include <us_proc_inst.h>
+
+#define mm_read_lock(task, mm, atomic, lock) \
+ mm = atomic ? task->active_mm : get_task_mm(task); \
+ if (mm == NULL) { \
+ /* FIXME: */ \
+ panic("ERRR mm_read_lock: mm == NULL\n"); \
+ } \
+ \
+ if (atomic) { \
+ lock = down_read_trylock(&mm->mmap_sem); \
+ } else { \
+ lock = 1; \
+ down_read(&mm->mmap_sem); \
+ }
+
+#define mm_read_unlock(mm, atomic, lock) \
+ if (lock) { \
+ up_read(&mm->mmap_sem); \
+ } \
+ \
+ if (!atomic) { \
+ mmput(mm); \
+ }
-extern struct list_head proc_probes_list;
+static LIST_HEAD(proc_probes_list);
- struct sspt_procs *sspt_procs_create(struct dentry* dentry, struct task_struct *task)
-struct sspt_proc *sspt_proc_create(struct dentry* dentry, pid_t tgid)
++struct sspt_proc *sspt_proc_create(struct dentry* dentry, struct task_struct *task)
{
- struct sspt_procs *procs = kmalloc(sizeof(*procs), GFP_ATOMIC);
-
- if (procs) {
- INIT_LIST_HEAD(&procs->list);
- procs->tgid = task ? task->tgid : 0;
- procs->task = task;
- procs->dentry = dentry;
- procs->sm = NULL;
- procs->first_install = 0;
- INIT_LIST_HEAD(&procs->file_list);
+ struct sspt_proc *proc = kmalloc(sizeof(*proc), GFP_ATOMIC);
+
+ if (proc) {
+ INIT_LIST_HEAD(&proc->list);
- proc->tgid = tgid;
++ proc->tgid = task ? task->tgid : 0;
++ proc->task = task;
+ proc->dentry = dentry;
++ proc->sm = NULL;
++ proc->first_install = 0;
+ INIT_LIST_HEAD(&proc->file_list);
}
- return procs;
+ return proc;
}
- void sspt_procs_free(struct sspt_procs *procs)
+ void sspt_proc_free(struct sspt_proc *proc)
{
struct sspt_file *file, *n;
- list_for_each_entry_safe(file, n, &procs->file_list, list) {
+ list_for_each_entry_safe(file, n, &proc->file_list, list) {
list_del(&file->list);
sspt_file_free(file);
}
#include "../storage.h"
extern inst_us_proc_t us_proc_info;
- struct sspt_procs *sspt_procs_get_by_task(struct task_struct *task)
++struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
+{
- struct sspt_procs *procs, *tmp;
++ struct sspt_proc *proc, *tmp;
+
- list_for_each_entry_safe(procs, tmp, &proc_probes_list, list) {
- if (procs->tgid == task->tgid) {
- return procs;
++ list_for_each_entry_safe(proc, tmp, &proc_probes_list, list) {
++ if (proc->tgid == task->tgid) {
++ return proc;
+ }
+ }
+
+ return NULL;
+}
+
- static void add_proc_probes(struct sspt_procs *procs)
++static void add_proc_probes(struct sspt_proc *proc)
+{
- list_add_tail(&procs->list, &proc_probes_list);
++ list_add_tail(&proc->list, &proc_probes_list);
+}
+
- struct sspt_procs *sspt_procs_get_by_task_or_new(struct task_struct *task)
++struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
+{
- struct sspt_procs *procs = sspt_procs_get_by_task(task);
- if (procs == NULL) {
- procs = sspt_procs_copy(us_proc_info.pp, task);
- procs->sm = create_sm_us(task);
- add_proc_probes(procs);
++ struct sspt_proc *proc = sspt_proc_get_by_task(task);
++ if (proc == NULL) {
++ proc = sspt_proc_copy(us_proc_info.pp, task);
++ proc->sm = create_sm_us(task);
++ add_proc_probes(proc);
+ }
+
- return procs;
++ return proc;
+}
+
- void sspt_procs_free_all(void)
+ void sspt_proc_free_all(void)
{
// is user-space instrumentation
if (us_proc_info.path == NULL) {
return;
}
- struct sspt_procs *procs, *n;
- list_for_each_entry_safe(procs, n, &proc_probes_list, list) {
- list_del(&procs->list);
- sspt_procs_free(procs);
- if (strcmp(us_proc_info.path,"*") == 0) {
- // libonly
- struct sspt_proc *proc, *n;
- list_for_each_entry_safe(proc, n, &proc_probes_list, list) {
- list_del(&proc->list);
- sspt_proc_free(proc);
- }
- } else {
- // app
- sspt_proc_free(us_proc_info.pp);
- us_proc_info.pp = NULL;
++ struct sspt_proc *proc, *n;
++ list_for_each_entry_safe(proc, n, &proc_probes_list, list) {
++ list_del(&proc->list);
++ sspt_proc_free(proc);
}
}
- static void sspt_procs_add_file(struct sspt_procs *procs, struct sspt_file *file)
+ static void sspt_proc_add_file(struct sspt_proc *proc, struct sspt_file *file)
{
- list_add(&file->list, &procs->file_list);
- file->procs = procs;
+ list_add(&file->list, &proc->file_list);
++ file->proc = proc;
}
- struct sspt_file *sspt_procs_find_file_or_new(struct sspt_procs *procs,
+ struct sspt_file *sspt_proc_find_file_or_new(struct sspt_proc *proc,
struct dentry *dentry, char *name)
{
struct sspt_file *file;
sspt_file_add_ip(file, ip_d);
}
- struct sspt_procs *sspt_procs_copy(struct sspt_procs *procs, struct task_struct *task)
+ struct sspt_proc *sspt_proc_copy(struct sspt_proc *proc, struct task_struct *task)
{
struct sspt_file *file;
- struct sspt_procs *procs_out = sspt_procs_create(procs->dentry, task);
- struct sspt_proc *proc_out = sspt_proc_create(proc->dentry, task->tgid);
++ struct sspt_proc *proc_out = sspt_proc_create(proc->dentry, task);
- list_for_each_entry(file, &procs->file_list, list) {
- sspt_procs_add_file(procs_out, sspt_file_copy(file));
+ list_for_each_entry(file, &proc->file_list, list) {
+ sspt_proc_add_file(proc_out, sspt_file_copy(file));
}
- return procs_out;
+ return proc_out;
}
- struct sspt_file *sspt_procs_find_file(struct sspt_procs *procs, struct dentry *dentry)
+ struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc, struct dentry *dentry)
{
struct sspt_file *file;
return NULL;
}
- void sspt_procs_install_page(struct sspt_procs *procs, unsigned long page_addr)
+
- struct task_struct *task = procs->task;
++void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
+{
+ int lock, atomic;
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
- struct sspt_file *file = sspt_procs_find_file(procs, dentry);
++ struct task_struct *task = proc->task;
+
+ atomic = in_atomic();
+ mm_read_lock(task, mm, atomic, lock);
+
+ vma = find_vma(mm, page_addr);
+ if (vma && check_vma(vma)) {
+ struct dentry *dentry = vma->vm_file->f_dentry;
- void sspt_procs_install(struct sspt_procs *procs)
++ struct sspt_file *file = sspt_proc_find_file(proc, dentry);
+ if (file) {
+ struct sspt_page *page;
+ if (!file->loaded) {
+ sspt_file_set_mapping(file, vma);
+ file->loaded = 1;
+ }
+
+ page = sspt_find_page_mapped(file, page_addr);
+ if (page) {
+ sspt_register_page(page, file);
+ }
+ }
+ }
+
+ mm_read_unlock(mm, atomic, lock);
+}
+
- struct task_struct *task = procs->task;
++void sspt_proc_install(struct sspt_proc *proc)
+{
+ int lock, atomic;
+ struct vm_area_struct *vma;
- procs->first_install = 1;
++ struct task_struct *task = proc->task;
+ struct mm_struct *mm;
+
- struct sspt_file *file = sspt_procs_find_file(procs, dentry);
++ proc->first_install = 1;
+
+ atomic = in_atomic();
+ mm_read_lock(task, mm, atomic, lock);
+
+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
+ if (check_vma(vma)) {
+ struct dentry *dentry = vma->vm_file->f_dentry;
++ struct sspt_file *file = sspt_proc_find_file(proc, dentry);
+ if (file) {
+ if (!file->loaded) {
+ sspt_file_set_mapping(file, vma);
+ file->loaded = 1;
+ }
+
+ sspt_file_install(file);
+ }
+ }
+ }
+
+ mm_read_unlock(mm, atomic, lock);
+}
#include <linux/types.h>
#include "sspt_file.h"
- struct sspt_procs {
+struct slot_manager;
+struct task_struct;
+
+ struct sspt_proc {
struct list_head list;
pid_t tgid;
+ struct task_struct *task;
struct dentry *dentry;
+ struct slot_manager *sm;
struct list_head file_list;
+ unsigned first_install:1;
};
- struct sspt_procs *sspt_procs_create(struct dentry* dentry, struct task_struct *task);
- struct sspt_procs *sspt_procs_copy(struct sspt_procs *procs, struct task_struct *task);
- void sspt_procs_free(struct sspt_procs *procs);
-struct sspt_proc *sspt_proc_create(struct dentry* dentry, pid_t tgid);
++struct sspt_proc *sspt_proc_create(struct dentry* dentry, struct task_struct *task);
+ struct sspt_proc *sspt_proc_copy(struct sspt_proc *proc, struct task_struct *task);
+ void sspt_proc_free(struct sspt_proc *proc);
+
- struct sspt_procs *sspt_procs_get_by_task(struct task_struct *task);
- struct sspt_procs *sspt_procs_get_by_task_or_new(struct task_struct *task);
- void sspt_procs_free_all(void);
++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 sspt_proc_free_all(void);
- void sspt_procs_add_ip_data(struct sspt_procs *procs, struct dentry* dentry,
+ void sspt_proc_add_ip_data(struct sspt_proc *proc, struct dentry* dentry,
char *name, struct ip_data *ip_d);
- struct sspt_file *sspt_procs_find_file(struct sspt_procs *procs, struct dentry *dentry);
- struct sspt_file *sspt_procs_find_file_or_new(struct sspt_procs *procs,
+ struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc, struct dentry *dentry);
+ struct sspt_file *sspt_proc_find_file_or_new(struct sspt_proc *proc,
struct dentry *dentry, char *name);
- void sspt_procs_install_page(struct sspt_procs *procs, unsigned long page_addr);
- void sspt_procs_install(struct sspt_procs *procs);
++void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr);
++void sspt_proc_install(struct sspt_proc *proc);
+
#endif /* __SSPT_PROC__ */
unsigned long offset_addr = addr - vma->vm_start;
struct dentry *dentry = vma->vm_file->f_dentry;
char *name = dentry->d_iname;
- struct sspt_procs *procs = sspt_procs_get_by_task(task);
- struct sspt_proc *proc = get_proc_probes_by_task(task);
++ struct sspt_proc *proc = sspt_proc_get_by_task(task);
struct ip_data pd = {
.offset = offset_addr,
.pre_handler = pre_handler,
{
int iRet = 0, found = 0;
struct task_struct *task = NULL;
- struct sspt_procs *procs;
++ struct sspt_proc *proc;
if (!is_us_instrumentation()) {
return 0;
if (iRet)
EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
- if (is_libonly()) {
- struct sspt_proc *proc;
- for_each_process(task) {
- proc = get_proc_probes_by_task(task);
- if (proc) {
- int ret = uninstall_us_proc_probes(task, proc, US_UNREGS_PROBE);
- if (ret) {
- EPRINTF ("failed to uninstall IPs (%d)!", ret);
- }
-
- dbi_unregister_all_uprobes(task, 1);
- }
- }
- }
- else
- {
- if (us_proc_info.tgid == 0)
- return 0;
- rcu_read_lock ();
- for_each_process (task)
- {
- if (task->tgid == us_proc_info.tgid)
- {
- found = 1;
- get_task_struct (task);
- break;
- }
- }
- rcu_read_unlock ();
- if (found)
- {
- int i, ret;
- // uninstall IPs
- ret = uninstall_us_proc_probes(task, us_proc_info.pp, US_UNREGS_PROBE);
- if (ret != 0) {
- EPRINTF ("failed to uninstall IPs %d!", ret);
+ for_each_process(task) {
- procs = sspt_procs_get_by_task(task);
- if (procs) {
- int ret = uninstall_us_proc_probes(task, procs, US_UNREGS_PROBE);
++ proc = sspt_proc_get_by_task(task);
++ if (proc) {
++ int ret = uninstall_us_proc_probes(task, proc, US_UNREGS_PROBE);
+ if (ret) {
+ EPRINTF ("failed to uninstall IPs (%d)!", ret);
}
- put_task_struct (task);
-
- printk("### 1 ### dbi_unregister_all_uprobes:\n");
- dbi_unregister_all_uprobes(task, 1);
- us_proc_info.tgid = 0;
- for(i = 0; i < us_proc_info.libs_count; i++)
- us_proc_info.p_libs[i].loaded = 0;
- }
- }
-
- return iRet;
-}
-static int install_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
-{
- kernel_probe_t *probe = NULL;
- int iRet = 0;
-
- DPRINTF("us_proc_probes = 0x%x, uflag = 0x%x, "
- "probes_flags = 0x%x, kflag = 0x%x",
- us_proc_probes, uflag, probes_flags, kflag);
-
- if (!(probes_flags & kflag)) {
- iRet = add_probe_to_list (addr, &probe);
- if (iRet) {
- EPRINTF ("add_probe_to_list(0x%lx) result=%d!", addr, iRet);
- return iRet;
- }
- probes_flags |= kflag;
- }
- if (!(us_proc_probes & uflag)) {
- if (!(probes_flags & uflag)) {
- iRet = register_kernel_probe (probe);
- if (iRet) {
- EPRINTF ("register_kernel_probe(0x%lx) result=%d!", addr, iRet);
- return iRet;
- }
+ dbi_unregister_all_uprobes(task);
}
- us_proc_probes |= uflag;
}
- if (probe)
- *pprobe = probe;
+ uninit_filter();
+ unregister_filter(app_filter);
- return 0;
+ return iRet;
}
-static void install_proc_probes(struct task_struct *task, struct sspt_proc *proc, int atomic);
-
int inst_usr_space_proc (void)
{
int ret, i;
- struct task_struct *task = NULL;
+ struct task_struct *task = NULL, *ts;
- struct sspt_procs *procs;
++ struct sspt_proc *proc;
if (!is_us_instrumentation()) {
return 0;
DPRINTF("User space instr");
-#ifdef SLP_APP
- launchpad_daemon_dentry = dentry_by_path("/usr/bin/launchpad_preloading_preinitializing_daemon");
- if (launchpad_daemon_dentry == NULL) {
- return -EINVAL;
- }
-
-#endif /* SLP_APP */
-
-#ifdef ANDROID_APP
- app_process_dentry = dentry_by_path("/system/bin/app_process");
- if (app_process_dentry == NULL) {
- return -EINVAL;
- }
-
- android_app_vma_start = 0;
- android_app_vma_end = 0;
-#endif /* ANDROID_APP */
-
- for (i = 0; i < us_proc_info.libs_count; i++) {
- us_proc_info.p_libs[i].loaded = 0;
- }
- /* check whether process is already running
- * 1) if process is running - look for the libraries in the process maps
- * 1.1) check if page for symbol does exist
- * 1.1.1) if page exists - instrument it
- * 1.1.2) if page does not exist - make sure that do_page_fault handler is installed
- * 2) if process is not running - make sure that do_page_fault handler is installed
- * */
-
- if (is_libonly())
- {
- // FIXME: clear_task_inst_info();
- for_each_process (task) {
- struct sspt_proc *proc;
-
- if (task->flags & PF_KTHREAD){
- DPRINTF("ignored kernel thread %d\n",
- task->pid);
- continue;
- }
-
- proc = get_proc_probes_by_task_or_new(task);
- DPRINTF("trying process");
- install_proc_probes(task, proc, 1);
- //put_task_struct (task);
- }
- }
- else
- {
- ret = find_task_by_path (us_proc_info.path, &task, NULL);
- if ( task )
- {
- DPRINTF("task found. installing probes");
- us_proc_info.tgid = task->pid;
- install_proc_probes(task, us_proc_info.pp, 0);
- put_task_struct (task);
- }
- }
-
- // enable 'do_page_fault' probe to detect when they will be loaded
- ret = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
- if (ret != 0)
- {
- EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
- return ret;
- }
- // enable 'do_exit' probe to detect for remove task_struct
- ret = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
- if (ret != 0)
- {
- EPRINTF ("install_kernel_probe(do_exit) result=%d!", ret);
- return ret;
- }
- /* enable 'copy_process' */
- ret = install_kernel_probe (cp_addr, US_PROC_CP_INSTLD, 0, &cp_probe);
- if (ret != 0)
- {
- EPRINTF ("instpall_kernel_probe(copy_process) result=%d!", ret);
+ ret = register_filter(app_filter, get_filter_by_pach());
+ if (ret)
return ret;
- }
- // enable 'mm_release' probe to detect when for remove user space probes
- ret = install_kernel_probe (mr_addr, US_PROC_MR_INSTLD, 0, &mr_probe);
- if (ret != 0)
- {
- EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
- return ret;
- }
-
- // enable 'do_munmap' probe to detect when for remove user space probes
- ret = install_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD, 0, &unmap_probe);
- if (ret != 0)
- {
- EPRINTF ("install_kernel_probe(do_munmap) result=%d!", ret);
- return ret;
- }
- return 0;
-}
-
-#include "../../tools/gpmu/probes/entry_data.h"
-
-void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
- struct task_struct *task = current->group_leader;
-
- if (task->flags & PF_KTHREAD) {
- DPRINTF("ignored kernel thread %d\n", task->pid);
- return;
- }
+ if (strcmp(us_proc_info.path, "*")) {
+ ret = set_filter(app_filter);
+ if (ret)
+ return ret;
- if (is_us_instrumentation()) {
- // for x86 do_page_fault is do_page_fault(struct pt_regs *regs, unsigned long error_code)
- // instead of do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) for arm
-#ifdef CONFIG_X86
- unsigned long address = read_cr2();
- swap_put_entry_data((void *)address, &sa_dpf);
-#else /* CONFIG_X86 */
- swap_put_entry_data((void *)addr, &sa_dpf);
-#endif /* CONFIG_X86 */
+ ret = init_filter(us_proc_info.m_f_dentry, 0);
+ if (ret)
+ return ret;
}
-}
-EXPORT_SYMBOL_GPL(do_page_fault_j_pre_code);
-
-
-unsigned long imi_sum_time = 0;
-unsigned long imi_sum_hit = 0;
-
-static void set_mapping_file(struct sspt_file *file,
- const struct sspt_proc *proc,
- const struct task_struct *task,
- const struct vm_area_struct *vma)
-{
- int app_flag = (vma->vm_file->f_dentry == proc->dentry);
-
- file->vm_start = vma->vm_start;
- file->vm_end = vma->vm_end;
-
- pack_event_info(DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
- task->tgid, file->name, vma->vm_start,
- vma->vm_end - vma->vm_start, app_flag);
-}
-void print_vma(struct mm_struct *mm);
-
-static int register_us_page_probe(struct sspt_page *page,
- const struct sspt_file *file,
- struct task_struct *task)
-{
- int err = 0;
- struct us_ip *ip, *n;
-
- spin_lock(&page->lock);
-
- if (sspt_page_is_install(page)) {
- printk("page %lx in %s task[tgid=%u, pid=%u] already installed\n",
- page->offset, file->dentry->d_iname, task->tgid, task->pid);
- print_vma(task->mm);
- goto unlock;
+ ret = register_helper();
+ if (ret) {
+ return ret;
}
- sspt_page_assert_install(page);
- sspt_set_all_ip_addr(page, file);
+ for_each_process(task) {
+ ts = check_task(task);
- list_for_each_entry_safe(ip, n, &page->ip_list, list) {
- err = register_usprobe_my(task, ip);
- if (err == -ENOEXEC) {
- list_del(&ip->list);
- free_ip(ip);
- continue;
- } else if (err) {
- EPRINTF("Failed to install probe");
+ if (ts) {
- procs = sspt_procs_get_by_task_or_new(ts);
- sspt_procs_install(procs);
++ proc = sspt_proc_get_by_task_or_new(ts);
++ sspt_proc_install(proc);
}
}
-unlock:
- sspt_page_installed(page);
- spin_unlock(&page->lock);
return 0;
}
return err;
}
- int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag)
-static int uninstall_us_proc_probes(struct task_struct *task, struct sspt_proc *proc, enum US_FLAGS flag)
++int uninstall_us_proc_probes(struct task_struct *task, struct sspt_proc *proc, enum US_FLAGS flag)
{
int err = 0;
struct sspt_file *file;
}
ip->jprobe.priv_arg = ip;
- ip->jprobe.up.task = ip->page->file->procs->task;
- ip->jprobe.up.sm = ip->page->file->procs->sm;
- ret = dbi_register_ujprobe(task, &ip->jprobe, atomic);
++ ip->jprobe.up.task = ip->page->file->proc->task;
++ ip->jprobe.up.sm = ip->page->file->proc->sm;
+ ret = dbi_register_ujprobe(&ip->jprobe);
if (ret) {
if (ret == -ENOEXEC) {
pack_event_info(ERR_MSG_ID, RECORD_ENTRY, "dp",
}
ip->retprobe.priv_arg = ip;
- ip->retprobe.up.task = ip->page->file->procs->task;
- ip->retprobe.up.sm = ip->page->file->procs->sm;
- ret = dbi_register_uretprobe(task, &ip->retprobe, atomic);
++ ip->retprobe.up.task = ip->page->file->proc->task;
++ ip->retprobe.up.sm = ip->page->file->proc->sm;
+ ret = dbi_register_uretprobe(&ip->retprobe);
if (ret) {
EPRINTF ("dbi_register_uretprobe() failure %d", ret);
return ret;
int install_otg_ip(unsigned long addr,
kprobe_pre_entry_handler_t pre_handler,
unsigned long jp_handler,
- kretprobe_handler_t rp_handler);
+ uretprobe_handler_t rp_handler);
+
- int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag);
++int uninstall_us_proc_probes(struct task_struct *task, struct sspt_proc *proc, enum US_FLAGS flag);
+int check_vma(struct vm_area_struct *vma);
+int unregister_us_file_probes(struct task_struct *task, struct sspt_file *file, enum US_FLAGS flag);
#endif /* !defined(__US_PROC_INST_H__) */