Binary files 2.2.18pre14/ID and stackoverflow/ID differ diff -urN 2.2.18pre14/arch/alpha/mm/fault.c stackoverflow/arch/alpha/mm/fault.c --- 2.2.18pre14/arch/alpha/mm/fault.c Tue Sep 5 02:28:38 2000 +++ stackoverflow/arch/alpha/mm/fault.c Tue Oct 3 01:04:31 2000 @@ -102,7 +102,7 @@ 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 diff -urN 2.2.18pre14/arch/i386/mm/fault.c stackoverflow/arch/i386/mm/fault.c --- 2.2.18pre14/arch/i386/mm/fault.c Thu May 4 13:00:36 2000 +++ stackoverflow/arch/i386/mm/fault.c Tue Oct 3 01:04:31 2000 @@ -29,13 +29,13 @@ */ int __verify_write(const void * addr, unsigned long size) { - struct vm_area_struct * vma; + struct vm_area_struct * vma, * prev_vma; unsigned long start = (unsigned long) addr; if (!size) return 1; - vma = find_vma(current->mm, start); + vma = find_vma_prev(current->mm, start, &prev_vma); if (!vma) goto bad_area; if (vma->vm_start > start) @@ -75,7 +75,7 @@ check_stack: if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; - if (expand_stack(vma, start) == 0) + if (expand_stack(vma, start, prev_vma) == 0) goto good_area; bad_area: @@ -112,7 +112,7 @@ { struct task_struct *tsk; struct mm_struct *mm; - struct vm_area_struct * vma; + struct vm_area_struct * vma, * prev_vma; unsigned long address; unsigned long page; unsigned long fixup; @@ -133,7 +133,7 @@ down(&mm->mmap_sem); - vma = find_vma(mm, address); + vma = find_vma_prev(mm, address, &prev_vma); if (!vma) goto bad_area; if (vma->vm_start <= address) @@ -150,7 +150,7 @@ if (address + 32 < regs->esp) goto bad_area; } - if (expand_stack(vma, address)) + if (expand_stack(vma, address, prev_vma)) goto bad_area; /* * Ok, we have a good vm_area for this memory access, so diff -urN 2.2.18pre14/arch/ppc/mm/fault.c stackoverflow/arch/ppc/mm/fault.c --- 2.2.18pre14/arch/ppc/mm/fault.c Tue Sep 5 02:28:38 2000 +++ stackoverflow/arch/ppc/mm/fault.c Tue Oct 3 01:04:31 2000 @@ -58,7 +58,7 @@ void 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; int fault; @@ -92,14 +92,14 @@ } down(&mm->mmap_sem); - vma = find_vma(mm, address); + vma = find_vma_prev(mm, address, &prev_vma); if (!vma) goto bad_area; if (vma->vm_start <= address) goto good_area; if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; - if (expand_stack(vma, address)) + if (expand_stack(vma, address, prev_vma)) goto bad_area; good_area: diff -urN 2.2.18pre14/arch/s390/mm/fault.c stackoverflow/arch/s390/mm/fault.c --- 2.2.18pre14/arch/s390/mm/fault.c Tue Sep 5 02:28:39 2000 +++ stackoverflow/arch/s390/mm/fault.c Tue Oct 3 01:28:47 2000 @@ -80,7 +80,7 @@ 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 diff -urN 2.2.18pre14/arch/sparc/mm/fault.c stackoverflow/arch/sparc/mm/fault.c --- 2.2.18pre14/arch/sparc/mm/fault.c Sun Apr 2 21:07:48 2000 +++ stackoverflow/arch/sparc/mm/fault.c Tue Oct 3 01:28:57 2000 @@ -222,7 +222,7 @@ 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 @@ -414,7 +414,7 @@ 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: if(write) { diff -urN 2.2.18pre14/arch/sparc64/mm/fault.c stackoverflow/arch/sparc64/mm/fault.c --- 2.2.18pre14/arch/sparc64/mm/fault.c Sun Apr 2 21:07:48 2000 +++ stackoverflow/arch/sparc64/mm/fault.c Tue Oct 3 01:29:01 2000 @@ -194,7 +194,7 @@ 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 diff -urN 2.2.18pre14/include/linux/mm.h stackoverflow/include/linux/mm.h --- 2.2.18pre14/include/linux/mm.h Mon Oct 2 22:28:16 2000 +++ stackoverflow/include/linux/mm.h Tue Oct 3 01:06:43 2000 @@ -347,13 +347,18 @@ #define GFP_DMA __GFP_DMA +extern int heap_stack_gap; + /* vma is the first one with address < vma->vm_end, * and even address < vma->vm_start. Have to extend vma. */ -static inline int expand_stack(struct vm_area_struct * vma, unsigned long address) +static inline int expand_stack(struct vm_area_struct * vma, unsigned long address, + struct vm_area_struct * prev_vma) { unsigned long grow; address &= PAGE_MASK; + if (prev_vma && prev_vma->vm_end + (heap_stack_gap << PAGE_SHIFT) > address) + return -ENOMEM; grow = vma->vm_start - address; if ((vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur) || @@ -371,6 +376,8 @@ /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr); +extern struct vm_area_struct * find_vma_prev(struct mm_struct *, unsigned long, + struct vm_area_struct **); /* Look up the first VMA which intersects the interval start_addr..end_addr-1, NULL if none. Assume start_addr < end_addr. */ diff -urN 2.2.18pre14/include/linux/sysctl.h stackoverflow/include/linux/sysctl.h --- 2.2.18pre14/include/linux/sysctl.h Mon Oct 2 22:28:16 2000 +++ stackoverflow/include/linux/sysctl.h Tue Oct 3 01:04:31 2000 @@ -121,7 +121,8 @@ VM_PAGECACHE=7, /* struct: Set cache memory thresholds */ VM_PAGERDAEMON=8, /* struct: Control kswapd behaviour */ VM_PGT_CACHE=9, /* struct: Set page table cache parameters */ - VM_PAGE_CLUSTER=10 /* int: set number of pages to swap together */ + VM_PAGE_CLUSTER=10, /* int: set number of pages to swap together */ + VM_HEAP_STACK_GAP=11, /* int: page gap between heap and stack */ }; diff -urN 2.2.18pre14/kernel/sysctl.c stackoverflow/kernel/sysctl.c --- 2.2.18pre14/kernel/sysctl.c Tue Jun 13 03:48:15 2000 +++ stackoverflow/kernel/sysctl.c Tue Oct 3 01:04:31 2000 @@ -252,6 +252,8 @@ &pgt_cache_water, 2*sizeof(int), 0600, NULL, &proc_dointvec}, {VM_PAGE_CLUSTER, "page-cluster", &page_cluster, sizeof(int), 0600, NULL, &proc_dointvec}, + {VM_HEAP_STACK_GAP, "heap-stack-gap", + &heap_stack_gap, sizeof(int), 0644, NULL, &proc_dointvec}, {0} }; diff -urN 2.2.18pre14/mm/mmap.c stackoverflow/mm/mmap.c --- 2.2.18pre14/mm/mmap.c Mon Oct 2 22:28:16 2000 +++ stackoverflow/mm/mmap.c Tue Oct 3 01:04:31 2000 @@ -40,6 +40,7 @@ kmem_cache_t *vm_area_cachep; int sysctl_overcommit_memory; +int heap_stack_gap = 1; /* Check that a process has enough memory to allocate a * new virtual mapping. @@ -371,9 +372,14 @@ for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { /* At this point: (!vmm || addr < vmm->vm_end). */ + unsigned long __heap_stack_gap = 0; if (TASK_SIZE - len < addr) return 0; - if (!vmm || addr + len <= vmm->vm_start) + if (!vmm) + return addr; + if (vmm->vm_flags & VM_GROWSDOWN) + __heap_stack_gap = heap_stack_gap << PAGE_SHIFT; + if (addr + len + __heap_stack_gap <= vmm->vm_start) return addr; addr = vmm->vm_end; }