support PTRACE_DETACH.
change getppid() to use proc->ftn->ppid_parent->pid, for ptraced process. refs #280
This commit is contained in:
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
#define RFLAGS_TF (1 << 8)
|
||||||
#define RFLAGS_IF (1 << 9)
|
#define RFLAGS_IF (1 << 9)
|
||||||
|
|
||||||
#define MSR_EFER 0xc0000080
|
#define MSR_EFER 0xc0000080
|
||||||
|
|||||||
101
kernel/syscall.c
101
kernel/syscall.c
@ -1351,9 +1351,19 @@ SYSCALL_DECLARE(getpid)
|
|||||||
|
|
||||||
SYSCALL_DECLARE(getppid)
|
SYSCALL_DECLARE(getppid)
|
||||||
{
|
{
|
||||||
if (cpu_local_var(current)->ftn->parent)
|
struct process *proc = cpu_local_var(current);
|
||||||
return cpu_local_var(current)->ftn->parent->pid;
|
int pid = 1; // fake init
|
||||||
return 1; // fake init
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&proc->ftn->lock);
|
||||||
|
if (proc->ftn->ptrace & PT_TRACED) {
|
||||||
|
if (proc->ftn->ppid_parent)
|
||||||
|
pid = proc->ftn->ppid_parent->pid;
|
||||||
|
} else {
|
||||||
|
if (proc->ftn->parent)
|
||||||
|
pid = proc->ftn->parent->pid;
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
|
||||||
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2542,6 +2552,88 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ptrace_detach(int pid, int data)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
struct process *proc;
|
||||||
|
struct fork_tree_node *child, *next;
|
||||||
|
ihk_spinlock_t *savelock;
|
||||||
|
unsigned long irqstate;
|
||||||
|
struct siginfo info;
|
||||||
|
|
||||||
|
proc = findthread_and_lock(pid, -1, &savelock, &irqstate);
|
||||||
|
if (!proc) {
|
||||||
|
error = -ESRCH;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock(savelock, irqstate);
|
||||||
|
|
||||||
|
if (!(proc->ftn->ptrace & PT_TRACED) || proc->ftn->parent == NULL) {
|
||||||
|
error = -ESRCH;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data > 64 || data < 0) {
|
||||||
|
error = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&proc->ftn->lock);
|
||||||
|
ihk_mc_spinlock_lock_noirq(&proc->ftn->parent->lock);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(child, next, &proc->ftn->parent->ptrace_children, ptrace_siblings_list) {
|
||||||
|
if (child == proc->ftn) {
|
||||||
|
list_del(&child->ptrace_siblings_list);
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kprintf("ptrace_detach,not found\n");
|
||||||
|
error = -EPERM;
|
||||||
|
goto out_notfound;
|
||||||
|
found:
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock);
|
||||||
|
|
||||||
|
proc->ftn->ptrace = 0;
|
||||||
|
proc->ftn->parent = proc->ftn->ppid_parent;
|
||||||
|
proc->ftn->ppid_parent = NULL;
|
||||||
|
|
||||||
|
if (proc->ftn->parent) {
|
||||||
|
ihk_mc_spinlock_lock_noirq(&proc->ftn->parent->lock);
|
||||||
|
list_add_tail(&proc->ftn->siblings_list, &proc->ftn->parent->children);
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
proc->uctx->rflags &= ~RFLAGS_TF; /* SingleStep clear */
|
||||||
|
/* TODO: other flags may clear */
|
||||||
|
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
|
||||||
|
|
||||||
|
if (data != 0) {
|
||||||
|
struct process *cur;
|
||||||
|
|
||||||
|
cur = cpu_local_var(current);
|
||||||
|
memset(&info, '\0', sizeof info);
|
||||||
|
info.si_signo = data;
|
||||||
|
info.si_code = SI_USER;
|
||||||
|
info._sifields._kill.si_pid = cur->ftn->pid;
|
||||||
|
error = do_kill(pid, -1, data, &info, 1);
|
||||||
|
if (error < 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error = sched_wakeup_process(proc, PS_TRACED | PS_STOPPED);
|
||||||
|
if (error < 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return error;
|
||||||
|
out_notfound:
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock);
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(ptrace)
|
SYSCALL_DECLARE(ptrace)
|
||||||
{
|
{
|
||||||
const long request = (long)ihk_mc_syscall_arg0(ctx);
|
const long request = (long)ihk_mc_syscall_arg0(ctx);
|
||||||
@ -2607,7 +2699,8 @@ SYSCALL_DECLARE(ptrace)
|
|||||||
dkprintf("ptrace: unimplemented ptrace(PTRACE_ATTACH) called.\n");
|
dkprintf("ptrace: unimplemented ptrace(PTRACE_ATTACH) called.\n");
|
||||||
break;
|
break;
|
||||||
case PTRACE_DETACH:
|
case PTRACE_DETACH:
|
||||||
dkprintf("ptrace: unimplemented ptrace(PTRACE_DETACH) called.\n");
|
dkprintf("ptrace: PTRACE_DETACH: data=%d\n", data);
|
||||||
|
error = ptrace_detach(pid, data);
|
||||||
break;
|
break;
|
||||||
case PTRACE_GETFPXREGS:
|
case PTRACE_GETFPXREGS:
|
||||||
dkprintf("ptrace: unimplemented ptrace(PTRACE_GETFPXREGS) called.\n");
|
dkprintf("ptrace: unimplemented ptrace(PTRACE_GETFPXREGS) called.\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user