summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2002-07-06 07:00:01 +0000
committerjeff <jeff@FreeBSD.org>2002-07-06 07:00:01 +0000
commit427f5f38922275a7bb218d1406eb9e0cb589eccf (patch)
tree85e4e496d113cb252366300989c7f835842a160a /sys/kern
parent68e01986120fe7577fe96c40f9eaaff18f1ee461 (diff)
downloadFreeBSD-src-427f5f38922275a7bb218d1406eb9e0cb589eccf.zip
FreeBSD-src-427f5f38922275a7bb218d1406eb9e0cb589eccf.tar.gz
Clean up execve locking:
- Grab the vnode object early in exec when we still have the vnode lock. - Cache the object in the image_params. - Make use of the cached object in imgact_*.c
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/imgact_aout.c2
-rw-r--r--sys/kern/imgact_elf.c15
-rw-r--r--sys/kern/kern_exec.c8
3 files changed, 20 insertions, 5 deletions
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c
index 41ae8cf..16629d1 100644
--- a/sys/kern/imgact_aout.c
+++ b/sys/kern/imgact_aout.c
@@ -186,9 +186,9 @@ exec_aout_imgact(imgp)
vmspace = imgp->proc->p_vmspace;
vp = imgp->vp;
+ object = imgp->object;
map = &vmspace->vm_map;
vm_map_lock(map);
- VOP_GETVOBJECT(vp, &object);
vm_object_reference(object);
text_end = virtual_offset + a_out->a_text;
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 9044527..f2e1afc 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -76,7 +76,7 @@ static int elf_freebsd_fixup(register_t **stack_base,
static int elf_load_file(struct proc *p, const char *file, u_long *addr,
u_long *entry);
static int elf_load_section(struct proc *p,
- struct vmspace *vmspace, struct vnode *vp,
+ struct vmspace *vmspace, struct vnode *vp, vm_object_t object,
vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz,
vm_prot_t prot);
static int exec_elf_imgact(struct image_params *imgp);
@@ -186,19 +186,17 @@ elf_check_header(const Elf_Ehdr *hdr)
}
static int
-elf_load_section(struct proc *p, struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot)
+elf_load_section(struct proc *p, struct vmspace *vmspace, struct vnode *vp, vm_object_t object, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot)
{
size_t map_len;
vm_offset_t map_addr;
int error, rv;
size_t copy_len;
- vm_object_t object;
vm_offset_t file_addr;
vm_offset_t data_buf = 0;
GIANT_REQUIRED;
- VOP_GETVOBJECT(vp, &object);
error = 0;
/*
@@ -356,6 +354,7 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry)
imgp->attr = attr;
imgp->firstpage = NULL;
imgp->image_header = (char *)kmem_alloc_wait(exec_map, PAGE_SIZE);
+ imgp->object = NULL;
if (imgp->image_header == NULL) {
nd->ni_vp = NULL;
@@ -389,6 +388,9 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry)
*/
if (error == 0)
nd->ni_vp->v_flag |= VTEXT;
+ VOP_GETVOBJECT(nd->ni_vp, &imgp->object);
+ vm_object_reference(imgp->object);
+
VOP_UNLOCK(nd->ni_vp, 0, curthread); /* XXXKSE */
if (error)
goto fail;
@@ -425,6 +427,7 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry)
prot |= VM_PROT_READ;
if ((error = elf_load_section(p, vmspace, nd->ni_vp,
+ imgp->object,
phdr[i].p_offset,
(caddr_t)phdr[i].p_vaddr +
rbase,
@@ -449,6 +452,9 @@ fail:
if (imgp->image_header)
kmem_free_wakeup(exec_map, (vm_offset_t)imgp->image_header,
PAGE_SIZE);
+ if (imgp->object)
+ vm_object_deallocate(imgp->object);
+
if (nd->ni_vp)
vrele(nd->ni_vp);
@@ -540,6 +546,7 @@ exec_elf_imgact(struct image_params *imgp)
if ((error = elf_load_section(imgp->proc,
vmspace, imgp->vp,
+ imgp->object,
phdr[i].p_offset,
(caddr_t)phdr[i].p_vaddr,
phdr[i].p_memsz,
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index a533d86..8682d62 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -182,6 +182,7 @@ execve(td, uap)
imgp->interpreter_name[0] = '\0';
imgp->auxargs = NULL;
imgp->vp = NULL;
+ imgp->object = NULL;
imgp->firstpage = NULL;
imgp->ps_strings = 0;
imgp->auxarg_size = 0;
@@ -227,6 +228,8 @@ interpret:
VOP_UNLOCK(imgp->vp, 0, td);
goto exec_fail_dealloc;
}
+ VOP_GETVOBJECT(imgp->vp, &imgp->object);
+ vm_object_reference(imgp->object);
error = exec_map_first_page(imgp);
VOP_UNLOCK(imgp->vp, 0, td);
@@ -270,6 +273,8 @@ interpret:
/* free name buffer and old vnode */
NDFREE(ndp, NDF_ONLY_PNBUF);
vrele(ndp->ni_vp);
+ vm_object_deallocate(imgp->object);
+ imgp->object = NULL;
/* set new name to that of the interpreter */
NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
UIO_SYSSPACE, imgp->interpreter_name, td);
@@ -519,6 +524,9 @@ exec_fail_dealloc:
vrele(imgp->vp);
}
+ if (imgp->object)
+ vm_object_deallocate(imgp->object);
+
if (error == 0)
goto done2;
OpenPOWER on IntegriCloud