[patch] ac18: locking in sys_ptrace() on alpha

From: Ivan Kokshaysky (ink@jurassic.park.msu.ru)
Date: Wed Jun 14 2000 - 07:14:27 EST


On Tue, Jun 13, 2000 at 06:51:19PM +0200, Manfred Spraul wrote:
> Could you also add get_task_struct() as on i386? Otherwise the task may
> disappear immediately after find_task_by_pid().
> Hmm read_lock(&tasklist_lock) is also missing ;)
>
OK, here is the diff.

Ivan.

--- 2.4.0t1ac18/arch/alpha/kernel/ptrace.c Wed Jun 14 12:07:57 2000
+++ linux/arch/alpha/kernel/ptrace.c Wed Jun 14 12:50:29 2000
@@ -247,17 +247,22 @@
         if (request == PTRACE_TRACEME) {
                 /* are we already being traced? */
                 if (current->ptrace & PT_PTRACED)
- goto out;
+ goto out_notsk;
                 /* set the ptrace bit in the process ptrace flags. */
                 current->ptrace |= PT_PTRACED;
                 ret = 0;
- goto out;
+ goto out_notsk;
         }
         if (pid == 1) /* you may not mess with init */
- goto out;
+ goto out_notsk;
         ret = -ESRCH;
- if (!(child = find_task_by_pid(pid)))
- goto out;
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
+ if (!child)
+ goto out_notsk;
         if (request == PTRACE_ATTACH) {
                 ret = -EPERM;
                 if (child == current)
@@ -276,11 +281,13 @@
                 if (child->ptrace & PT_PTRACED)
                         goto out;
                 child->ptrace |= PT_PTRACED;
+ write_lock_irq(&tasklist_lock);
                 if (child->p_pptr != current) {
                         REMOVE_LINKS(child);
                         child->p_pptr = current;
                         SET_LINKS(child);
                 }
+ write_unlock_irq(&tasklist_lock);
                 send_sig(SIGSTOP, child, 1);
                 ret = 0;
                 goto out;
@@ -387,9 +394,11 @@
                 child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
                 wake_up_process(child);
                 child->exit_code = data;
+ write_lock_irq(&tasklist_lock);
                 REMOVE_LINKS(child);
                 child->p_pptr = child->p_opptr;
                 SET_LINKS(child);
+ write_unlock_irq(&tasklist_lock);
                 /* make sure single-step breakpoint is gone. */
                 ptrace_cancel_bpt(child);
                 ret = 0;
@@ -400,6 +409,8 @@
                 goto out;
         }
  out:
+ free_task_struct(child);
+ out_notsk:
         unlock_kernel();
         return ret;
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Jun 15 2000 - 21:00:31 EST