]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.39/patches.suse/silent-stack-overflow
Updated kernel (2.6.27.41).
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / silent-stack-overflow
diff --git a/src/patches/suse-2.6.27.39/patches.suse/silent-stack-overflow b/src/patches/suse-2.6.27.39/patches.suse/silent-stack-overflow
deleted file mode 100644 (file)
index fec8030..0000000
+++ /dev/null
@@ -1,466 +0,0 @@
-From: Andrea Arcangeli <andrea@suse.de>
-Subject: avoid silent stack overflow over the heap
-Patch-mainline: no
-References: bnc#44807 bnc#211997
-
-x
-
-Signed-off-by: Andrea Arcangeli <andrea@suse.de>
-Updated-by: Jeff Mahoney <jeffm@suse.com>
----
-
- arch/alpha/mm/fault.c                   |    2 -
- arch/arm/mm/fault.c                     |    2 -
- arch/cris/mm/fault.c                    |    2 -
- arch/frv/mm/fault.c                     |    2 -
- arch/ia64/mm/fault.c                    |    2 -
- arch/m32r/mm/fault.c                    |    2 -
- arch/m68k/mm/fault.c                    |    2 -
- arch/mips/mm/fault.c                    |    2 -
- arch/parisc/mm/fault.c                  |    2 -
- arch/powerpc/mm/fault.c                 |    5 ++-
- arch/powerpc/platforms/cell/spu_fault.c |    2 -
- arch/s390/mm/fault.c                    |    2 -
- arch/sh/mm/fault_32.c                   |    2 -
- arch/sh/mm/tlbflush_64.c                |    2 -
- arch/sparc/mm/fault.c                   |    4 +--
- arch/sparc64/mm/fault.c                 |    2 -
- arch/um/kernel/trap.c                   |    9 ++++--
- arch/x86/kernel/sys_x86_64.c            |   10 ++++++-
- arch/x86/mm/fault.c                     |   10 ++++++-
- arch/xtensa/mm/fault.c                  |    2 -
- include/linux/mm.h                      |    5 +++
- kernel/sysctl.c                         |    8 ++++++
- mm/mmap.c                               |   42 +++++++++++++++++++++++++-------
- 23 files changed, 88 insertions(+), 35 deletions(-)
-
---- a/arch/alpha/mm/fault.c
-+++ b/arch/alpha/mm/fault.c
-@@ -123,7 +123,7 @@ do_page_fault(unsigned long address, uns
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL))
-               goto bad_area;
-       /* Ok, we have a good vm_area for this memory access, so
---- a/arch/arm/mm/fault.c
-+++ b/arch/arm/mm/fault.c
-@@ -233,7 +233,7 @@ out_of_memory:
-       goto survive;
- check_stack:
--      if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
-+      if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr, NULL))
-               goto good_area;
- out:
-       return fault;
---- a/arch/cris/mm/fault.c
-+++ b/arch/cris/mm/fault.c
-@@ -133,7 +133,7 @@ do_page_fault(unsigned long address, str
-               if (address + PAGE_SIZE < rdusp())
-                       goto bad_area;
-       }
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL))
-               goto bad_area;
-       /*
---- a/arch/frv/mm/fault.c
-+++ b/arch/frv/mm/fault.c
-@@ -121,7 +121,7 @@ asmlinkage void do_page_fault(int datamm
-               }
-       }
--      if (expand_stack(vma, ear0))
-+      if (expand_stack(vma, ear0, NULL))
-               goto bad_area;
- /*
---- a/arch/ia64/mm/fault.c
-+++ b/arch/ia64/mm/fault.c
-@@ -185,7 +185,7 @@ ia64_do_page_fault (unsigned long addres
-               if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
-                   || REGION_OFFSET(address) >= RGN_MAP_LIMIT)
-                       goto bad_area;
--              if (expand_stack(vma, address))
-+              if (expand_stack(vma, address, NULL /* FIXME? */))
-                       goto bad_area;
-       } else {
-               vma = prev_vma;
---- a/arch/m32r/mm/fault.c
-+++ b/arch/m32r/mm/fault.c
-@@ -159,7 +159,7 @@ asmlinkage void do_page_fault(struct pt_
-                       goto bad_area;
-       }
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL))
-               goto bad_area;
- /*
-  * Ok, we have a good vm_area for this memory access, so
---- a/arch/m68k/mm/fault.c
-+++ b/arch/m68k/mm/fault.c
-@@ -121,7 +121,7 @@ int do_page_fault(struct pt_regs *regs,
-               if (address + 256 < rdusp())
-                       goto map_err;
-       }
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL))
-               goto map_err;
- /*
---- a/arch/mips/mm/fault.c
-+++ b/arch/mips/mm/fault.c
-@@ -80,7 +80,7 @@ asmlinkage void do_page_fault(struct pt_
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL))
-               goto bad_area;
- /*
-  * Ok, we have a good vm_area for this memory access, so
---- a/arch/parisc/mm/fault.c
-+++ b/arch/parisc/mm/fault.c
-@@ -196,7 +196,7 @@ good_area:
- check_expansion:
-       vma = prev_vma;
--      if (vma && (expand_stack(vma, address) == 0))
-+      if (vma && (expand_stack(vma, address, NULL) == 0))
-               goto good_area;
- /*
---- a/arch/powerpc/mm/fault.c
-+++ b/arch/powerpc/mm/fault.c
-@@ -116,7 +116,7 @@ static int store_updates_sp(struct pt_re
- int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
-                           unsigned long error_code)
- {
--      struct vm_area_struct * vma;
-+      struct vm_area_struct * vma, * prev_vma;
-       struct mm_struct *mm = current->mm;
-       siginfo_t info;
-       int code = SEGV_MAPERR;
-@@ -230,7 +230,8 @@ int __kprobes do_page_fault(struct pt_re
-                   && (!user_mode(regs) || !store_updates_sp(regs)))
-                       goto bad_area;
-       }
--      if (expand_stack(vma, address))
-+      find_vma_prev(mm, address, &prev_vma);
-+      if (expand_stack(vma, address, prev_vma))
-               goto bad_area;
- good_area:
---- a/arch/powerpc/platforms/cell/spu_fault.c
-+++ b/arch/powerpc/platforms/cell/spu_fault.c
-@@ -59,7 +59,7 @@ int spu_handle_mm_fault(struct mm_struct
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
--      if (expand_stack(vma, ea))
-+      if (expand_stack(vma, ea, NULL))
-               goto bad_area;
- good_area:
-       is_write = dsisr & MFC_DSISR_ACCESS_PUT;
---- a/arch/s390/mm/fault.c
-+++ b/arch/s390/mm/fault.c
-@@ -350,7 +350,7 @@ do_exception(struct pt_regs *regs, unsig
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL /* FIXME? */))
-               goto bad_area;
- /*
-  * Ok, we have a good vm_area for this memory access, so
---- a/arch/sh/mm/fault_32.c
-+++ b/arch/sh/mm/fault_32.c
-@@ -108,7 +108,7 @@ asmlinkage void __kprobes do_page_fault(
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL))
-               goto bad_area;
- /*
-  * Ok, we have a good vm_area for this memory access, so
---- a/arch/sh/mm/tlbflush_64.c
-+++ b/arch/sh/mm/tlbflush_64.c
-@@ -153,7 +153,7 @@ asmlinkage void do_page_fault(struct pt_
- #endif
-               goto bad_area;
-       }
--      if (expand_stack(vma, address)) {
-+      if (expand_stack(vma, address, NULL)) {
- #ifdef DEBUG_FAULT
-               print_task(tsk);
-               printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n",
---- a/arch/sparc/mm/fault.c
-+++ b/arch/sparc/mm/fault.c
-@@ -219,7 +219,7 @@ asmlinkage void do_sparc_fault(struct pt
-               goto good_area;
-       if(!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
--      if(expand_stack(vma, address))
-+      if(expand_stack(vma, address, NULL))
-               goto bad_area;
-       /*
-        * Ok, we have a good vm_area for this memory access, so
-@@ -472,7 +472,7 @@ static void force_user_fault(unsigned lo
-               goto good_area;
-       if(!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
--      if(expand_stack(vma, address))
-+      if(expand_stack(vma, address, NULL))
-               goto bad_area;
- good_area:
-       info.si_code = SEGV_ACCERR;
---- a/arch/sparc64/mm/fault.c
-+++ b/arch/sparc64/mm/fault.c
-@@ -367,7 +367,7 @@ continue_fault:
-                               goto bad_area;
-               }
-       }
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL))
-               goto bad_area;
-       /*
-        * Ok, we have a good vm_area for this memory access, so
---- a/arch/um/kernel/trap.c
-+++ b/arch/um/kernel/trap.c
-@@ -24,7 +24,7 @@ int handle_page_fault(unsigned long addr
-                     int is_write, int is_user, int *code_out)
- {
-       struct mm_struct *mm = current->mm;
--      struct vm_area_struct *vma;
-+      struct vm_area_struct *vma, *prev_vma;
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-@@ -50,8 +50,11 @@ int handle_page_fault(unsigned long addr
-               goto out;
-       else if (is_user && !ARCH_IS_STACKGROW(address))
-               goto out;
--      else if (expand_stack(vma, address))
--              goto out;
-+      else {
-+              find_vma_prev(mm, address, &prev_vma);
-+              if(expand_stack(vma, address, prev_vma))
-+                      goto out;
-+      }
- good_area:
-       *code_out = SEGV_ACCERR;
---- a/arch/x86/kernel/sys_x86_64.c
-+++ b/arch/x86/kernel/sys_x86_64.c
-@@ -106,6 +106,7 @@ arch_get_unmapped_area(struct file *filp
- full_search:
-       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
-+              unsigned long __heap_stack_gap;
-               /* At this point:  (!vma || addr < vma->vm_end). */
-               if (end - len < addr) {
-                       /*
-@@ -119,7 +120,14 @@ full_search:
-                       }
-                       return -ENOMEM;
-               }
--              if (!vma || addr + len <= vma->vm_start) {
-+              if (!vma)
-+                      goto got_it;
-+              __heap_stack_gap = 0;
-+              if (vma->vm_flags & VM_GROWSDOWN)
-+                      __heap_stack_gap = min(end-(addr+len),
-+                                             (unsigned long) heap_stack_gap << PAGE_SHIFT);
-+              if (addr + len + __heap_stack_gap <= vma->vm_start) {
-+              got_it:
-                       /*
-                        * Remember the place where we stopped the search:
-                        */
---- a/arch/x86/mm/fault.c
-+++ b/arch/x86/mm/fault.c
-@@ -585,7 +585,7 @@ void __kprobes do_page_fault(struct pt_r
- {
-       struct task_struct *tsk;
-       struct mm_struct *mm;
--      struct vm_area_struct *vma;
-+      struct vm_area_struct *vma, *prev_vma;
-       unsigned long address;
-       int write, si_code;
-       int fault;
-@@ -719,7 +719,13 @@ again:
-               if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
-                       goto bad_area;
-       }
--      if (expand_stack(vma, address))
-+      /*
-+       * find_vma_prev is just a bit slower, because it cannot
-+       * use the mmap_cache, so we run it only in the growsdown
-+       * slow path and we leave find_vma in the fast path.
-+       */
-+      find_vma_prev(current->mm, address, &prev_vma);
-+      if (expand_stack(vma, address, prev_vma))
-               goto bad_area;
- /*
-  * Ok, we have a good vm_area for this memory access, so
---- a/arch/xtensa/mm/fault.c
-+++ b/arch/xtensa/mm/fault.c
-@@ -80,7 +80,7 @@ void do_page_fault(struct pt_regs *regs)
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
--      if (expand_stack(vma, address))
-+      if (expand_stack(vma, address, NULL))
-               goto bad_area;
-       /* Ok, we have a good vm_area for this memory access, so
---- a/include/linux/mm.h
-+++ b/include/linux/mm.h
-@@ -1208,7 +1208,10 @@ void page_cache_async_readahead(struct a
- unsigned long max_sane_readahead(unsigned long nr);
- /* Do stack extension */
--extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
-+#define EXPAND_STACK_HAS_3_ARGS
-+extern int heap_stack_gap;
-+extern int expand_stack(struct vm_area_struct * vma, unsigned long address,
-+                      struct vm_area_struct * prev_vma);
- #ifdef CONFIG_IA64
- extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
- #endif
---- a/kernel/sysctl.c
-+++ b/kernel/sysctl.c
-@@ -1208,6 +1208,14 @@ static struct ctl_table vm_table[] = {
-               .extra2         = &one,
-       },
- #endif
-+      {
-+              .ctl_name       = CTL_UNNUMBERED,
-+              .procname       = "heap-stack-gap",
-+              .data           = &heap_stack_gap,
-+              .maxlen         = sizeof(int),
-+              .mode           = 0644,
-+              .proc_handler   = &proc_dointvec,
-+      },
- /*
-  * NOTE: do not add new entries to this table unless you have read
-  * Documentation/sysctl/ctl_unnumbered.txt
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -85,6 +85,7 @@ int sysctl_overcommit_memory = OVERCOMMI
- int sysctl_overcommit_ratio = 50;     /* default is 50% */
- int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
- atomic_long_t vm_committed_space = ATOMIC_LONG_INIT(0);
-+int heap_stack_gap = 1;
- /*
-  * Check that a process has enough memory to allocate a new virtual
-@@ -1291,6 +1292,7 @@ arch_get_unmapped_area(struct file *filp
- full_search:
-       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
-               /* At this point:  (!vma || addr < vma->vm_end). */
-+              unsigned long __heap_stack_gap;
-               if (TASK_SIZE - len < addr) {
-                       /*
-                        * Start a new search - just in case we missed
-@@ -1304,7 +1306,14 @@ full_search:
-                       }
-                       return -ENOMEM;
-               }
--              if (!vma || addr + len <= vma->vm_start) {
-+              if (!vma)
-+                      goto got_it;
-+              __heap_stack_gap = 0;
-+              if (vma->vm_flags & VM_GROWSDOWN)
-+                      __heap_stack_gap = min(TASK_SIZE-(addr+len),
-+                                             (unsigned long) heap_stack_gap << PAGE_SHIFT);
-+              if (addr + len + __heap_stack_gap <= vma->vm_start) {
-+              got_it:
-                       /*
-                        * Remember the place where we stopped the search:
-                        */
-@@ -1633,11 +1642,9 @@ int expand_upwards(struct vm_area_struct
- }
- #endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
--/*
-- * vma is the first one with address < vma->vm_start.  Have to extend vma.
-- */
- static inline int expand_downwards(struct vm_area_struct *vma,
--                                 unsigned long address)
-+                                 unsigned long address,
-+                                 struct vm_area_struct *prev_vma)
- {
-       int error;
-@@ -1665,6 +1672,13 @@ static inline int expand_downwards(struc
-       if (address < vma->vm_start) {
-               unsigned long size, grow;
-+              error = -ENOMEM;
-+              if (prev_vma) {
-+                      unsigned long __heap_stack_gap = min(TASK_SIZE-prev_vma->vm_end,
-+                                                           (unsigned long) heap_stack_gap << PAGE_SHIFT);
-+                      if (unlikely(prev_vma->vm_end + __heap_stack_gap > address))
-+                              goto out_unlock;
-+              }
-               size = vma->vm_end - address;
-               grow = (vma->vm_start - address) >> PAGE_SHIFT;
-@@ -1674,6 +1688,7 @@ static inline int expand_downwards(struc
-                       vma->vm_pgoff -= grow;
-               }
-       }
-+ out_unlock:
-       anon_vma_unlock(vma);
-       return error;
- }
-@@ -1684,8 +1699,16 @@ int expand_stack_downwards(struct vm_are
- }
- #ifdef CONFIG_STACK_GROWSUP
--int expand_stack(struct vm_area_struct *vma, unsigned long address)
-+int expand_stack(struct vm_area_struct * vma, unsigned long address,
-+               struct vm_area_struct * prev_vma)
- {
-+      /*
-+       * If you re-use the heap-stack-gap for a growsup stack you
-+       * should implement the feature for growsup too and remove
-+       * this WARN_ON.
-+       */
-+      WARN_ON(prev_vma);
-+
-       return expand_upwards(vma, address);
- }
-@@ -1698,7 +1721,7 @@ find_extend_vma(struct mm_struct *mm, un
-       vma = find_vma_prev(mm, addr, &prev);
-       if (vma && (vma->vm_start <= addr))
-               return vma;
--      if (!prev || expand_stack(prev, addr))
-+      if (!prev || expand_stack(prev, addr, NULL))
-               return NULL;
-       if (prev->vm_flags & VM_LOCKED)
-               make_pages_present(addr, prev->vm_end);
-@@ -1713,7 +1736,7 @@ int expand_stack(struct vm_area_struct *
- struct vm_area_struct *
- find_extend_vma(struct mm_struct * mm, unsigned long addr)
- {
--      struct vm_area_struct * vma;
-+      struct vm_area_struct * vma, * prev_vma;
-       unsigned long start;
-       addr &= PAGE_MASK;
-@@ -1725,7 +1748,8 @@ find_extend_vma(struct mm_struct * mm, u
-       if (!(vma->vm_flags & VM_GROWSDOWN))
-               return NULL;
-       start = vma->vm_start;
--      if (expand_stack(vma, addr))
-+      find_vma_prev(mm, addr, &prev_vma);
-+      if (expand_stack(vma, addr, prev_vma))
-               return NULL;
-       if (vma->vm_flags & VM_LOCKED)
-               make_pages_present(addr, start);