@@ -506,7 +506,16 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
|
|||||||
int coredumped = 0;
|
int coredumped = 0;
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
|
|
||||||
kfree(pending);
|
if(ptraceflag){
|
||||||
|
if(proc->ptrace_recvsig)
|
||||||
|
kfree(proc->ptrace_recvsig);
|
||||||
|
proc->ptrace_recvsig = pending;
|
||||||
|
if(proc->ptrace_sendsig)
|
||||||
|
kfree(proc->ptrace_sendsig);
|
||||||
|
proc->ptrace_sendsig = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
kfree(pending);
|
||||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||||
switch (sig) {
|
switch (sig) {
|
||||||
case SIGSTOP:
|
case SIGSTOP:
|
||||||
|
|||||||
@@ -386,6 +386,8 @@ struct process {
|
|||||||
unsigned long saved_auxv[AUXV_LEN];
|
unsigned long saved_auxv[AUXV_LEN];
|
||||||
|
|
||||||
unsigned long *ptrace_debugreg; /* debug registers for ptrace */
|
unsigned long *ptrace_debugreg; /* debug registers for ptrace */
|
||||||
|
struct sig_pending *ptrace_recvsig;
|
||||||
|
struct sig_pending *ptrace_sendsig;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct process_vm {
|
struct process_vm {
|
||||||
|
|||||||
@@ -1969,6 +1969,12 @@ void destroy_process(struct process *proc)
|
|||||||
if (proc->ptrace_debugreg) {
|
if (proc->ptrace_debugreg) {
|
||||||
kfree(proc->ptrace_debugreg);
|
kfree(proc->ptrace_debugreg);
|
||||||
}
|
}
|
||||||
|
if (proc->ptrace_recvsig) {
|
||||||
|
kfree(proc->ptrace_recvsig);
|
||||||
|
}
|
||||||
|
if (proc->ptrace_sendsig) {
|
||||||
|
kfree(proc->ptrace_sendsig);
|
||||||
|
}
|
||||||
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2715,11 +2715,18 @@ static int ptrace_wakeup_sig(int pid, long request, long data) {
|
|||||||
|
|
||||||
/* TODO: Tracing process replace the original
|
/* TODO: Tracing process replace the original
|
||||||
signal with "data" */
|
signal with "data" */
|
||||||
proc = cpu_local_var(current);
|
if (request == PTRACE_CONT && child->ptrace_sendsig) {
|
||||||
memset(&info, '\0', sizeof info);
|
memcpy(&info, &child->ptrace_sendsig->info, sizeof info);
|
||||||
info.si_signo = data;
|
kfree(child->ptrace_sendsig);
|
||||||
info.si_code = SI_USER;
|
child->ptrace_sendsig = NULL;
|
||||||
info._sifields._kill.si_pid = proc->ftn->pid;
|
}
|
||||||
|
else {
|
||||||
|
proc = cpu_local_var(current);
|
||||||
|
memset(&info, '\0', sizeof info);
|
||||||
|
info.si_signo = data;
|
||||||
|
info.si_code = SI_USER;
|
||||||
|
info._sifields._kill.si_pid = proc->ftn->pid;
|
||||||
|
}
|
||||||
error = do_kill(pid, -1, data, &info, 1);
|
error = do_kill(pid, -1, data, &info, 1);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
@@ -3185,6 +3192,70 @@ static long ptrace_geteventmsg(int pid, long data)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
ptrace_getsiginfo(int pid, siginfo_t *data)
|
||||||
|
{
|
||||||
|
ihk_spinlock_t *savelock;
|
||||||
|
unsigned long irqstate;
|
||||||
|
struct process *child;
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
child = findthread_and_lock(pid, -1, &savelock, &irqstate);
|
||||||
|
if (!child) {
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child->ftn->status != PS_TRACED) {
|
||||||
|
rc = -ESRCH;
|
||||||
|
}
|
||||||
|
else if (child->ptrace_recvsig) {
|
||||||
|
if (copy_to_user(proc, data, &child->ptrace_recvsig->info, sizeof(siginfo_t))) {
|
||||||
|
rc = -EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = -ESRCH;
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock(savelock, irqstate);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
ptrace_setsiginfo(int pid, siginfo_t *data)
|
||||||
|
{
|
||||||
|
ihk_spinlock_t *savelock;
|
||||||
|
unsigned long irqstate;
|
||||||
|
struct process *child;
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
kprintf("ptrace_setsiginfo: sig=%d errno=%d code=%d\n", data->si_signo, data->si_errno, data->si_code);
|
||||||
|
child = findthread_and_lock(pid, -1, &savelock, &irqstate);
|
||||||
|
if (!child) {
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child->ftn->status != PS_TRACED) {
|
||||||
|
rc = -ESRCH;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (child->ptrace_sendsig == NULL) {
|
||||||
|
child->ptrace_sendsig = kmalloc(sizeof(struct sig_pending), IHK_MC_AP_NOWAIT);
|
||||||
|
if (child->ptrace_sendsig == NULL) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rc &&
|
||||||
|
copy_from_user(proc, &child->ptrace_sendsig->info, data, sizeof(siginfo_t))) {
|
||||||
|
rc = -EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock(savelock, irqstate);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(ptrace)
|
SYSCALL_DECLARE(ptrace)
|
||||||
{
|
{
|
||||||
const long request = (long)ihk_mc_syscall_arg0(ctx);
|
const long request = (long)ihk_mc_syscall_arg0(ctx);
|
||||||
@@ -3269,9 +3340,11 @@ SYSCALL_DECLARE(ptrace)
|
|||||||
break;
|
break;
|
||||||
case PTRACE_GETSIGINFO:
|
case PTRACE_GETSIGINFO:
|
||||||
dkprintf("ptrace: unimplemented ptrace(PTRACE_GETSIGINFO) called.\n");
|
dkprintf("ptrace: unimplemented ptrace(PTRACE_GETSIGINFO) called.\n");
|
||||||
|
error = ptrace_getsiginfo(pid, (siginfo_t *)data);
|
||||||
break;
|
break;
|
||||||
case PTRACE_SETSIGINFO:
|
case PTRACE_SETSIGINFO:
|
||||||
dkprintf("ptrace: unimplemented ptrace(PTRACE_SETSIGINFO) called.\n");
|
dkprintf("ptrace: unimplemented ptrace(PTRACE_SETSIGINFO) called.\n");
|
||||||
|
error = ptrace_setsiginfo(pid, (siginfo_t *)data);
|
||||||
break;
|
break;
|
||||||
case PTRACE_GETREGSET:
|
case PTRACE_GETREGSET:
|
||||||
dkprintf("ptrace: unimplemented ptrace(PTRACE_GETREGSET) called.\n");
|
dkprintf("ptrace: unimplemented ptrace(PTRACE_GETREGSET) called.\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user