summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2017-07-22 04:57:51 +0000
committeralc <alc@FreeBSD.org>2017-07-22 04:57:51 +0000
commit8a273c31651b9d74a5fe09f3c6ba50f3b1a71522 (patch)
treed47a0ef1fa0adb20397534c56e2bc86cb9459b87
parent203dfa799be56a3c4585c42f6f73aee976c13db3 (diff)
downloadFreeBSD-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.c4
-rw-r--r--sys/vm/vm_map.c14
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;
OpenPOWER on IntegriCloud