ptrace: Allow separate tracing of signals and syscalls
This commit is contained in:
parent
8859849452
commit
0146b31837
@ -67,7 +67,9 @@ typedef struct file_descriptors {
|
||||
#define PROC_FLAG_RUNNING 0x08
|
||||
#define PROC_FLAG_SLEEP_INT 0x10
|
||||
#define PROC_FLAG_SUSPENDED 0x20
|
||||
#define PROC_FLAG_TRACED 0x40
|
||||
|
||||
#define PROC_FLAG_TRACE_SYSCALLS 0x40
|
||||
#define PROC_FLAG_TRACE_SIGNALS 0x80
|
||||
|
||||
typedef struct process {
|
||||
pid_t id; /* PID */
|
||||
|
@ -11,7 +11,8 @@ enum __ptrace_request {
|
||||
PTRACE_DETACH,
|
||||
PTRACE_TRACEME,
|
||||
PTRACE_GETREGS,
|
||||
PTRACE_PEEKDATA
|
||||
PTRACE_PEEKDATA,
|
||||
PTRACE_SIGNALS_ONLY_PLZ
|
||||
};
|
||||
|
||||
enum __ptrace_event {
|
||||
|
@ -16,7 +16,7 @@ long ptrace_attach(pid_t pid) {
|
||||
process_t * tracee = process_from_pid(pid);
|
||||
if (!tracee) return -ESRCH;
|
||||
if (this_core->current_process->user != 0 && this_core->current_process->user != tracee->user) return -EPERM;
|
||||
__sync_or_and_fetch(&tracee->flags, PROC_FLAG_TRACED);
|
||||
__sync_or_and_fetch(&tracee->flags, (PROC_FLAG_TRACE_SYSCALLS | PROC_FLAG_TRACE_SIGNALS));
|
||||
tracee->tracer = this_core->current_process->id;
|
||||
send_signal(pid, SIGSTOP, 1);
|
||||
return 0;
|
||||
@ -26,7 +26,7 @@ long ptrace_self(void) {
|
||||
process_t * parent = process_get_parent((process_t*)this_core->current_process);
|
||||
if (!parent) return -EINVAL;
|
||||
|
||||
__sync_or_and_fetch(&this_core->current_process->flags, PROC_FLAG_TRACED);
|
||||
__sync_or_and_fetch(&this_core->current_process->flags, (PROC_FLAG_TRACE_SYSCALLS | PROC_FLAG_TRACE_SIGNALS));
|
||||
this_core->current_process->tracer = parent->id;
|
||||
|
||||
return 0;
|
||||
@ -95,6 +95,14 @@ long ptrace_peek(pid_t pid, void * addr, void * data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long ptrace_signals_only(pid_t pid) {
|
||||
process_t * tracee = process_from_pid(pid);
|
||||
if (!tracee || (tracee->tracer != this_core->current_process->id) || !(tracee->flags & PROC_FLAG_SUSPENDED)) return -ESRCH;
|
||||
__sync_and_and_fetch(&tracee->flags, ~(PROC_FLAG_TRACE_SYSCALLS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long ptrace_handle(long request, pid_t pid, void * addr, void * data) {
|
||||
switch (request) {
|
||||
case PTRACE_ATTACH:
|
||||
@ -107,6 +115,8 @@ long ptrace_handle(long request, pid_t pid, void * addr, void * data) {
|
||||
return ptrace_continue(pid,(uintptr_t)data);
|
||||
case PTRACE_PEEKDATA:
|
||||
return ptrace_peek(pid,addr,data);
|
||||
case PTRACE_SIGNALS_ONLY_PLZ:
|
||||
return ptrace_signals_only(pid);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ void handle_signal(process_t * proc, signal_t * sig) {
|
||||
free(sig);
|
||||
|
||||
/* Are we being traced? */
|
||||
if (this_core->current_process->flags & PROC_FLAG_TRACED) {
|
||||
if (this_core->current_process->flags & PROC_FLAG_TRACE_SIGNALS) {
|
||||
signum = ptrace_signal(signum, 0);
|
||||
}
|
||||
|
||||
|
@ -1138,7 +1138,7 @@ void syscall_handler(struct regs * r) {
|
||||
scall_func func = syscalls[arch_syscall_number(r)];
|
||||
this_core->current_process->syscall_registers = r;
|
||||
|
||||
if (this_core->current_process->flags & PROC_FLAG_TRACED) {
|
||||
if (this_core->current_process->flags & PROC_FLAG_TRACE_SYSCALLS) {
|
||||
ptrace_signal(SIGTRAP, PTRACE_EVENT_SYSCALL_ENTER);
|
||||
}
|
||||
|
||||
@ -1146,7 +1146,7 @@ void syscall_handler(struct regs * r) {
|
||||
arch_syscall_arg0(r), arch_syscall_arg1(r), arch_syscall_arg2(r),
|
||||
arch_syscall_arg3(r), arch_syscall_arg4(r)));
|
||||
|
||||
if (this_core->current_process->flags & PROC_FLAG_TRACED) {
|
||||
if (this_core->current_process->flags & PROC_FLAG_TRACE_SYSCALLS) {
|
||||
ptrace_signal(SIGTRAP, PTRACE_EVENT_SYSCALL_EXIT);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user