]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.27 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Fri, 13 Aug 2010 21:42:26 +0000 (14:42 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 13 Aug 2010 21:42:26 +0000 (14:42 -0700)
queue-2.6.27/mm-fix-missing-page-table-unmap-for-stack-guard-page-failure-case.patch [new file with mode: 0644]
queue-2.6.27/mm-keep-a-guard-page-below-a-grow-down-stack-segment.patch [new file with mode: 0644]
queue-2.6.27/series [new file with mode: 0644]
queue-2.6.27/x86-don-t-send-sigbus-for-kernel-page-faults.patch [new file with mode: 0644]

diff --git a/queue-2.6.27/mm-fix-missing-page-table-unmap-for-stack-guard-page-failure-case.patch b/queue-2.6.27/mm-fix-missing-page-table-unmap-for-stack-guard-page-failure-case.patch
new file mode 100644 (file)
index 0000000..7776a34
--- /dev/null
@@ -0,0 +1,34 @@
+From 5528f9132cf65d4d892bcbc5684c61e7822b21e9 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 13 Aug 2010 09:24:04 -0700
+Subject: mm: fix missing page table unmap for stack guard page failure case
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 5528f9132cf65d4d892bcbc5684c61e7822b21e9 upstream.
+
+.. which didn't show up in my tests because it's a no-op on x86-64 and
+most other architectures.  But we enter the function with the last-level
+page table mapped, and should unmap it at exit.
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/memory.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2428,8 +2428,10 @@ static int do_anonymous_page(struct mm_s
+       spinlock_t *ptl;
+       pte_t entry;
+-      if (check_stack_guard_page(vma, address) < 0)
++      if (check_stack_guard_page(vma, address) < 0) {
++              pte_unmap(page_table);
+               return VM_FAULT_SIGBUS;
++      }
+       /* Allocate our own private page. */
+       pte_unmap(page_table);
diff --git a/queue-2.6.27/mm-keep-a-guard-page-below-a-grow-down-stack-segment.patch b/queue-2.6.27/mm-keep-a-guard-page-below-a-grow-down-stack-segment.patch
new file mode 100644 (file)
index 0000000..c3fd2aa
--- /dev/null
@@ -0,0 +1,72 @@
+From 320b2b8de12698082609ebbc1a17165727f4c893 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Thu, 12 Aug 2010 17:54:33 -0700
+Subject: mm: keep a guard page below a grow-down stack segment
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 320b2b8de12698082609ebbc1a17165727f4c893 upstream.
+
+This is a rather minimally invasive patch to solve the problem of the
+user stack growing into a memory mapped area below it.  Whenever we fill
+the first page of the stack segment, expand the segment down by one
+page.
+
+Now, admittedly some odd application might _want_ the stack to grow down
+into the preceding memory mapping, and so we may at some point need to
+make this a process tunable (some people might also want to have more
+than a single page of guarding), but let's try the minimal approach
+first.
+
+Tested with trivial application that maps a single page just below the
+stack, and then starts recursing.  Without this, we will get a SIGSEGV
+_after_ the stack has smashed the mapping.  With this patch, we'll get a
+nice SIGBUS just as the stack touches the page just above the mapping.
+
+Requested-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/memory.c |   23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2396,6 +2396,26 @@ out_nomap:
+ }
+ /*
++ * This is like a special single-page "expand_downwards()",
++ * except we must first make sure that 'address-PAGE_SIZE'
++ * doesn't hit another vma.
++ *
++ * The "find_vma()" will do the right thing even if we wrap
++ */
++static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
++{
++      address &= PAGE_MASK;
++      if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
++              address -= PAGE_SIZE;
++              if (find_vma(vma->vm_mm, address) != vma)
++                      return -ENOMEM;
++
++              expand_stack(vma, address);
++      }
++      return 0;
++}
++
++/*
+  * We enter with non-exclusive mmap_sem (to exclude vma changes,
+  * but allow concurrent faults), and pte mapped but not yet locked.
+  * We return with mmap_sem still held, but pte unmapped and unlocked.
+@@ -2408,6 +2428,9 @@ static int do_anonymous_page(struct mm_s
+       spinlock_t *ptl;
+       pte_t entry;
++      if (check_stack_guard_page(vma, address) < 0)
++              return VM_FAULT_SIGBUS;
++
+       /* Allocate our own private page. */
+       pte_unmap(page_table);
diff --git a/queue-2.6.27/series b/queue-2.6.27/series
new file mode 100644 (file)
index 0000000..17f3100
--- /dev/null
@@ -0,0 +1,3 @@
+mm-keep-a-guard-page-below-a-grow-down-stack-segment.patch
+mm-fix-missing-page-table-unmap-for-stack-guard-page-failure-case.patch
+x86-don-t-send-sigbus-for-kernel-page-faults.patch
diff --git a/queue-2.6.27/x86-don-t-send-sigbus-for-kernel-page-faults.patch b/queue-2.6.27/x86-don-t-send-sigbus-for-kernel-page-faults.patch
new file mode 100644 (file)
index 0000000..e85c6a9
--- /dev/null
@@ -0,0 +1,61 @@
+From 96054569190bdec375fe824e48ca1f4e3b53dd36 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Date: Fri, 13 Aug 2010 13:46:26 -0700
+Subject: x86: don't send SIGBUS for kernel page faults
+
+Based on commit 96054569190bdec375fe824e48ca1f4e3b53dd36 upstream,
+authored by Linus Torvalds.
+
+This is my backport to the .27 kernel tree, hopefully preserving
+the same functionality.
+
+Original commit message:
+       It's wrong for several reasons, but the most direct one is that the
+       fault may be for the stack accesses to set up a previous SIGBUS.  When
+       we have a kernel exception, the kernel exception handler does all the
+       fixups, not some user-level signal handler.
+
+       Even apart from the nested SIGBUS issue, it's also wrong to give out
+       kernel fault addresses in the signal handler info block, or to send a
+       SIGBUS when a system call already returns EFAULT.
+
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/mm/fault.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/mm/fault.c
++++ b/arch/x86/mm/fault.c
+@@ -589,6 +589,7 @@ void __kprobes do_page_fault(struct pt_r
+       unsigned long address;
+       int write, si_code;
+       int fault;
++      int should_exit_no_context = 0;
+ #ifdef CONFIG_X86_64
+       unsigned long flags;
+ #endif
+@@ -876,6 +877,9 @@ no_context:
+       oops_end(flags, regs, SIGKILL);
+ #endif
++      if (should_exit_no_context)
++              return;
++
+ /*
+  * We ran out of memory, or some other thing happened to us that made
+  * us unable to handle the page fault gracefully.
+@@ -901,8 +905,11 @@ do_sigbus:
+       up_read(&mm->mmap_sem);
+       /* Kernel mode? Handle exceptions or die */
+-      if (!(error_code & PF_USER))
++      if (!(error_code & PF_USER)) {
++              should_exit_no_context = 1;
+               goto no_context;
++      }
++
+ #ifdef CONFIG_X86_32
+       /* User space => ok to do another page fault */
+       if (is_prefetch(regs, address, error_code))