From: Greg Kroah-Hartman Date: Tue, 11 Aug 2009 21:48:52 +0000 (-0700) Subject: more .30 patches X-Git-Tag: v2.6.30.5~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=34d7c5aa8560e0332cbe10cbdccedb816cdb9925;p=thirdparty%2Fkernel%2Fstable-queue.git more .30 patches --- diff --git a/queue-2.6.30/mm_for_maps-shift-down_read-to-the-caller.patch b/queue-2.6.30/mm_for_maps-shift-down_read-to-the-caller.patch new file mode 100644 index 00000000000..637bd154dab --- /dev/null +++ b/queue-2.6.30/mm_for_maps-shift-down_read-to-the-caller.patch @@ -0,0 +1,70 @@ +From 00f89d218523b9bf6b522349c039d5ac80aa536d Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Fri, 10 Jul 2009 03:27:38 +0200 +Subject: mm_for_maps: shift down_read(mmap_sem) to the caller + +From: Oleg Nesterov + +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 +Acked-by: Serge Hallyn +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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)) diff --git a/queue-2.6.30/mm_for_maps-simplify-use-ptrace_may_access.patch b/queue-2.6.30/mm_for_maps-simplify-use-ptrace_may_access.patch new file mode 100644 index 00000000000..435204239b2 --- /dev/null +++ b/queue-2.6.30/mm_for_maps-simplify-use-ptrace_may_access.patch @@ -0,0 +1,65 @@ +From 13f0feafa6b8aead57a2a328e2fca6a5828bf286 Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Tue, 23 Jun 2009 21:25:32 +0200 +Subject: mm_for_maps: simplify, use ptrace_may_access() + +From: Oleg Nesterov + +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 +Reviewed-by: Serge Hallyn +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-2.6.30/mm_for_maps-take-cred_guard_mutex-to-fix-the-race-with-exec.patch b/queue-2.6.30/mm_for_maps-take-cred_guard_mutex-to-fix-the-race-with-exec.patch new file mode 100644 index 00000000000..50265aa3a83 --- /dev/null +++ b/queue-2.6.30/mm_for_maps-take-cred_guard_mutex-to-fix-the-race-with-exec.patch @@ -0,0 +1,61 @@ +From 704b836cbf19e885f8366bccb2e4b0474346c02d Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +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 + +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 +Acked-by: Serge Hallyn +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-2.6.30/series b/queue-2.6.30/series index 2f304d132cc..d1ba2416941 100644 --- a/queue-2.6.30/series +++ b/queue-2.6.30/series @@ -64,3 +64,6 @@ usb-usbfs-fix-enoent-error-code-to-be-enodev.patch 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