Use shared vnode locks for the ELF interpreter.
Reviewed by: kib MFC after: 2 weeks Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D19874
This commit is contained in:
parent
f1ef572a1e
commit
4033ecc915
@ -716,7 +716,7 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
|
||||
struct nameidata *nd;
|
||||
struct vattr *attr;
|
||||
struct image_params *imgp;
|
||||
u_long rbase;
|
||||
u_long flags, rbase;
|
||||
u_long base_addr = 0;
|
||||
int error;
|
||||
|
||||
@ -744,7 +744,10 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
|
||||
imgp->object = NULL;
|
||||
imgp->execlabel = NULL;
|
||||
|
||||
NDINIT(nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_SYSSPACE, file, curthread);
|
||||
flags = FOLLOW | LOCKSHARED | LOCKLEAF;
|
||||
|
||||
again:
|
||||
NDINIT(nd, LOOKUP, flags, UIO_SYSSPACE, file, curthread);
|
||||
if ((error = namei(nd)) != 0) {
|
||||
nd->ni_vp = NULL;
|
||||
goto fail;
|
||||
@ -759,16 +762,31 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Also make certain that the interpreter stays the same,
|
||||
* so set its VV_TEXT flag, too. Since this function is only
|
||||
* used to load the interpreter, the VV_TEXT is almost always
|
||||
* already set.
|
||||
*/
|
||||
if (VOP_IS_TEXT(nd->ni_vp) == 0) {
|
||||
if (VOP_ISLOCKED(nd->ni_vp) != LK_EXCLUSIVE) {
|
||||
/*
|
||||
* LK_UPGRADE could have resulted in dropping
|
||||
* the lock. Just try again from the start,
|
||||
* this time with exclusive vnode lock.
|
||||
*/
|
||||
vput(nd->ni_vp);
|
||||
flags &= ~LOCKSHARED;
|
||||
goto again;
|
||||
}
|
||||
|
||||
VOP_SET_TEXT(nd->ni_vp);
|
||||
}
|
||||
|
||||
error = exec_map_first_page(imgp);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Also make certain that the interpreter stays the same, so set
|
||||
* its VV_TEXT flag, too.
|
||||
*/
|
||||
VOP_SET_TEXT(nd->ni_vp);
|
||||
|
||||
imgp->object = nd->ni_vp->v_object;
|
||||
|
||||
hdr = (const Elf_Ehdr *)imgp->image_header;
|
||||
|
Loading…
Reference in New Issue
Block a user