Commit ab50f6ac authored by Pavel Emelyanov's avatar Pavel Emelyanov

ptrace: Factor out pie stopping code

Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Acked-by: 's avatarAndrey Vagin <avagin@parallels.com>
parent 48fcc799
...@@ -1579,20 +1579,9 @@ static int attach_to_tasks(bool root_seized, enum trace_flags *flag) ...@@ -1579,20 +1579,9 @@ static int attach_to_tasks(bool root_seized, enum trace_flags *flag)
return -1; return -1;
} }
ret = ptrace_set_breakpoint(pid, item->rst->breakpoint); ret = ptrace_stop_pie(pid, item->rst->breakpoint, flag);
if (ret < 0) if (ret < 0)
return -1; return -1;
/* A breakpoint was not set */
if (ret > 0)
*flag = TRACE_EXIT;
else {
*flag = TRACE_ENTER;
if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL)) {
pr_perror("Unable to start %d", pid);
return -1;
}
}
} }
} }
......
...@@ -139,5 +139,6 @@ enum trace_flags { ...@@ -139,5 +139,6 @@ enum trace_flags {
extern int parasite_stop_on_syscall(int tasks, int sys_nr, enum trace_flags trace); extern int parasite_stop_on_syscall(int tasks, int sys_nr, enum trace_flags trace);
extern int parasite_unmap(struct parasite_ctl *ctl, unsigned long addr); extern int parasite_unmap(struct parasite_ctl *ctl, unsigned long addr);
extern int ptrace_stop_pie(pid_t pid, void *addr, enum trace_flags *tf);
#endif /* __CR_PARASITE_SYSCALL_H__ */ #endif /* __CR_PARASITE_SYSCALL_H__ */
...@@ -871,21 +871,9 @@ static int parasite_fini_seized(struct parasite_ctl *ctl) ...@@ -871,21 +871,9 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
return -1; return -1;
/* Go to sigreturn as closer as we can */ /* Go to sigreturn as closer as we can */
ret = ptrace_set_breakpoint(pid, ctl->sigreturn_addr); ret = ptrace_stop_pie(pid, ctl->sigreturn_addr, &flag);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret > 0)
flag = TRACE_EXIT;
else {
/* Start tracing syscalls */
ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
if (ret) {
pr_perror("ptrace");
return -1;
}
flag = TRACE_ENTER;
}
if (parasite_stop_on_syscall(1, __NR_rt_sigreturn, flag)) if (parasite_stop_on_syscall(1, __NR_rt_sigreturn, flag))
return -1; return -1;
...@@ -1238,3 +1226,34 @@ err_restore: ...@@ -1238,3 +1226,34 @@ err_restore:
parasite_cure_seized(ctl); parasite_cure_seized(ctl);
return NULL; return NULL;
} }
int ptrace_stop_pie(pid_t pid, void *addr, enum trace_flags *tf)
{
int ret;
ret = ptrace_set_breakpoint(pid, addr);
if (ret < 0)
return ret;
if (ret > 0) {
/*
* PIE will stop on a breakpoint, next
* stop after that will be syscall enter.
*/
*tf = TRACE_EXIT;
return 0;
}
/*
* No breakpoints available -- start tracing it
* in a per-syscall manner.
*/
ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
if (ret) {
pr_perror("ptrace");
return -1;
}
*tf = TRACE_ENTER;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment