Pulled in the 4.11 upstream fixes for the stack gap problem: Unmerged paths: (use "git add ..." to mark resolution) both modified: arch/arm/mm/mmap.c both modified: arch/frv/mm/elf-fdpic.c both modified: arch/mips/mm/mmap.c both modified: arch/powerpc/mm/slice.c both modified: arch/sh/mm/mmap.c both modified: arch/sparc/kernel/sys_sparc_64.c both modified: arch/sparc/mm/hugetlbpage.c both modified: arch/x86/kernel/sys_x86_64.c both modified: arch/x86/mm/hugetlbpage.c both modified: fs/hugetlbfs/inode.c both modified: mm/mmap.c Huh, this sure is a whole lot of merge conflicts, generally only happens when someone's copy+pasting code and renaming things. Let's take a look at some of these rejects (HEAD is PaX, the ugly vm_start_gap is the upstream fix): fs/hugetlbfs/inode.c: <<<<<<< HEAD if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len)) ======= if (TASK_SIZE - len >= addr && (!vma || addr + len <= vm_start_gap(vma))) >>>>>>> 9f3069116ed29013d0eb89e02def9effb038f850 arch/arm/mm/mmap.c: <<<<<<< HEAD if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len)) ======= if (TASK_SIZE - len >= addr && (!vma || addr + len <= vm_start_gap(vma))) >>>>>>> 9f3069116ed29013d0eb89e02def9effb038f850 arch/sh/mm/mmap.c: <<<<<<< HEAD if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len)) ======= if (TASK_SIZE - len >= addr && (!vma || addr + len <= vm_start_gap(vma))) >>>>>>> 9f3069116ed29013d0eb89e02def9effb038f850 arch/x86/kernel/sys_x86_64.c: <<<<<<< HEAD if (end - len >= addr && check_heap_stack_gap(vma, addr, len)) ======= if (end - len >= addr && (!vma || addr + len <= vm_start_gap(vma))) >>>>>>> 9f3069116ed29013d0eb89e02def9effb038f850 arch/powerpc/mm/slice.c: <<<<<<< HEAD return check_heap_stack_gap(vma, addr, len); ======= return (!vma || (addr + len) <= vm_start_gap(vma)); >>>>>>> 9f3069116ed29013d0eb89e02def9effb038f850 arch/frv/mm/elf-fdpic.c: <<<<<<< HEAD if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len)) ======= if (TASK_SIZE - len >= addr && (!vma || addr + len <= vm_start_gap(vma))) >>>>>>> 9f3069116ed29013d0eb89e02def9effb038f850 arch/mips/mm/mmap.c: <<<<<<< HEAD if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len)) ======= if (TASK_SIZE - len >= addr && (!vma || addr + len <= vm_start_gap(vma))) >>>>>>> 9f3069116ed29013d0eb89e02def9effb038f850 (the rest are all the same kinds of rejects) Let's look at our check_heap_stack_gap(): bool check_heap_stack_gap(const struct vm_area_struct *vma, unsigned long addr, unsigned long len) { if (!vma) { #ifdef CONFIG_STACK_GROWSUP if (addr > sysctl_heap_stack_gap) vma = find_vma(current->mm, addr - sysctl_heap_stack_gap); else vma = find_vma(current->mm, 0); if (vma && (vma->vm_flags & VM_GROWSUP)) return false; #endif return true; } if (addr + len > vma->vm_start) return false; if (vma->vm_flags & VM_GROWSDOWN) return sysctl_heap_stack_gap <= vma->vm_start - addr - len; #ifdef CONFIG_STACK_GROWSUP else if (vma->vm_prev && (vma->vm_prev->vm_flags & VM_GROWSUP)) return addr - vma->vm_prev->vm_end >= sysctl_heap_stack_gap; #endif return true; } Amazing, it took them 4 whole weeks just to rip off PaX's fix from 2010.