summaryrefslogtreecommitdiffstats
path: root/sys/i386/linux/imgact_linux.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2002-08-13 06:55:28 +0000
committerjeff <jeff@FreeBSD.org>2002-08-13 06:55:28 +0000
commita996673e123dab0805b05084774227cae72d75e5 (patch)
tree9e630263213e8fdda8c938a92f150220b0eb745d /sys/i386/linux/imgact_linux.c
parent216ea61cb629b077f8cf1b29f90f2c08ff1b1eea (diff)
downloadFreeBSD-src-a996673e123dab0805b05084774227cae72d75e5.zip
FreeBSD-src-a996673e123dab0805b05084774227cae72d75e5.tar.gz
- Hold the vnode lock throughout execve.
- Set VV_TEXT in the top level execve code. - Fixup the image activators to deal with the newly locked vnode.
Diffstat (limited to 'sys/i386/linux/imgact_linux.c')
-rw-r--r--sys/i386/linux/imgact_linux.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c
index 5634619..4b493d1 100644
--- a/sys/i386/linux/imgact_linux.c
+++ b/sys/i386/linux/imgact_linux.c
@@ -65,6 +65,7 @@ exec_linux_imgact(imgp)
unsigned long virtual_offset, file_offset;
vm_offset_t buffer;
unsigned long bss_size;
+ struct thread *td = curthread;
int error;
if (((a_out->a_magic >> 16) & 0xff) != 0x64)
@@ -110,10 +111,12 @@ exec_linux_imgact(imgp)
a_out->a_data + bss_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur)
return (ENOMEM);
+ VOP_UNLOCK(imgp->vp, 0, td);
+
/* copy in arguments and/or environment from old process */
error = exec_extract_strings(imgp);
if (error)
- return (error);
+ goto fail;
/*
* Destroy old process VM and create a new one (with a new stack)
@@ -138,14 +141,14 @@ exec_linux_imgact(imgp)
a_out->a_text + a_out->a_data + bss_size, FALSE,
VM_PROT_ALL, VM_PROT_ALL, 0);
if (error)
- return error;
+ goto fail;
error = vm_mmap(kernel_map, &buffer,
round_page(a_out->a_text + a_out->a_data + file_offset),
VM_PROT_READ, VM_PROT_READ, 0,
(caddr_t) imgp->vp, trunc_page(file_offset));
if (error)
- return error;
+ goto fail;
error = copyout((caddr_t)(void *)(uintptr_t)(buffer + file_offset),
(caddr_t)vmaddr, a_out->a_text + a_out->a_data);
@@ -154,7 +157,7 @@ exec_linux_imgact(imgp)
buffer + round_page(a_out->a_text + a_out->a_data + file_offset));
if (error)
- return error;
+ goto fail;
/*
* remove write enable on the 'text' part
@@ -165,7 +168,7 @@ exec_linux_imgact(imgp)
VM_PROT_EXECUTE|VM_PROT_READ,
TRUE);
if (error)
- return error;
+ goto fail;
}
else {
#ifdef DEBUG
@@ -182,7 +185,7 @@ exec_linux_imgact(imgp)
MAP_PRIVATE | MAP_FIXED,
(caddr_t)imgp->vp, file_offset);
if (error)
- return (error);
+ goto fail;
#ifdef DEBUG
printf("imgact: startaddr=%08lx, length=%08lx\n",
@@ -197,7 +200,7 @@ exec_linux_imgact(imgp)
VM_PROT_ALL,
FALSE);
if (error)
- return (error);
+ goto fail;
/*
* Allocate anon demand-zeroed area for uninitialized data
@@ -207,7 +210,7 @@ exec_linux_imgact(imgp)
error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr,
bss_size, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0);
if (error)
- return (error);
+ goto fail;
#ifdef DEBUG
printf("imgact: bssaddr=%08lx, length=%08lx\n",
(u_long)vmaddr, bss_size);
@@ -230,7 +233,10 @@ exec_linux_imgact(imgp)
imgp->entry_addr = a_out->a_entry;
imgp->proc->p_sysent = &linux_sysvec;
- return (0);
+
+fail:
+ vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td);
+ return (error);
}
/*
OpenPOWER on IntegriCloud