unsigned long pf_addr;
unsigned long cp_addr;
+unsigned long mr_addr;
unsigned long exit_addr;
-unsigned long exec_addr;
kernel_probe_t *pf_probe = NULL;
kernel_probe_t *cp_probe = NULL;
+kernel_probe_t *mr_probe = NULL;
kernel_probe_t *exit_probe = NULL;
-kernel_probe_t *exec_probe = NULL;
unsigned int probes_flags = 0;
int
return -EINVAL;
}
- cp_addr = lookup_name("copy_process");
- if (cp_addr == 0) {
- EPRINTF("Cannot find address for copy_process function!");
- return -EINVAL;
- }
+ cp_addr = lookup_name("copy_process");
+ if (cp_addr == 0) {
+ EPRINTF("Cannot find address for copy_process function!");
+ return -EINVAL;
+ }
- exit_addr = lookup_name("do_exit");
- if (exit_addr == 0) {
- EPRINTF("Cannot find address for do_exit function!");
+ mr_addr = lookup_name("mm_release");
+ if (mr_addr == 0) {
+ EPRINTF("Cannot find address for mm_release function!");
return -EINVAL;
}
- exec_addr = lookup_name("do_execve");
- if (exec_addr == 0) {
- EPRINTF("Cannot find address for do_execve function!");
+ exit_addr = lookup_name("do_exit");
+ if (exit_addr == 0) {
+ EPRINTF("Cannot find address for do_exit function!");
return -EINVAL;
}
register_kernel_jprobe (kernel_probe_t * probe)
{
int result;
- if (((probe == pf_probe) && (us_proc_probes & US_PROC_PF_INSTLD)) ||
+ if( ((probe == pf_probe) && (us_proc_probes & US_PROC_PF_INSTLD)) ||
((probe == cp_probe) && (us_proc_probes & US_PROC_CP_INSTLD)) ||
- ((probe == exec_probe) && (us_proc_probes & US_PROC_EXEC_INSTLD)) ||
+ ((probe == mr_probe) && (us_proc_probes & US_PROC_MR_INSTLD)) ||
((probe == exit_probe) && (us_proc_probes & US_PROC_EXIT_INSTLD)))
{
return 0; // probe is already registered
static int
unregister_kernel_jprobe (kernel_probe_t * probe)
{
- if (((probe == pf_probe) && (us_proc_probes & US_PROC_PF_INSTLD)) ||
- ((probe == cp_probe) && (us_proc_probes & US_PROC_CP_INSTLD)) ||
- ((probe == exit_probe) && (us_proc_probes & US_PROC_EXIT_INSTLD)) ||
- ((probe == exec_probe) && (us_proc_probes & US_PROC_EXEC_INSTLD))) {
+ if( ((probe == pf_probe) && (us_proc_probes & US_PROC_PF_INSTLD)) ||
+ ((probe == cp_probe) && (us_proc_probes & US_PROC_CP_INSTLD)) ||
+ ((probe == mr_probe) && (us_proc_probes & US_PROC_MR_INSTLD)) ||
+ ((probe == exit_probe) && (us_proc_probes & US_PROC_EXIT_INSTLD)) ) {
return 0; // probe is necessary for user space instrumentation
}
dbi_unregister_jprobe (&probe->jprobe);
register_kernel_retprobe (kernel_probe_t * probe)
{
int result;
- if (((probe == pf_probe) && (us_proc_probes & US_PROC_PF_INSTLD)) ||
- ((probe == cp_probe) && (us_proc_probes & US_PROC_CP_INSTLD)) ||
- ((probe == exit_probe) && (us_proc_probes & US_PROC_EXIT_INSTLD)) ||
- ((probe == exec_probe) && (us_proc_probes & US_PROC_EXEC_INSTLD))) {
+ if( ((probe == pf_probe) && (us_proc_probes & US_PROC_PF_INSTLD)) ||
+ ((probe == cp_probe) && (us_proc_probes & US_PROC_CP_INSTLD)) ||
+ ((probe == mr_probe) && (us_proc_probes & US_PROC_MR_INSTLD)) ||
+ ((probe == exit_probe) && (us_proc_probes & US_PROC_EXIT_INSTLD)) ) {
+
return 0; // probe is already registered
}
static int
unregister_kernel_retprobe (kernel_probe_t * probe)
{
- if (((probe == pf_probe) && (us_proc_probes & US_PROC_PF_INSTLD)) ||
- ((probe == cp_probe) && (us_proc_probes & US_PROC_CP_INSTLD)) ||
- ((probe == exit_probe) && (us_proc_probes & US_PROC_EXIT_INSTLD)) ||
- ((probe == exec_probe) && (us_proc_probes & US_PROC_EXEC_INSTLD))) {
+ if( ((probe == pf_probe) && (us_proc_probes & US_PROC_PF_INSTLD)) ||
+ ((probe == cp_probe) && (us_proc_probes & US_PROC_CP_INSTLD)) ||
+ ((probe == mr_probe) && (us_proc_probes & US_PROC_MR_INSTLD)) ||
+ ((probe == exit_probe) && (us_proc_probes & US_PROC_EXIT_INSTLD)) ) {
return 0; // probe is necessary for user space instrumentation
}
dbi_unregister_kretprobe (&probe->retprobe);
}
pprobe = &pf_probe;
}
- else if (addr == cp_addr) {
- probes_flags |= PROBE_FLAG_CP_INSTLD;
- if (us_proc_probes & US_PROC_CP_INSTLD)
- {
- return 0;
- }
- pprobe = &cp_probe;
- }
+ else if (addr == cp_addr) {
+ probes_flags |= PROBE_FLAG_CP_INSTLD;
+ if (us_proc_probes & US_PROC_CP_INSTLD)
+ {
+ return 0;
+ }
+ pprobe = &cp_probe;
+ }
else if (addr == exit_addr) {
probes_flags |= PROBE_FLAG_EXIT_INSTLD;
if (us_proc_probes & US_PROC_EXIT_INSTLD)
}
pprobe = &exit_probe;
}
- else if (addr == exec_addr) {
- probes_flags |= PROBE_FLAG_EXEC_INSTLD;
- if (us_proc_probes & US_PROC_EXEC_INSTLD) {
+ else if (addr == mr_addr) {
+ probes_flags |= PROBE_FLAG_MR_INSTLD;
+ if (us_proc_probes & US_PROC_MR_INSTLD) {
return 0;
}
- pprobe = &exec_probe;
+ pprobe = &mr_probe;
}
result = add_probe_to_list (addr, pprobe);
if (result) {
if (addr == pf_addr)
probes_flags &= ~PROBE_FLAG_PF_INSTLD;
- else if (addr == cp_addr)
- probes_flags &= ~PROBE_FLAG_CP_INSTLD;
+ else if (addr == cp_addr)
+ probes_flags &= ~PROBE_FLAG_CP_INSTLD;
else if (addr == exit_addr)
probes_flags &= ~PROBE_FLAG_EXIT_INSTLD;
- else if (addr == exec_addr)
- probes_flags &= ~PROBE_FLAG_EXEC_INSTLD;
+ else if (addr == mr_addr)
+ probes_flags &= ~PROBE_FLAG_MR_INSTLD;
}
return result;
}
if (p->addr == pf_addr) {
probes_flags &= ~PROBE_FLAG_PF_INSTLD;
pf_probe = NULL;
- } else if (p->addr == cp_addr) {
- probes_flags &= ~PROBE_FLAG_CP_INSTLD;
- cp_probe = NULL;
+ } else if (p->addr == cp_addr) {
+ probes_flags &= ~PROBE_FLAG_CP_INSTLD;
+ cp_probe = NULL;
} else if (p->addr == exit_addr) {
probes_flags &= ~PROBE_FLAG_EXIT_INSTLD;
exit_probe = NULL;
- } else if (p->addr == exec_addr) {
- probes_flags &= ~PROBE_FLAG_EXEC_INSTLD;
- exec_probe = NULL;
+ } else if (p->addr == mr_addr) {
+ probes_flags &= ~PROBE_FLAG_MR_INSTLD;
+ mr_probe = NULL;
}
hlist_del(node);
kfree(p);
if (p->addr == pf_addr) {
probes_flags &= ~PROBE_FLAG_PF_INSTLD;
pf_probe = NULL;
- } else if (p->addr == cp_addr) {
- probes_flags &= ~PROBE_FLAG_CP_INSTLD;
- cp_probe = NULL;
+ } else if (p->addr == cp_addr) {
+ probes_flags &= ~PROBE_FLAG_CP_INSTLD;
+ cp_probe = NULL;
} else if (p->addr == exit_addr) {
probes_flags &= ~PROBE_FLAG_EXIT_INSTLD;
exit_probe = NULL;
- } else if (p->addr == exec_addr) {
- probes_flags &= ~PROBE_FLAG_EXEC_INSTLD;
- exec_probe = NULL;
+ } else if (p->addr == mr_addr) {
+ probes_flags &= ~PROBE_FLAG_MR_INSTLD;
+ mr_probe = NULL;
}
hlist_del(node);
kfree(p);
}
pf_probe = NULL;
}
- else if (addr == cp_addr) {
- probes_flags &= ~PROBE_FLAG_CP_INSTLD;
- if (us_proc_probes & US_PROC_CP_INSTLD)
- {
- return 0;
- }
- cp_probe = NULL;
- }
+ else if (addr == cp_addr) {
+ probes_flags &= ~PROBE_FLAG_CP_INSTLD;
+ if (us_proc_probes & US_PROC_CP_INSTLD)
+ {
+ return 0;
+ }
+ cp_probe = NULL;
+ }
+ else if (addr == mr_addr) {
+ probes_flags &= ~PROBE_FLAG_MR_INSTLD;
+ if (us_proc_probes & US_PROC_MR_INSTLD) {
+ return 0;
+ }
+ mr_probe = NULL;
+ }
else if (addr == exit_addr) {
probes_flags &= ~PROBE_FLAG_EXIT_INSTLD;
if (us_proc_probes & US_PROC_EXIT_INSTLD)
}
exit_probe = NULL;
}
- else if (addr == exec_addr) {
- probes_flags &= ~PROBE_FLAG_EXEC_INSTLD;
- if (us_proc_probes & US_PROC_EXEC_INSTLD) {
- return 0;
- }
- exec_probe = NULL;
- }
result = remove_probe_from_list (addr);
skip = 1;
#endif /* CONFIG_X86 */
}
- else if (cp_probe == probe)
- {
- if (!(probes_flags & PROBE_FLAG_CP_INSTLD))
- skip = 1;
- }
- else if (exit_probe == probe)
+ else if (cp_probe == probe)
{
- if (us_proc_probes & US_PROC_EXIT_INSTLD)
- do_exit_probe_pre_code ();
- if (!(probes_flags & PROBE_FLAG_EXIT_INSTLD))
+ if (!(probes_flags & PROBE_FLAG_CP_INSTLD))
skip = 1;
}
- else if (exec_probe == probe)
+ else if (mr_probe == probe)
+ {
+ if (us_proc_probes & US_PROC_MR_INSTLD)
+ mm_release_probe_pre_code();
+ if (!(probes_flags & PROBE_FLAG_MR_INSTLD))
+ skip = 1;
+ }
+ else if (exit_probe == probe)
{
- if (us_proc_probes & US_PROC_EXEC_INSTLD)
- /*
- * FIXME: This is not a good choice to call do_exit_probe_pre_code()
- * here. The function should have more common name explaining that
- * we deinstall all the user space instrumentation from this task.
- */
- do_exit_probe_pre_code ();
- if (!(probes_flags & PROBE_FLAG_EXEC_INSTLD))
+ if (us_proc_probes & US_PROC_EXIT_INSTLD)
+ do_exit_probe_pre_code();
+ if (!(probes_flags & PROBE_FLAG_EXIT_INSTLD))
skip = 1;
}
if (!(probes_flags & PROBE_FLAG_CP_INSTLD))
skip = 1;
}
+ else if (mr_probe == probe)
+ {
+ if (!(probes_flags & PROBE_FLAG_MR_INSTLD))
+ skip = 1;
+ }
else if (exit_probe == probe)
{
if (!(probes_flags & PROBE_FLAG_EXIT_INSTLD))
//if user-space instrumentation is not set
if (!us_proc_info.path)
- return 0;
+ return 0;
iRet = uninstall_kernel_probe (pf_addr, US_PROC_PF_INSTLD,
0, &pf_probe);
if (iRet)
EPRINTF ("uninstall_kernel_probe(do_page_fault) result=%d!", iRet);
- iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
- 0, &cp_probe);
- if (iRet)
- EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
+ iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
+ 0, &cp_probe);
+ if (iRet)
+ EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
+
+ iRet = uninstall_kernel_probe (mr_addr, US_PROC_MR_INSTLD,
+ 0, &mr_probe);
+ if (iRet)
+ EPRINTF ("uninstall_kernel_probe(mm_release) result=%d!", iRet);
iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
0, &exit_probe);
if (iRet)
EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
- iRet = uninstall_kernel_probe (exec_addr, US_PROC_EXEC_INSTLD,
- 0, &exec_probe);
- if (iRet)
- EPRINTF ("uninstall_kernel_probe(do_execve) result=%d!", iRet);
-
if (!strcmp(us_proc_info.path,"*"))
{
for_each_process (task)
EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
return ret;
}
- // enable 'do_exit' probe to detect when user proc exits in order to remove user space probes
+ // 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 ("instpall_kernel_probe(copy_process) result=%d!", ret);
return ret;
}
- /*
- * When do_execve occurs we need to unregister all the uprobes from
- * this address space because VMAs may change.
- */
- ret = install_kernel_probe (exec_addr, US_PROC_EXEC_INSTLD, 0, &exec_probe);
+
+ // 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(do_execve) result=%d!", ret);
+ EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
return ret;
}
return 0;
}
-char expath[512];
-
void do_page_fault_ret_pre_code (void)
{
struct mm_struct *mm;
EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
+
void do_exit_probe_pre_code (void)
{
+ // TODO: remove task
+}
+EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
+
+void mm_release_probe_pre_code(void)
+{
int iRet, del = 0;
struct task_struct *task;
inst_us_proc_t *task_inst_info = NULL;
}
}
}
-EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
+EXPORT_SYMBOL_GPL(mm_release_probe_pre_code);
static void recover_child(struct task_struct *child_task, inst_us_proc_t *parent_iup)
{
- int i, k;
- for (i = 0; i < parent_iup->libs_count; ++i)
- {
- for (k = 0; k < parent_iup->p_libs[i].ips_count; ++k)
- if (parent_iup->p_libs[i].p_ips[k].installed)
- arch_disarm_uprobe (&parent_iup->p_libs[i].p_ips[k].jprobe.kp, child_task);
-
- for (k = 0; k < parent_iup->p_libs[i].vtps_count; ++k)
- if (parent_iup->p_libs[i].p_vtps[k].installed)
- arch_disarm_uprobe (&parent_iup->p_libs[i].p_vtps[k].jprobe.kp, child_task);
- }
+ int i, k;
+ for(i = 0; i < parent_iup->libs_count; ++i)
+ {
+ for(k = 0; k < parent_iup->p_libs[i].ips_count; ++k)
+ if(parent_iup->p_libs[i].p_ips[k].installed)
+ arch_disarm_uprobe(&parent_iup->p_libs[i].p_ips[k].jprobe.kp, child_task);
+
+ for(k = 0; k < parent_iup->p_libs[i].vtps_count; ++k)
+ if(parent_iup->p_libs[i].p_vtps[k].installed)
+ arch_disarm_uprobe(&parent_iup->p_libs[i].p_vtps[k].jprobe.kp, child_task);
+ }
}
-static void rm_uprobs_child(struct task_struct *new_task)
+static void rm_uprobes_child(struct task_struct *new_task)
{
- if(us_proc_info.path && (us_proc_info.tgid == current->tgid)) {
- recover_child(new_task, &us_proc_info);
- }
+ if(!strcmp(us_proc_info.path, "*")) {
+ inst_us_proc_t *task_inst_info = get_task_inst_node(current);
+ if(task_inst_info)
+ recover_child(new_task, task_inst_info);
+ } else {
+ if(us_proc_info.tgid == current->tgid) {
+ recover_child(new_task, &us_proc_info);
+ }
+ }
}
void copy_process_ret_pre_code(struct task_struct *p)
{
- if(!p || IS_ERR(p))
- return;
+ if(!p || IS_ERR(p))
+ return;
- if(p->mm != current->mm) // check flags CLONE_VM
- rm_uprobs_child(p);
+ if(p->mm != current->mm) // check flags CLONE_VM
+ rm_uprobes_child(p);
}