Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c +++ sys/kern/imgact_elf.c @@ -2684,7 +2684,7 @@ return (flags); } -void +vm_size_t __elfN(stackgap)(struct image_params *imgp, uintptr_t *stack_base) { uintptr_t range, rbase, gap; @@ -2692,7 +2692,7 @@ pct = __elfN(aslr_stack_gap); if (pct == 0) - return; + return (0); if (pct > 50) pct = 50; range = imgp->eff_stack_sz * pct / 100; @@ -2700,4 +2700,5 @@ gap = rbase % range; gap &= ~(sizeof(u_long) - 1); *stack_base -= gap; + return (gap); } Index: sys/kern/kern_exec.c =================================================================== --- sys/kern/kern_exec.c +++ sys/kern/kern_exec.c @@ -1148,6 +1148,7 @@ stack_prot, error, vm_mmap_to_errno(error)); return (vm_mmap_to_errno(error)); } + vmspace->vm_stkgap = 0; /* * vm_ssize and vm_maxsaddr are somewhat antiquated concepts, but they @@ -1493,12 +1494,16 @@ void exec_stackgap(struct image_params *imgp, uintptr_t *dp) { + struct proc *p = imgp->proc; + if (imgp->sysent->sv_stackgap == NULL || - (imgp->proc->p_fctl0 & (NT_FREEBSD_FCTL_ASLR_DISABLE | + (p->p_fctl0 & (NT_FREEBSD_FCTL_ASLR_DISABLE | NT_FREEBSD_FCTL_ASG_DISABLE)) != 0 || - (imgp->map_flags & MAP_ASLR) == 0) + (imgp->map_flags & MAP_ASLR) == 0) { + p->p_vmspace->vm_stkgap = 0; return; - imgp->sysent->sv_stackgap(imgp, dp); + } + p->p_vmspace->vm_stkgap = imgp->sysent->sv_stackgap(imgp, dp); } /* Index: sys/kern/kern_resource.c =================================================================== --- sys/kern/kern_resource.c +++ sys/kern/kern_resource.c @@ -671,6 +671,12 @@ if (limp->rlim_max < 0) limp->rlim_max = RLIM_INFINITY; + if (which == RLIMIT_STACK && limp->rlim_cur != RLIM_INFINITY) { + limp->rlim_cur += p->p_vmspace->vm_stkgap; + if (limp->rlim_cur > limp->rlim_max) + limp->rlim_cur = limp->rlim_max; + } + oldssiz.rlim_cur = 0; newlim = lim_alloc(); PROC_LOCK(p); Index: sys/sys/imgact_elf.h =================================================================== --- sys/sys/imgact_elf.h +++ sys/sys/imgact_elf.h @@ -118,7 +118,7 @@ int __elfN(freebsd_fixup)(uintptr_t *, struct image_params *); int __elfN(coredump)(struct thread *, struct vnode *, off_t, int); size_t __elfN(populate_note)(int, void *, void *, size_t, void **); -void __elfN(stackgap)(struct image_params *, uintptr_t *); +vm_size_t __elfN(stackgap)(struct image_params *, uintptr_t *); int __elfN(freebsd_copyout_auxargs)(struct image_params *, uintptr_t); void __elfN(puthdr)(struct thread *, void *, size_t, int, size_t, int); void __elfN(prepare_notes)(struct thread *, struct note_info_list *, Index: sys/sys/sysent.h =================================================================== --- sys/sys/sysent.h +++ sys/sys/sysent.h @@ -119,7 +119,7 @@ void (*sv_elf_core_prepare_notes)(struct thread *, struct note_info_list *, size_t *); int (*sv_imgact_try)(struct image_params *); - void (*sv_stackgap)(struct image_params *, uintptr_t *); + vm_size_t (*sv_stackgap)(struct image_params *, uintptr_t *); int (*sv_copyout_auxargs)(struct image_params *, uintptr_t); int sv_minsigstksz; /* minimum signal stack size */ Index: sys/vm/vm_map.h =================================================================== --- sys/vm/vm_map.h +++ sys/vm/vm_map.h @@ -293,6 +293,7 @@ caddr_t vm_taddr; /* (c) user virtual address of text */ caddr_t vm_daddr; /* (c) user virtual address of data */ caddr_t vm_maxsaddr; /* user VA at max stack growth */ + vm_size_t vm_stkgap; /* stack gap size in bytes */ u_int vm_refcnt; /* number of references */ /* * Keep the PMAP last, so that CPU-specific variations of that Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -343,6 +343,7 @@ vm->vm_taddr = 0; vm->vm_daddr = 0; vm->vm_maxsaddr = 0; + vm->vm_stkgap = 0; return (vm); } @@ -4265,6 +4266,7 @@ vm2->vm_taddr = vm1->vm_taddr; vm2->vm_daddr = vm1->vm_daddr; vm2->vm_maxsaddr = vm1->vm_maxsaddr; + vm2->vm_stkgap = vm1->vm_stkgap; vm_map_lock(old_map); if (old_map->busy) vm_map_wait_busy(old_map);