static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
 {
-       pid_t pgrp;
+       struct pid *pgrp;
+       pid_t pgrp_nr;
        int retval = tty_check_change(real_tty);
 
        if (retval == -EIO)
            (current->signal->tty != real_tty) ||
            (real_tty->session != process_session(current)))
                return -ENOTTY;
-       if (get_user(pgrp, p))
+       if (get_user(pgrp_nr, p))
                return -EFAULT;
-       if (pgrp < 0)
+       if (pgrp_nr < 0)
                return -EINVAL;
-       if (session_of_pgrp(pgrp) != process_session(current))
-               return -EPERM;
-       real_tty->pgrp = pgrp;
-       return 0;
+       rcu_read_lock();
+       pgrp = find_pid(pgrp_nr);
+       retval = -ESRCH;
+       if (!pgrp)
+               goto out_unlock;
+       retval = -EPERM;
+       if (session_of_pgrp(pgrp) != task_session(current))
+               goto out_unlock;
+       retval = 0;
+       real_tty->pgrp = pgrp_nr;
+out_unlock:
+       rcu_read_unlock();
+       return retval;
 }
 
 /**
 
 extern int core_kernel_text(unsigned long addr);
 extern int __kernel_text_address(unsigned long addr);
 extern int kernel_text_address(unsigned long addr);
-extern int session_of_pgrp(int pgrp);
+struct pid;
+extern struct pid *session_of_pgrp(struct pid *pgrp);
 
 extern void dump_thread(struct pt_regs *regs, struct user *dump);
 
 
  * This checks not only the pgrp, but falls back on the pid if no
  * satisfactory pgrp is found. I dunno - gdb doesn't work correctly
  * without this...
+ *
+ * The caller must hold rcu lock or the tasklist lock.
  */
-int session_of_pgrp(int pgrp)
+struct pid *session_of_pgrp(struct pid *pgrp)
 {
        struct task_struct *p;
-       int sid = 0;
-
-       read_lock(&tasklist_lock);
+       struct pid *sid = NULL;
 
-       p = find_task_by_pid_type(PIDTYPE_PGID, pgrp);
+       p = pid_task(pgrp, PIDTYPE_PGID);
        if (p == NULL)
-               p = find_task_by_pid(pgrp);
+               p = pid_task(pgrp, PIDTYPE_PID);
        if (p != NULL)
-               sid = process_session(p);
-
-       read_unlock(&tasklist_lock);
+               sid = task_session(p);
 
        return sid;
 }