aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_exec.c9
-rw-r--r--sys/sys/proc.h1
-rw-r--r--sys/vm/vm_map.c4
3 files changed, 13 insertions, 1 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 9f223ca6d94a..04c1c9a7c961 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -282,6 +282,7 @@ kern_execve(td, args, mac_p)
struct mac *mac_p;
{
struct proc *p = td->td_proc;
+ struct vmspace *oldvmspace;
int error;
AUDIT_ARG_ARGV(args->begin_argv, args->argc,
@@ -298,6 +299,8 @@ kern_execve(td, args, mac_p)
PROC_UNLOCK(p);
}
+ KASSERT((td->td_pflags & TDP_EXECVMSPC) == 0, ("nested execve"));
+ oldvmspace = td->td_proc->p_vmspace;
error = do_execve(td, args, mac_p);
if (p->p_flag & P_HADTHREADS) {
@@ -312,6 +315,12 @@ kern_execve(td, args, mac_p)
thread_single_end();
PROC_UNLOCK(p);
}
+ if ((td->td_pflags & TDP_EXECVMSPC) != 0) {
+ KASSERT(td->td_proc->p_vmspace != oldvmspace,
+ ("oldvmspace still used"));
+ vmspace_free(oldvmspace);
+ td->td_pflags &= ~TDP_EXECVMSPC;
+ }
return (error);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index a0fd11c780e1..fbd064cd6769 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -429,6 +429,7 @@ do { \
#define TDP_NERRNO 0x08000000 /* Last errno is already in td_errno */
#define TDP_UIOHELD 0x10000000 /* Current uio has pages held in td_ma */
#define TDP_DEVMEMIO 0x20000000 /* Accessing memory for /dev/mem */
+#define TDP_EXECVMSPC 0x40000000 /* Execve destroyed old vmspace */
/*
* Reasons that the current thread can not be run yet.
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 9dc655c13a56..04f3bd5e9306 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -3758,6 +3758,8 @@ vmspace_exec(struct proc *p, vm_offset_t minuser, vm_offset_t maxuser)
struct vmspace *oldvmspace = p->p_vmspace;
struct vmspace *newvmspace;
+ KASSERT((curthread->td_pflags & TDP_EXECVMSPC) == 0,
+ ("vmspace_exec recursed"));
newvmspace = vmspace_alloc(minuser, maxuser, NULL);
if (newvmspace == NULL)
return (ENOMEM);
@@ -3774,7 +3776,7 @@ vmspace_exec(struct proc *p, vm_offset_t minuser, vm_offset_t maxuser)
PROC_VMSPACE_UNLOCK(p);
if (p == curthread->td_proc)
pmap_activate(curthread);
- vmspace_free(oldvmspace);
+ curthread->td_pflags |= TDP_EXECVMSPC;
return (0);
}