Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 256842
b: refs/heads/master
c: fca26f2
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo authored and Oleg Nesterov committed Jun 16, 2011
1 parent ffaeb1b commit b8ed34c
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3544d72a0e10d0aa1c1bd59ed77a53a59cdc12f7
refs/heads/master: fca26f260c528ee51a2e451b5b200aeb528f3e09
1 change: 1 addition & 0 deletions trunk/include/linux/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define PTRACE_SETREGSET 0x4205

#define PTRACE_SEIZE 0x4206
#define PTRACE_INTERRUPT 0x4207

/* flags in @data for PTRACE_SEIZE */
#define PTRACE_SEIZE_DEVEL 0x80000000 /* temp flag for development */
Expand Down
29 changes: 27 additions & 2 deletions trunk/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,10 +658,12 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
int ptrace_request(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
bool seized = child->ptrace & PT_SEIZED;
int ret = -EIO;
siginfo_t siginfo;
void __user *datavp = (void __user *) data;
unsigned long __user *datalp = datavp;
unsigned long flags;

switch (request) {
case PTRACE_PEEKTEXT:
Expand Down Expand Up @@ -694,6 +696,27 @@ int ptrace_request(struct task_struct *child, long request,
ret = ptrace_setsiginfo(child, &siginfo);
break;

case PTRACE_INTERRUPT:
/*
* Stop tracee without any side-effect on signal or job
* control. At least one trap is guaranteed to happen
* after this request. If @child is already trapped, the
* current trap is not disturbed and another trap will
* happen after the current trap is ended with PTRACE_CONT.
*
* The actual trap might not be PTRACE_EVENT_STOP trap but
* the pending condition is cleared regardless.
*/
if (unlikely(!seized || !lock_task_sighand(child, &flags)))
break;

if (likely(task_set_jobctl_pending(child, JOBCTL_TRAP_STOP)))
signal_wake_up(child, 0);

unlock_task_sighand(child, &flags);
ret = 0;
break;

case PTRACE_DETACH: /* detach a process that was attached. */
ret = ptrace_detach(child, data);
break;
Expand Down Expand Up @@ -819,7 +842,8 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
goto out_put_task_struct;
}

ret = ptrace_check_attach(child, request == PTRACE_KILL);
ret = ptrace_check_attach(child, request == PTRACE_KILL ||
request == PTRACE_INTERRUPT);
if (ret < 0)
goto out_put_task_struct;

Expand Down Expand Up @@ -961,7 +985,8 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
goto out_put_task_struct;
}

ret = ptrace_check_attach(child, request == PTRACE_KILL);
ret = ptrace_check_attach(child, request == PTRACE_KILL ||
request == PTRACE_INTERRUPT);
if (!ret)
ret = compat_arch_ptrace(child, request, addr, data);

Expand Down

0 comments on commit b8ed34c

Please sign in to comment.