From: Greg Kroah-Hartman Date: Fri, 13 Aug 2010 21:42:26 +0000 (-0700) Subject: .27 patches X-Git-Tag: v2.6.27.52~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7ee461ae5459c0b18ec43661e244fe3e3c0ab07a;p=thirdparty%2Fkernel%2Fstable-queue.git .27 patches --- 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 index 00000000000..7776a349feb --- /dev/null +++ b/queue-2.6.27/mm-fix-missing-page-table-unmap-for-stack-guard-page-failure-case.patch @@ -0,0 +1,34 @@ +From 5528f9132cf65d4d892bcbc5684c61e7822b21e9 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c3fd2aa197c --- /dev/null +++ b/queue-2.6.27/mm-keep-a-guard-page-below-a-grow-down-stack-segment.patch @@ -0,0 +1,72 @@ +From 320b2b8de12698082609ebbc1a17165727f4c893 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Thu, 12 Aug 2010 17:54:33 -0700 +Subject: mm: keep a guard page below a grow-down stack segment + +From: Linus Torvalds + +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..17f31002693 --- /dev/null +++ b/queue-2.6.27/series @@ -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 index 00000000000..e85c6a9f5c0 --- /dev/null +++ b/queue-2.6.27/x86-don-t-send-sigbus-for-kernel-page-faults.patch @@ -0,0 +1,61 @@ +From 96054569190bdec375fe824e48ca1f4e3b53dd36 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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))