Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm:
[ARM] 3507/1: Replace map_desc.physical with map_desc.pfn: aaed2000
[ARM] 3506/1: aaec2000: debug-macro.S needs hardware.h
[ARM] 3505/1: aaec2000: entry-macro.S needs asm/arch/irqs.h
[ARM] 3504/1: Fix clcd includes for aaec2000
[ARM] 3503/1: Fix map_desc structure for aaec2000
[ARM] 3501/1: i.MX: fix lowlevel debug macros
[ARM] rtc-sa1100: fix compiler warnings and error cleanup
[ARM] Allow SA1100 RTC alarm to be configured for wakeup
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 4e0f0ec..b0f8da8 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -148,12 +148,16 @@
int ptrace_attach(struct task_struct *task)
{
int retval;
- task_lock(task);
+
retval = -EPERM;
if (task->pid <= 1)
- goto bad;
+ goto out;
if (task->tgid == current->tgid)
- goto bad;
+ goto out;
+
+ write_lock_irq(&tasklist_lock);
+ task_lock(task);
+
/* the same process cannot be attached many times */
if (task->ptrace & PT_PTRACED)
goto bad;
@@ -166,17 +170,15 @@
? 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:
+ write_unlock_irq(&tasklist_lock);
task_unlock(task);
+out:
return retval;
}
@@ -417,21 +419,22 @@
*/
int ptrace_traceme(void)
{
- int ret;
+ int ret = -EPERM;
/*
* Are we already being traced?
*/
- if (current->ptrace & PT_PTRACED)
- return -EPERM;
- ret = security_ptrace(current->parent, current);
- if (ret)
- return -EPERM;
- /*
- * Set the ptrace bit in the process ptrace flags.
- */
- current->ptrace |= PT_PTRACED;
- return 0;
+ task_lock(current);
+ if (!(current->ptrace & PT_PTRACED)) {
+ ret = security_ptrace(current->parent, current);
+ /*
+ * Set the ptrace bit in the process ptrace flags.
+ */
+ if (!ret)
+ current->ptrace |= PT_PTRACED;
+ }
+ task_unlock(current);
+ return ret;
}
/**