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 helper.o us_slot_manager.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 us_def_handler.o \
+ probes_manager.o storage.o us_proc_inst.o \
+ us_def_handler.o \
ks_def_handler.o
-I$(realpath $(top_srcdir)/src/modules/ks_manager) \
-I$(realpath $(top_srcdir)/src/modules/kprobe) \
-I$(realpath $(top_srcdir)/src/modules/kprobe/arch) \
- -I$(realpath $(top_srcdir)/src/modules/uprobe)
+ -I$(realpath $(top_srcdir)/src/modules/uprobe) \
+ -I$(realpath $(top_srcdir)/src/modules/us_manager)
extra_cflags = "$(inlude_opt) -DEC_ARCH_$(ARCH) -D__DEBUG $(memchecker) $(debug_opt) $(android_opt) $(slp_opt) $(android_app_opt) $(board_opt)"
#bin_SCRIPTS = patchko.sh insmod.sh
#include "device_driver.h" // device driver
#include "handlers_core.h"
#include <linux/notifier.h>
-#include "sspt/sspt_proc.h"
+#include <sspt/sspt_proc.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
goto sad_cleanup;
}
- sspt_proc_free_all();
-
vfree(bundle);
result = 0;
DPRINTF("Stop and Detach Probes");
#include "module.h"
#include "ec.h"
+#include <us_manager.h>
////////////////////////////////////////////////////////////////////////////////////////////
pack_event_info(EVENT_FMT_PROBE_ID, RECORD_ENTRY, "x", tmp);
event_mask = tmp;
- result = inst_usr_space_proc();
+ result = usm_start();
if (result == 0) // instrument user space process
result = set_kernel_probes();
// FIXME: SAFETY CHECK
pack_event_info(EVENT_FMT_PROBE_ID, RECORD_ENTRY, "x", tmp);
event_mask = tmp;
- result = inst_usr_space_proc();
+ result = usm_start();
if (result == 0) // instrument user space process
result = set_kernel_probes();
ec_info.ec_state = EC_STATE_IDLE;
spin_unlock_irqrestore (&ec_spinlock, spinlock_flags); // open our data for other CPUs
- ret = deinst_usr_space_proc ();
+ ret = usm_stop();
result = unset_kernel_probes();
if (result == 0)
result = ret;
spin_lock_init(&ec_spinlock);
#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
- ret = init_helper();
- if (ret)
- return ret;
-
return storage_init();
}
static void probes_manager_down(void)
{
unset_kernel_probes();
- uninit_helper();
storage_down();
}
#ifndef regs_return_value
/* "regs_return_value" is ARCH-dependent. ARCH is passed via "EC_ARCH_*" */
-#if defined(EC_ARCH_arm) /* ARCH == arm */
+#if defined(CONFIG_ARM)
#define regs_return_value(regs) ((regs)->ARM_r0)
-#elif defined(EC_ARCH_x86) /* ARCH == x86 */
+#elif defined(CONFIG_X86)
#define regs_return_value(regs) ((regs)->ax)
-#elif defined(EC_ARCH_mips) /* ARCH == mips */
+#elif defined(CONFIG_MIPS)
#define regs_return_value(regs) ((regs)->regs[2])
#else
-#error "Cannot define -DEC_ARCH_$(ARCH) or architecture no supported"
+#error this architecture is not supported
#endif
#endif /* ndef regs_return_value */
#include "sspt/sspt.h"
#include "sspt/sspt_debug.h"
#include "ks_def_handler.h"
+#include "../us_manager/us_manager.h"
#define after_buffer ec_info.buffer_size
spin_lock_init(&dbi_mh.lock);
INIT_LIST_HEAD(&dbi_mh.modules_handlers);
+
+ ptr_pack_task_event_info = pack_task_event_info;
+
return 0;
}
#include <dbi_kprobes_deps.h>
#include "storage.h"
#include "us_proc_inst.h"
+#include <sspt/sspt.h>
DEFINE_PER_CPU(struct us_ip *, gpCurIp) = NULL;
EXPORT_PER_CPU_SYMBOL_GPL(gpCurIp);
#include "helper.h"
#include "us_slot_manager.h"
-static const char *app_filter = "app";
-
#define print_event(fmt, args...) \
{ \
char *buf[1024]; \
pack_event_info(US_PROBE_ID, RECORD_ENTRY, "ds", 0x0badc0de, buf); \
}
-// is user-space instrumentation
-int is_us_instrumentation(void)
-{
- return !!us_proc_info.path;
-}
-
struct dentry *dentry_by_path(const char *path)
{
struct dentry *dentry;
return dentry;
}
-int check_vma(struct vm_area_struct *vma)
-{
- return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
- !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
- !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
-}
-
-int deinst_usr_space_proc (void)
-{
- int iRet = 0, found = 0;
- struct task_struct *task = NULL;
- struct sspt_proc *proc;
- int tmp_oops_in_progress;
-
- if (!is_us_instrumentation()) {
- return 0;
- }
-
- unregister_helper();
-
- if (iRet)
- EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
-
-
- tmp_oops_in_progress = oops_in_progress;
- oops_in_progress = 1;
- rcu_read_lock();
- for_each_process(task) {
- proc = sspt_proc_get_by_task(task);
- if (proc) {
- int ret = sspt_proc_uninstall(proc, task, US_UNREGS_PROBE);
- if (ret) {
- EPRINTF ("failed to uninstall IPs (%d)!", ret);
- }
-
- dbi_unregister_all_uprobes(task);
- }
- }
- rcu_read_unlock();
- oops_in_progress = tmp_oops_in_progress;
-
- uninit_filter();
- unregister_filter(app_filter);
-
- return iRet;
-}
-
-int inst_usr_space_proc (void)
-{
- int ret, i;
- struct task_struct *task = NULL, *ts;
- struct sspt_proc *proc;
- int tmp_oops_in_progress;
-
- if (!is_us_instrumentation()) {
- return 0;
- }
-
- DPRINTF("User space instr");
-
- ret = register_filter(app_filter, get_filter_by_path());
- if (ret)
- return ret;
-
- if (strcmp(us_proc_info.path, "*")) {
- ret = set_filter(app_filter);
- if (ret)
- return ret;
-
- ret = init_filter(us_proc_info.m_f_dentry, 0);
- if (ret)
- return ret;
- }
-
- ret = register_helper();
- if (ret) {
- return ret;
- }
-
- tmp_oops_in_progress = oops_in_progress;
- oops_in_progress = 1;
- rcu_read_lock();
- for_each_process(task) {
- ts = check_task(task);
-
- if (ts) {
- proc = sspt_proc_get_by_task_or_new(ts);
- sspt_proc_install(proc);
- }
- }
- rcu_read_unlock();
- oops_in_progress = tmp_oops_in_progress;
-
- return 0;
-}
-
void print_vma(struct mm_struct *mm);
void print_vma(struct mm_struct *mm)
#define __US_PROC_INST_H__
#include <linux/signal.h> // struct sigpending
-#include "sspt/ip.h"
-
-/* Instruments or schedules pending instrumentation of user space process. */
-extern int inst_usr_space_proc (void);
-extern int deinst_usr_space_proc (void);
extern pid_t gl_nNotifyTgid;
struct vm_area_struct;
enum US_FLAGS;
-int is_us_instrumentation(void);
-
struct dentry *dentry_by_path(const char *path);
-int check_vma(struct vm_area_struct *vma);
#endif /* !defined(__US_PROC_INST_H__) */
EXTRA_CFLAGS := $(extra_cflags)
obj-m := swap_us_manager.o
-swap_us_manager-y := 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
inlude_opt = -I$(realpath $(top_srcdir)/src/modules/driver) \
-I$(realpath $(top_srcdir)/src/modules/uprobe) \
+ -I$(realpath $(top_srcdir)/src/modules/ksyms) \
-I$(realpath $(top_srcdir)/src/modules/kprobe) \
- -I$(realpath $(top_srcdir)/src/modules/kprobe/arch)
+ -I$(realpath $(top_srcdir)/src/modules/kprobe/arch) \
+ -I$(realpath $(top_srcdir)/src/modules/us_manager) \
+ -I$(realpath $(top_srcdir)/src/common)
extra_cflags = "$(inlude_opt) $(board_opt)"
*/
#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)
if (task->flags & PF_KTHREAD)
return 0;
- if (!is_us_instrumentation())
- return 0;
-
proc = sspt_proc_get_by_task(task);
if (proc)
goto install_proc;
#error this architecture is not supported
#endif
- if (!is_us_instrumentation() || task->tgid != task->pid) {
+ if (task->tgid != task->pid) {
goto out;
}
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)) {
#include "sspt_file.h"
#include "sspt_proc.h"
#include "sspt_debug.h"
-#include "../us_proc_inst.h"
#include <swap_uprobes.h>
#include "us_def_handler.h"
-#include "../storage.h"
+#include "../../driver/storage.h"
-static void print_proc_probes(const struct sspt_proc *proc);
-
-static inline struct sspt_proc *get_file_probes(const inst_us_proc_t *task_inst_info)
-{
- struct sspt_proc *proc = sspt_proc_create(task_inst_info->m_f_dentry, 0);
+#include "picl.h"
+#include "../../common/ec_probe.h"
- printk("####### get START #######\n");
+#include <us_manager.h>
- if (proc) {
- int i;
-
- printk("#2# get_file_probes: proc_p[dentry=%p]\n", proc->dentry);
-
- for (i = 0; i < task_inst_info->libs_count; ++i) {
- int k, j;
- us_proc_lib_t *p_libs = &task_inst_info->p_libs[i];
- struct dentry *dentry = p_libs->m_f_dentry;
- char *path = p_libs->path;
- char *name = strrchr(path, '/');
- name = name ? name + 1 : path;
+static void print_proc_probes(const struct sspt_proc *proc);
- for (k = 0; k < p_libs->ips_count; ++k) {
- struct ip_data pd;
- us_proc_ip_t *ip = &p_libs->p_ips[k];
- unsigned long got_addr = 0;
+struct sspt_proc;
- for (j = 0; j < p_libs->plt_count; ++j) {
- if (ip->offset == p_libs->p_plt[j].func_addr) {
- got_addr = p_libs->p_plt[j].got_addr;
- break;
- }
+static inline struct sspt_proc *get_file_probes(inst_us_proc_t *task_inst_info)
+{
+ int i, ret;
+
+ for (i = 0; i < task_inst_info->libs_count; ++i) {
+ int k, j;
+ us_proc_lib_t *p_libs = &task_inst_info->p_libs[i];
+ struct dentry *dentry = p_libs->m_f_dentry;
+ char *path = p_libs->path;
+ char *name = strrchr(path, '/');
+ name = name ? name + 1 : path;
+
+ for (k = 0; k < p_libs->ips_count; ++k) {
+ struct ip_data pd;
+ us_proc_ip_t *ip = &p_libs->p_ips[k];
+ unsigned long got_addr = 0;
+
+ for (j = 0; j < p_libs->plt_count; ++j) {
+ if (ip->offset == p_libs->p_plt[j].func_addr) {
+ got_addr = p_libs->p_plt[j].got_addr;
+ break;
}
+ }
- pd.flag_retprobe = 1;
- pd.offset = ip->offset;
- pd.got_addr = got_addr;
- pd.pre_handler = ip->jprobe.pre_entry ? ip->jprobe.pre_entry : ujprobe_event_pre_handler;
- pd.jp_handler = (unsigned long) (ip->jprobe.entry ? ip->jprobe.entry : ujprobe_event_handler);
- pd.rp_handler = ip->retprobe.handler ? ip->retprobe.handler : uretprobe_event_handler;
+ pd.flag_retprobe = 1;
+ pd.offset = ip->offset;
+ pd.got_addr = got_addr;
+ pd.pre_handler = ip->jprobe.pre_entry ? ip->jprobe.pre_entry : ujprobe_event_pre_handler;
+ pd.jp_handler = (unsigned long) (ip->jprobe.entry ? ip->jprobe.entry : ujprobe_event_handler);
+ pd.rp_handler = ip->retprobe.handler ? ip->retprobe.handler : uretprobe_event_handler;
- sspt_proc_add_ip_data(proc, dentry, name, &pd);
- }
+ ret = usm_register_probe(dentry, pd.offset, pd.pre_handler, pd.jp_handler, pd.rp_handler);
+ if (ret)
+ printk("### ERROR: usm_register_probe ret=%d\n", ret);
}
}
-// print_proc_probes(proc);
+ usm_set_dentry(task_inst_info->m_f_dentry);
printk("####### get END #######\n");
- return proc;
+ return NULL;
}
+static int check_vma(struct vm_area_struct *vma)
+{
+ return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
+ !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
+ !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
+}
enum US_FLAGS {
US_UNREGS_PROBE,
ret = dbi_register_ujprobe(&ip->jprobe);
if (ret) {
if (ret == -ENOEXEC) {
- pack_event_info(ERR_MSG_ID, RECORD_ENTRY, "dp",
- 0x1,
- ip->jprobe.up.kp.addr);
+ ptr_pack_task_event_info(current, ERR_MSG_ID,
+ RECORD_ENTRY, "dp",
+ 0x1,
+ ip->jprobe.up.kp.addr);
}
printk("dbi_register_ujprobe() failure %d\n", ret);
return ret;
file->vm_start = vma->vm_start;
file->vm_end = vma->vm_end;
- pack_task_event_info(task, DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
- task->tgid, file->name, vma->vm_start,
- vma->vm_end - vma->vm_start, app_flag);
+ ptr_pack_task_event_info(task, DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
+ task->tgid, file->name, vma->vm_start,
+ vma->vm_end - vma->vm_start, app_flag);
}
static LIST_HEAD(proc_probes_list);
+extern struct sspt_proc *proc_base;
+
struct sspt_proc *sspt_proc_create(struct dentry* dentry, struct task_struct *task)
{
struct sspt_proc *proc = kmalloc(sizeof(*proc), GFP_ATOMIC);
kfree(proc);
}
-// TODO: remove "us_proc_info"
-#include "../storage.h"
-extern inst_us_proc_t us_proc_info;
-
struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
{
struct sspt_proc *proc, *tmp;
{
struct sspt_proc *proc;
- proc = sspt_proc_copy(us_proc_info.pp, task);
+ proc = sspt_proc_copy(proc_base, task);
add_proc_probes(proc);
return proc;
void sspt_proc_free_all(void)
{
- // is user-space instrumentation
- if (us_proc_info.path == NULL) {
- return;
- }
-
struct sspt_proc *proc, *n;
list_for_each_entry_safe(proc, n, &proc_probes_list, list) {
list_del(&proc->list);
#include <linux/module.h>
+#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>
-static struct sspt_proc *proc_base;
+static const char *app_filter = "app";
+
+struct sspt_proc *proc_base;
+void (*ptr_pack_task_event_info)(struct task_struct *task,
+ int probe_id,
+ int record_type,
+ const char *fmt, ...) = NULL;
+
+EXPORT_SYMBOL_GPL(ptr_pack_task_event_info);
int usm_register_probe(struct dentry *dentry, unsigned long offset,
void *pre_handler, void *jp_handler, void *rp_handler)
return 0;
}
+EXPORT_SYMBOL_GPL(usm_register_probe);
int usm_unregister_probe(struct dentry *dentry, unsigned long offset)
{
return 0;
}
+EXPORT_SYMBOL_GPL(usm_unregister_probe);
+
+int usm_set_dentry(struct dentry *dentry)
+{
+ proc_base->dentry = dentry;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usm_set_dentry);
+
+int usm_stop(void)
+{
+ int iRet = 0, found = 0;
+ struct task_struct *task = NULL;
+ struct sspt_proc *proc;
+ int tmp_oops_in_progress;
+
+ unregister_helper();
+
+ if (iRet)
+ printk("uninstall_kernel_probe(do_munmap) result=%d!\n", iRet);
+
+
+ tmp_oops_in_progress = oops_in_progress;
+ oops_in_progress = 1;
+ rcu_read_lock();
+ for_each_process(task) {
+ proc = sspt_proc_get_by_task(task);
+ if (proc) {
+ int ret = sspt_proc_uninstall(proc, task, US_UNREGS_PROBE);
+ if (ret)
+ printk("failed to uninstall IPs (%d)!\n", ret);
+
+ dbi_unregister_all_uprobes(task);
+ }
+ }
+ rcu_read_unlock();
+ oops_in_progress = tmp_oops_in_progress;
+
+ uninit_filter();
+ unregister_filter(app_filter);
+
+ sspt_proc_free_all();
+
+ return iRet;
+}
+EXPORT_SYMBOL_GPL(usm_stop);
+
+int usm_start(void)
+{
+ int ret, i;
+ struct task_struct *task = NULL, *ts;
+ 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;
+ }
+
+ ret = register_helper();
+ if (ret) {
+ return ret;
+ }
+
+ tmp_oops_in_progress = oops_in_progress;
+ oops_in_progress = 1;
+ rcu_read_lock();
+ for_each_process(task) {
+ ts = check_task(task);
+
+ if (ts) {
+ proc = sspt_proc_get_by_task_or_new(ts);
+ sspt_proc_install(proc);
+ }
+ }
+ rcu_read_unlock();
+ oops_in_progress = tmp_oops_in_progress;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usm_start);
static int __init init_us_manager(void)
{
+ int ret;
+
+ ret = init_helper();
+ if (ret)
+ return ret;
+
proc_base = sspt_proc_create(NULL, NULL);
+ if (proc_base == NULL)
+ return -ENOMEM;
+
return 0;
}
static void __exit exit_us_manager(void)
{
sspt_proc_free(proc_base);
+ uninit_helper();
}
module_init(init_us_manager);