Merge branch 'irq-threaded-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / fs / proc / base.c
index 3326bbf..6f742f6 100644 (file)
@@ -234,23 +234,20 @@ static int check_mem_permission(struct task_struct *task)
 
 struct mm_struct *mm_for_maps(struct task_struct *task)
 {
-       struct mm_struct *mm = get_task_mm(task);
-       if (!mm)
+       struct mm_struct *mm;
+
+       if (mutex_lock_killable(&task->cred_guard_mutex))
                return NULL;
-       down_read(&mm->mmap_sem);
-       task_lock(task);
-       if (task->mm != mm)
-               goto out;
-       if (task->mm != current->mm &&
-           __ptrace_may_access(task, PTRACE_MODE_READ) < 0)
-               goto out;
-       task_unlock(task);
+
+       mm = get_task_mm(task);
+       if (mm && mm != current->mm &&
+                       !ptrace_may_access(task, PTRACE_MODE_READ)) {
+               mmput(mm);
+               mm = NULL;
+       }
+       mutex_unlock(&task->cred_guard_mutex);
+
        return mm;
-out:
-       task_unlock(task);
-       up_read(&mm->mmap_sem);
-       mmput(mm);
-       return NULL;
 }
 
 static int proc_pid_cmdline(struct task_struct *task, char * buffer)
@@ -2128,9 +2125,15 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
        if (copy_from_user(page, buf, count))
                goto out_free;
 
+       /* Guard against adverse ptrace interaction */
+       length = mutex_lock_interruptible(&task->cred_guard_mutex);
+       if (length < 0)
+               goto out_free;
+
        length = security_setprocattr(task,
                                      (char*)file->f_path.dentry->d_name.name,
                                      (void*)page, count);
+       mutex_unlock(&task->cred_guard_mutex);
 out_free:
        free_page((unsigned long) page);
 out: