exec vnode locking protocol changes: in a nutshell, don't keep vnodes
locked for any longer than we have to.
This commit is contained in:
parent
6f5b5cefc7
commit
3b34cba879
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: exec_elf32.c,v 1.11 1996/09/30 23:02:14 cgd Exp $ */
|
||||
/* $NetBSD: exec_elf32.c,v 1.12 1996/09/30 23:18:43 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou
|
||||
@ -304,7 +304,7 @@ ELFNAME(read_from)(p, vp, off, buf, size)
|
||||
int resid;
|
||||
|
||||
if ((error = vn_rdwr(UIO_READ, vp, buf, size,
|
||||
off, UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred,
|
||||
off, UIO_SYSSPACE, 0, p->p_ucred,
|
||||
&resid, p)) != 0)
|
||||
return error;
|
||||
/*
|
||||
@ -345,10 +345,17 @@ ELFNAME(load_file)(p, path, vcset, entry, ap, last)
|
||||
* 2. read filehdr
|
||||
* 3. map text, data, and bss out of it using VM_*
|
||||
*/
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p);
|
||||
if ((error = namei(&nd)) != 0) {
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return error;
|
||||
}
|
||||
#ifdef notyet /* XXX cgd 960926 */
|
||||
XXX cgd 960926: check vnode type
|
||||
XXX cgd 960926: check mount point for MNT_NOEXEC
|
||||
XXX cgd 960926: check VOP_ACCESS on it.
|
||||
XXX cgd 960926: (maybe) VOP_OPEN it (and VOP_CLOSE in copyargs?)
|
||||
#endif
|
||||
VOP_UNLOCK(nd.ni_vp);
|
||||
|
||||
if ((error = ELFNAME(read_from)(p, nd.ni_vp, 0, (caddr_t) &eh,
|
||||
sizeof(eh))) != 0)
|
||||
goto bad;
|
||||
@ -393,11 +400,17 @@ ELFNAME(load_file)(p, path, vcset, entry, ap, last)
|
||||
}
|
||||
}
|
||||
|
||||
free((char *) ph, M_TEMP);
|
||||
*last = addr;
|
||||
vrele(nd.ni_vp);
|
||||
return 0;
|
||||
|
||||
bad:
|
||||
if (ph != NULL)
|
||||
free((char *) ph, M_TEMP);
|
||||
|
||||
*last = addr;
|
||||
#ifdef notyet /* XXX cgd 960926 */
|
||||
(maybe) VOP_CLOSE it
|
||||
#endif
|
||||
vrele(nd.ni_vp);
|
||||
return error;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: exec_script.c,v 1.13 1996/02/04 02:15:06 christos Exp $ */
|
||||
/* $NetBSD: exec_script.c,v 1.14 1996/09/30 23:18:44 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994 Christopher G. Demetriou
|
||||
* Copyright (c) 1993, 1994, 1996 Christopher G. Demetriou
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -159,7 +159,10 @@ check_shell:
|
||||
* close all open fd's when the start. That kills this
|
||||
* method of implementing "safe" set-id and x-only scripts.
|
||||
*/
|
||||
if (VOP_ACCESS(epp->ep_vp, VREAD, p->p_ucred, p) == EACCES
|
||||
VOP_LOCK(epp->ep_vp);
|
||||
error = VOP_ACCESS(epp->ep_vp, VREAD, p->p_ucred, p);
|
||||
VOP_UNLOCK(epp->ep_vp);
|
||||
if (error == EACCES
|
||||
#ifdef SETUIDSCRIPTS
|
||||
|| script_sbits
|
||||
#endif
|
||||
@ -227,8 +230,6 @@ check_shell:
|
||||
scriptvp = epp->ep_vp;
|
||||
oldpnbuf = epp->ep_ndp->ni_cnd.cn_pnbuf;
|
||||
|
||||
VOP_UNLOCK(scriptvp);
|
||||
|
||||
if ((error = check_exec(p, epp)) == 0) {
|
||||
/* note that we've clobbered the header */
|
||||
epp->ep_flags |= EXEC_DESTR;
|
||||
@ -239,8 +240,10 @@ check_shell:
|
||||
* Also, set things up so that the fake args
|
||||
* list will be used.
|
||||
*/
|
||||
if ((epp->ep_flags & EXEC_HASFD) == 0)
|
||||
vn_close(scriptvp, FREAD, p->p_ucred, p);
|
||||
if ((epp->ep_flags & EXEC_HASFD) == 0) {
|
||||
VOP_CLOSE(scriptvp, FREAD, p->p_ucred, p);
|
||||
vrele(scriptvp);
|
||||
}
|
||||
|
||||
/* free the old pathname buffer */
|
||||
FREE(oldpnbuf, M_NAMEI);
|
||||
@ -273,8 +276,10 @@ fail:
|
||||
if (epp->ep_flags & EXEC_HASFD) {
|
||||
epp->ep_flags &= ~EXEC_HASFD;
|
||||
(void) fdrelease(p, epp->ep_fd);
|
||||
} else
|
||||
vn_close(scriptvp, FREAD, p->p_ucred, p);
|
||||
} else {
|
||||
VOP_CLOSE(scriptvp, FREAD, p->p_ucred, p);
|
||||
vrele(scriptvp);
|
||||
}
|
||||
|
||||
FREE(epp->ep_ndp->ni_cnd.cn_pnbuf, M_NAMEI);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: exec_subr.c,v 1.9 1994/12/04 03:10:42 mycroft Exp $ */
|
||||
/* $NetBSD: exec_subr.c,v 1.10 1996/09/30 23:18:45 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994 Christopher G. Demetriou
|
||||
* Copyright (c) 1993, 1994, 1996 Christopher G. Demetriou
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -41,6 +41,11 @@
|
||||
|
||||
#include <vm/vm.h>
|
||||
|
||||
/*
|
||||
* XXX cgd 960926: this module should collect simple statistics
|
||||
* (calls, extends, kills).
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* new_vmcmd():
|
||||
@ -164,7 +169,7 @@ vmcmd_map_readvn(p, cmd)
|
||||
return error;
|
||||
|
||||
error = vn_rdwr(UIO_READ, cmd->ev_vp, (caddr_t)cmd->ev_addr,
|
||||
cmd->ev_len, cmd->ev_offset, UIO_USERSPACE, IO_UNIT|IO_NODELOCKED,
|
||||
cmd->ev_len, cmd->ev_offset, UIO_USERSPACE, IO_UNIT,
|
||||
p->p_ucred, (int *)0, p);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: kern_exec.c,v 1.76 1996/09/26 23:34:47 cgd Exp $ */
|
||||
/* $NetBSD: kern_exec.c,v 1.77 1996/09/30 23:18:46 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1993, 1994 Christopher G. Demetriou
|
||||
* Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou
|
||||
* Copyright (C) 1992 Wolfgang Solfrank.
|
||||
* Copyright (C) 1992 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
@ -74,17 +74,17 @@
|
||||
*
|
||||
* ON EXIT:
|
||||
* error: nothing held, etc. exec header still allocated.
|
||||
* ok: filled exec package, executable's vnode (locked).
|
||||
* ok: filled exec package, executable's vnode (unlocked).
|
||||
*
|
||||
* EXEC SWITCH ENTRY:
|
||||
* Locked vnode to check, exec package, proc.
|
||||
*
|
||||
* EXEC SWITCH EXIT:
|
||||
* ok: return 0, filled exec package, executable's vnode (locked).
|
||||
* ok: return 0, filled exec package, executable's vnode (unlocked).
|
||||
* error: destructive:
|
||||
* everything deallocated execept exec header.
|
||||
* non-destructive:
|
||||
* error code, executable's vnode (locked),
|
||||
* error code, executable's vnode (unlocked),
|
||||
* exec header unmodified.
|
||||
*/
|
||||
int
|
||||
@ -135,9 +135,12 @@ check_exec(p, epp)
|
||||
if ((error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) != 0)
|
||||
goto bad1;
|
||||
|
||||
/* unlock vp, since we don't need it locked from here on out. */
|
||||
VOP_UNLOCK(vp);
|
||||
|
||||
/* now we have the file, get the exec header */
|
||||
error = vn_rdwr(UIO_READ, vp, epp->ep_hdr, epp->ep_hdrlen, 0,
|
||||
UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
|
||||
UIO_SYSSPACE, 0, p->p_ucred, &resid, p);
|
||||
if (error)
|
||||
goto bad2;
|
||||
epp->ep_hdrvalid = epp->ep_hdrlen - resid;
|
||||
@ -185,8 +188,8 @@ bad2:
|
||||
* unlock and close the vnode, restore the old one, free the
|
||||
* pathname buf, and punt.
|
||||
*/
|
||||
VOP_UNLOCK(vp);
|
||||
vn_close(vp, FREAD, p->p_ucred, p);
|
||||
VOP_CLOSE(vp, FREAD, p->p_ucred, p);
|
||||
vrele(vp);
|
||||
FREE(ndp->ni_cnd.cn_pnbuf, M_NAMEI);
|
||||
return error;
|
||||
|
||||
@ -195,8 +198,8 @@ bad1:
|
||||
* free the namei pathname buffer, and put the vnode
|
||||
* (which we don't yet have open).
|
||||
*/
|
||||
vput(vp); /* was still locked */
|
||||
FREE(ndp->ni_cnd.cn_pnbuf, M_NAMEI);
|
||||
vput(vp);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -244,6 +247,7 @@ sys_execve(p, v, retval)
|
||||
}
|
||||
|
||||
/* init the namei data to point the file user's program name */
|
||||
/* XXX cgd 960926: why do this here? most will be clobbered. */
|
||||
NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
|
||||
|
||||
/*
|
||||
@ -359,6 +363,7 @@ sys_execve(p, v, retval)
|
||||
pack.ep_ssize = len; /* maybe should go elsewhere, but... */
|
||||
|
||||
/* Unmap old program */
|
||||
/* XXX cgd 960926: the sparc #ifdef should be a MD hook */
|
||||
#ifdef sparc
|
||||
kill_user_windows(p); /* before stack addresses go away */
|
||||
#endif
|
||||
@ -469,7 +474,7 @@ sys_execve(p, v, retval)
|
||||
|
||||
FREE(nid.ni_cnd.cn_pnbuf, M_NAMEI);
|
||||
VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
|
||||
vput(pack.ep_vp);
|
||||
vrele(pack.ep_vp);
|
||||
|
||||
/* setup new registers and do misc. setup. */
|
||||
(*pack.ep_emul->e_setregs)(p, &pack, (u_long) stack, retval);
|
||||
@ -496,7 +501,7 @@ bad:
|
||||
}
|
||||
/* close and put the exec'd file */
|
||||
VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
|
||||
vput(pack.ep_vp);
|
||||
vrele(pack.ep_vp);
|
||||
FREE(nid.ni_cnd.cn_pnbuf, M_NAMEI);
|
||||
kmem_free_wakeup(exec_map, (vm_offset_t) argp, NCARGS);
|
||||
|
||||
@ -516,7 +521,7 @@ exec_abort:
|
||||
FREE(pack.ep_emul_arg, M_TEMP);
|
||||
FREE(nid.ni_cnd.cn_pnbuf, M_NAMEI);
|
||||
VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
|
||||
vput(pack.ep_vp);
|
||||
vrele(pack.ep_vp);
|
||||
kmem_free_wakeup(exec_map, (vm_offset_t) argp, NCARGS);
|
||||
FREE(pack.ep_hdr, M_EXEC);
|
||||
exit1(p, W_EXITCODE(0, SIGABRT));
|
||||
|
Loading…
x
Reference in New Issue
Block a user