diff options
author | alc <alc@FreeBSD.org> | 2017-07-22 04:57:51 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2017-07-22 04:57:51 +0000 |
commit | 8a273c31651b9d74a5fe09f3c6ba50f3b1a71522 (patch) | |
tree | d47a0ef1fa0adb20397534c56e2bc86cb9459b87 | |
parent | 203dfa799be56a3c4585c42f6f73aee976c13db3 (diff) | |
download | FreeBSD-src-8a273c31651b9d74a5fe09f3c6ba50f3b1a71522.zip FreeBSD-src-8a273c31651b9d74a5fe09f3c6ba50f3b1a71522.tar.gz |
MFC r320498
Clear the MAP_WIREFUTURE flag on the vm map in exec_new_vmspace() when it
recycles the current vm space. Otherwise, an mlockall(MCL_FUTURE) could
still be in effect on the process after an execve(2), which violates the
specification for mlockall(2).
It's pointless for vm_map_stack() to check the MEMLOCK limit. It will
never be asked to wire the stack. Moreover, it doesn't even implement
wiring of the stack.
-rw-r--r-- | sys/kern/kern_exec.c | 4 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 14 |
2 files changed, 10 insertions, 8 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index a1e673a..cc77489 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1082,6 +1082,10 @@ exec_new_vmspace(imgp, sv) shmexit(vmspace); pmap_remove_pages(vmspace_pmap(vmspace)); vm_map_remove(map, vm_map_min(map), vm_map_max(map)); + /* An exec terminates mlockall(MCL_FUTURE). */ + vm_map_lock(map); + vm_map_modflags(map, 0, MAP_WIREFUTURE); + vm_map_unlock(map); } else { error = vmspace_exec(p, sv_minuser, sv->sv_maxuser); if (error) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index cbaf18d..6913d22 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -3445,27 +3445,25 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge) return (vm2); } +/* + * Create a process's stack for exec_new_vmspace(). This function is never + * asked to wire the newly created stack. + */ int vm_map_stack(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize, vm_prot_t prot, vm_prot_t max, int cow) { vm_size_t growsize, init_ssize; - rlim_t lmemlim, vmemlim; + rlim_t vmemlim; int rv; + MPASS((map->flags & MAP_WIREFUTURE) == 0); growsize = sgrowsiz; init_ssize = (max_ssize < growsize) ? max_ssize : growsize; vm_map_lock(map); PROC_LOCK(curproc); - lmemlim = lim_cur(curproc, RLIMIT_MEMLOCK); vmemlim = lim_cur(curproc, RLIMIT_VMEM); PROC_UNLOCK(curproc); - if (!old_mlock && map->flags & MAP_WIREFUTURE) { - if (ptoa(pmap_wired_count(map->pmap)) + init_ssize > lmemlim) { - rv = KERN_NO_SPACE; - goto out; - } - } /* If we would blow our VMEM resource limit, no go */ if (map->size + init_ssize > vmemlim) { rv = KERN_NO_SPACE; |