--- /dev/null
+From 00f89d218523b9bf6b522349c039d5ac80aa536d Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Fri, 10 Jul 2009 03:27:38 +0200
+Subject: mm_for_maps: shift down_read(mmap_sem) to the caller
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 00f89d218523b9bf6b522349c039d5ac80aa536d upstream.
+
+mm_for_maps() takes ->mmap_sem after security checks, this looks
+strange and obfuscates the locking rules. Move this lock to its
+single caller, m_start().
+
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Serge Hallyn <serue@us.ibm.com>
+Signed-off-by: James Morris <jmorris@namei.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/proc/base.c | 8 +++-----
+ fs/proc/task_mmu.c | 1 +
+ fs/proc/task_nommu.c | 1 +
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -235,9 +235,8 @@ static int check_mem_permission(struct t
+ struct mm_struct *mm_for_maps(struct task_struct *task)
+ {
+ struct mm_struct *mm = get_task_mm(task);
+- if (!mm)
+- return NULL;
+- if (mm != current->mm) {
++
++ if (mm && mm != current->mm) {
+ /*
+ * task->mm can be changed before security check,
+ * in that case we must notice the change after.
+@@ -245,10 +244,9 @@ struct mm_struct *mm_for_maps(struct tas
+ if (!ptrace_may_access(task, PTRACE_MODE_READ) ||
+ mm != task->mm) {
+ mmput(mm);
+- return NULL;
++ mm = NULL;
+ }
+ }
+- down_read(&mm->mmap_sem);
+ return mm;
+ }
+
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -119,6 +119,7 @@ static void *m_start(struct seq_file *m,
+ mm = mm_for_maps(priv->task);
+ if (!mm)
+ return NULL;
++ down_read(&mm->mmap_sem);
+
+ tail_vma = get_gate_vma(priv->task);
+ priv->tail_vma = tail_vma;
+--- a/fs/proc/task_nommu.c
++++ b/fs/proc/task_nommu.c
+@@ -189,6 +189,7 @@ static void *m_start(struct seq_file *m,
+ priv->task = NULL;
+ return NULL;
+ }
++ down_read(&mm->mmap_sem);
+
+ /* start from the Nth VMA */
+ for (p = rb_first(&mm->mm_rb); p; p = rb_next(p))
--- /dev/null
+From 13f0feafa6b8aead57a2a328e2fca6a5828bf286 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Tue, 23 Jun 2009 21:25:32 +0200
+Subject: mm_for_maps: simplify, use ptrace_may_access()
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 13f0feafa6b8aead57a2a328e2fca6a5828bf286 upstream.
+
+It would be nice to kill __ptrace_may_access(). It requires task_lock(),
+but this lock is only needed to read mm->flags in the middle.
+
+Convert mm_for_maps() to use ptrace_may_access(), this also simplifies
+the code a little bit.
+
+Also, we do not need to take ->mmap_sem in advance. In fact I think
+mm_for_maps() should not play with ->mmap_sem at all, the caller should
+take this lock.
+
+With or without this patch, without ->cred_guard_mutex held we can race
+with exec() and get the new ->mm but check old creds.
+
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reviewed-by: Serge Hallyn <serue@us.ibm.com>
+Signed-off-by: James Morris <jmorris@namei.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/proc/base.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -237,20 +237,19 @@ struct mm_struct *mm_for_maps(struct tas
+ struct mm_struct *mm = get_task_mm(task);
+ if (!mm)
+ return NULL;
++ if (mm != current->mm) {
++ /*
++ * task->mm can be changed before security check,
++ * in that case we must notice the change after.
++ */
++ if (!ptrace_may_access(task, PTRACE_MODE_READ) ||
++ mm != task->mm) {
++ mmput(mm);
++ 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);
+ 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)
--- /dev/null
+From 704b836cbf19e885f8366bccb2e4b0474346c02d Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Fri, 10 Jul 2009 03:27:40 +0200
+Subject: mm_for_maps: take ->cred_guard_mutex to fix the race with exec
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 704b836cbf19e885f8366bccb2e4b0474346c02d upstream.
+
+The problem is minor, but without ->cred_guard_mutex held we can race
+with exec() and get the new ->mm but check old creds.
+
+Now we do not need to re-check task->mm after ptrace_may_access(), it
+can't be changed to the new mm under us.
+
+Strictly speaking, this also fixes another very minor problem. Unless
+security check fails or the task exits mm_for_maps() should never
+return NULL, the caller should get either old or new ->mm.
+
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Serge Hallyn <serue@us.ibm.com>
+Signed-off-by: James Morris <jmorris@namei.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/proc/base.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -234,19 +234,19 @@ static int check_mem_permission(struct t
+
+ struct mm_struct *mm_for_maps(struct task_struct *task)
+ {
+- struct mm_struct *mm = get_task_mm(task);
++ struct mm_struct *mm;
+
+- if (mm && mm != current->mm) {
+- /*
+- * task->mm can be changed before security check,
+- * in that case we must notice the change after.
+- */
+- if (!ptrace_may_access(task, PTRACE_MODE_READ) ||
+- mm != task->mm) {
+- mmput(mm);
+- mm = NULL;
+- }
++ if (mutex_lock_killable(&task->cred_exec_mutex))
++ return NULL;
++
++ 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_exec_mutex);
++
+ return mm;
+ }
+
usb-devio-properly-do-access_ok-checks.patch
ring-buffer-fix-memleak-in-ring_buffer_free.patch
x86-fix-vmi-stack-protector.patch
+mm_for_maps-simplify-use-ptrace_may_access.patch
+mm_for_maps-shift-down_read-to-the-caller.patch
+mm_for_maps-take-cred_guard_mutex-to-fix-the-race-with-exec.patch