Ejemplo n.º 1
0
int ptrace_attach(struct task_struct *task)
{
	int retval;
	task_lock(task);
	retval = -EPERM;
	if (task->pid <= 1)
		goto bad;
	if (task->tgid == current->tgid)
		goto bad;
	/* the same process cannot be attached many times */
	if (task->ptrace & PT_PTRACED)
		goto bad;
	retval = may_attach(task);
	if (retval)
		goto bad;

	/* Go */
	task->ptrace |= PT_PTRACED | ((task->real_parent != current)
				      ? PT_ATTACHED : 0);
	if (capable(CAP_SYS_PTRACE))
		task->ptrace |= PT_PTRACE_CAP;
	task_unlock(task);

	write_lock_irq(&tasklist_lock);
	__ptrace_link(task, current);
	write_unlock_irq(&tasklist_lock);

	force_sig_specific(SIGSTOP, task);
	return 0;

bad:
	task_unlock(task);
	return retval;
}
Ejemplo n.º 2
0
int ptrace_attach(struct task_struct *task)
{
	int retval;

	audit_ptrace(task);

	retval = -EPERM;
	if (task->pid <= 1)
		goto out;
	if (task->tgid == current->tgid)
		goto out;

repeat:
	/*
	 * Nasty, nasty.
	 *
	 * We want to hold both the task-lock and the
	 * tasklist_lock for writing at the same time.
	 * But that's against the rules (tasklist_lock
	 * is taken for reading by interrupts on other
	 * cpu's that may have task_lock).
	 */
	task_lock(task);
	local_irq_disable();
	if (!write_trylock(&tasklist_lock)) {
		local_irq_enable();
		task_unlock(task);
		do {
			cpu_relax();
		} while (!write_can_lock(&tasklist_lock));
		goto repeat;
	}

	if (!task->mm)
		goto bad;
	/* the same process cannot be attached many times */
	if (task->ptrace & PT_PTRACED)
		goto bad;
	retval = may_attach(task);
	if (retval)
		goto bad;

	/* Go */
	task->ptrace |= PT_PTRACED | ((task->real_parent != current)
				      ? PT_ATTACHED : 0);
	if (capable(CAP_SYS_PTRACE))
		task->ptrace |= PT_PTRACE_CAP;

	__ptrace_link(task, current);

	force_sig_specific(SIGSTOP, task);

bad:
	write_unlock_irq(&tasklist_lock);
	task_unlock(task);
out:
	return retval;
}
Ejemplo n.º 3
0
static inline void freeze_process(struct task_struct *p)
{
	unsigned long flags;

	if (!freezing(p)) {
		rmb();
		if (!frozen(p)) {
			if (p->state == TASK_STOPPED)
				force_sig_specific(SIGSTOP, p);

			freeze(p);
			spin_lock_irqsave(&p->sighand->siglock, flags);
			signal_wake_up(p, p->state == TASK_STOPPED);
			spin_unlock_irqrestore(&p->sighand->siglock, flags);
		}
	}
}
Ejemplo n.º 4
0
int ptrace_attach(struct task_struct *task)
{
   int retval;
   task_lock(task);
   retval = -EPERM;
   if (task->pid <= 1)
      goto bad;
   if (task == current)
      goto bad;
   if (!task->mm)
      goto bad;
   if(((current->uid != task->euid) ||
       (current->uid != task->suid) ||
       (current->uid != task->uid) ||
       (current->gid != task->egid) ||
       (current->gid != task->sgid) ||
       (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
      goto bad;
   rmb();
   if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
      goto bad;
   /* the same process cannot be attached many times */
   if (task->ptrace & PT_PTRACED)
      goto bad;
   retval = security_ptrace(current, task);
   if (retval)
      goto bad;

   /* Go */
   task->ptrace |= PT_PTRACED;
   if (capable(CAP_SYS_PTRACE))
      task->ptrace |= PT_PTRACE_CAP;
   task_unlock(task);

   write_lock_irq(&tasklist_lock);
   __ptrace_link(task, current);
   write_unlock_irq(&tasklist_lock);

   force_sig_specific(SIGSTOP, task);
   return 0;

bad:
   task_unlock(task);
   return retval;
}
Ejemplo n.º 5
0
static void send_fake_signal(struct task_struct *p)
{
	if (p->state == TASK_STOPPED)
		force_sig_specific(SIGSTOP, p);
	fake_signal_wake_up(p, p->state == TASK_STOPPED);
}