Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 256841
b: refs/heads/master
c: 3544d72
h: refs/heads/master
i:
  256839: f4f0f8a
v: v3
  • Loading branch information
Tejun Heo authored and Oleg Nesterov committed Jun 16, 2011
1 parent bbad3a6 commit ffaeb1b
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 16 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: 73ddff2bee159ffb580bd24faf625cd5e628f5ec
refs/heads/master: 3544d72a0e10d0aa1c1bd59ed77a53a59cdc12f7
7 changes: 7 additions & 0 deletions trunk/include/linux/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
#define PTRACE_GETREGSET 0x4204
#define PTRACE_SETREGSET 0x4205

#define PTRACE_SEIZE 0x4206

/* flags in @data for PTRACE_SEIZE */
#define PTRACE_SEIZE_DEVEL 0x80000000 /* temp flag for development */

/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#define PTRACE_O_TRACEFORK 0x00000002
Expand All @@ -65,6 +70,7 @@
#define PTRACE_EVENT_EXEC 4
#define PTRACE_EVENT_VFORK_DONE 5
#define PTRACE_EVENT_EXIT 6
#define PTRACE_EVENT_STOP 7

#include <asm/ptrace.h>

Expand All @@ -77,6 +83,7 @@
* flags. When the a task is stopped the ptracer owns task->ptrace.
*/

#define PT_SEIZED 0x00010000 /* SEIZE used, enable new behavior */
#define PT_PTRACED 0x00000001
#define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */
#define PT_TRACESYSGOOD 0x00000004
Expand Down
35 changes: 29 additions & 6 deletions trunk/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,28 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
return !err;
}

static int ptrace_attach(struct task_struct *task)
static int ptrace_attach(struct task_struct *task, long request,
unsigned long flags)
{
bool seize = (request == PTRACE_SEIZE);
int retval;

/*
* SEIZE will enable new ptrace behaviors which will be implemented
* gradually. SEIZE_DEVEL is used to prevent applications
* expecting full SEIZE behaviors trapping on kernel commits which
* are still in the process of implementing them.
*
* Only test programs for new ptrace behaviors being implemented
* should set SEIZE_DEVEL. If unset, SEIZE will fail with -EIO.
*
* Once SEIZE behaviors are completely implemented, this flag and
* the following test will be removed.
*/
retval = -EIO;
if (seize && !(flags & PTRACE_SEIZE_DEVEL))
goto out;

audit_ptrace(task);

retval = -EPERM;
Expand Down Expand Up @@ -244,11 +262,16 @@ static int ptrace_attach(struct task_struct *task)
goto unlock_tasklist;

task->ptrace = PT_PTRACED;
if (seize)
task->ptrace |= PT_SEIZED;
if (task_ns_capable(task, CAP_SYS_PTRACE))
task->ptrace |= PT_PTRACE_CAP;

__ptrace_link(task, current);
send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);

/* SEIZE doesn't trap tracee on attach */
if (!seize)
send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);

spin_lock(&task->sighand->siglock);

Expand Down Expand Up @@ -785,8 +808,8 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
goto out;
}

if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
ret = ptrace_attach(child, request, data);
/*
* Some architectures need to do book-keeping after
* a ptrace attach.
Expand Down Expand Up @@ -927,8 +950,8 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
goto out;
}

if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
ret = ptrace_attach(child, request, data);
/*
* Some architectures need to do book-keeping after
* a ptrace attach.
Expand Down
39 changes: 30 additions & 9 deletions trunk/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1873,21 +1873,26 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
recalc_sigpending_tsk(current);
}

void ptrace_notify(int exit_code)
static void ptrace_do_notify(int signr, int exit_code, int why)
{
siginfo_t info;

BUG_ON((exit_code & (0x7f | ~0xffff)) != SIGTRAP);

memset(&info, 0, sizeof info);
info.si_signo = SIGTRAP;
info.si_signo = signr;
info.si_code = exit_code;
info.si_pid = task_pid_vnr(current);
info.si_uid = current_uid();

/* Let the debugger run. */
ptrace_stop(exit_code, why, 1, &info);
}

void ptrace_notify(int exit_code)
{
BUG_ON((exit_code & (0x7f | ~0xffff)) != SIGTRAP);

spin_lock_irq(&current->sighand->siglock);
ptrace_stop(exit_code, CLD_TRAPPED, 1, &info);
ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED);
spin_unlock_irq(&current->sighand->siglock);
}

Expand Down Expand Up @@ -2017,19 +2022,35 @@ static bool do_signal_stop(int signr)
/**
* do_jobctl_trap - take care of ptrace jobctl traps
*
* It is currently used only to trap for group stop while ptraced.
* When PT_SEIZED, it's used for both group stop and explicit
* SEIZE/INTERRUPT traps. Both generate PTRACE_EVENT_STOP trap with
* accompanying siginfo. If stopped, lower eight bits of exit_code contain
* the stop signal; otherwise, %SIGTRAP.
*
* When !PT_SEIZED, it's used only for group stop trap with stop signal
* number as exit_code and no siginfo.
*
* CONTEXT:
* Must be called with @current->sighand->siglock held, which may be
* released and re-acquired before returning with intervening sleep.
*/
static void do_jobctl_trap(void)
{
struct signal_struct *signal = current->signal;
int signr = current->jobctl & JOBCTL_STOP_SIGMASK;

WARN_ON_ONCE(!signr);
ptrace_stop(signr, CLD_STOPPED, 0, NULL);
current->exit_code = 0;
if (current->ptrace & PT_SEIZED) {
if (!signal->group_stop_count &&
!(signal->flags & SIGNAL_STOP_STOPPED))
signr = SIGTRAP;
WARN_ON_ONCE(!signr);
ptrace_do_notify(signr, signr | (PTRACE_EVENT_STOP << 8),
CLD_STOPPED);
} else {
WARN_ON_ONCE(!signr);
ptrace_stop(signr, CLD_STOPPED, 0, NULL);
current->exit_code = 0;
}
}

static int ptrace_signal(int signr, siginfo_t *info,
Expand Down

0 comments on commit ffaeb1b

Please sign in to comment.