Mercurial > illumos > illumos-gate
changeset 11736:63a134e1f09c
4492533 Filesystems may need VOP_CLOSE() for executables following a VOP_OPEN()
author | Donghai Qiao <Donghai.Qiao@Sun.COM> |
---|---|
date | Mon, 22 Feb 2010 13:53:44 -0500 |
parents | 3234f117f7ad |
children | 1161d1a1bcfe |
files | usr/src/uts/common/exec/intp/intp.c usr/src/uts/common/exec/java/java.c usr/src/uts/common/exec/shbin/shbin.c usr/src/uts/common/os/exec.c usr/src/uts/common/os/exit.c usr/src/uts/common/os/fork.c |
diffstat | 6 files changed, 87 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/exec/intp/intp.c Mon Feb 22 19:28:08 2010 +0100 +++ b/usr/src/uts/common/exec/intp/intp.c Mon Feb 22 13:53:44 2010 -0500 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -27,7 +27,7 @@ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" /* from S5R4 1.6 */ +/* from S5R4 1.6 */ #include <sys/types.h> #include <sys/param.h> @@ -227,6 +227,14 @@ error = gexec(&nvp, uap, args, &idata, ++level, execsz, exec_file, cred, EBA_NONE); + + if (!error) { + /* + * Close this executable as the interpreter + * will open and close it later on. + */ + (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, cred, NULL); + } done: VN_RELE(nvp); args->pathname = opath;
--- a/usr/src/uts/common/exec/java/java.c Mon Feb 22 19:28:08 2010 +0100 +++ b/usr/src/uts/common/exec/java/java.c Mon Feb 22 13:53:44 2010 -0500 @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Launch Java executables via exec(2). * @@ -163,6 +161,15 @@ pn_free(&lookpn); error = gexec(&nvp, uap, args, &idata, level + 1, execsz, execfile, cred, EBA_NONE); + + if (!error) { + /* + * Close this Java executable as the interpreter + * will open and close it later on. + */ + (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, cred, NULL); + } + VN_RELE(nvp); args->pathname = opath; pn_free(&resolvepn);
--- a/usr/src/uts/common/exec/shbin/shbin.c Mon Feb 22 19:28:08 2010 +0100 +++ b/usr/src/uts/common/exec/shbin/shbin.c Mon Feb 22 13:53:44 2010 -0500 @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -247,6 +247,14 @@ error = gexec(&nvp, uap, args, &idata, ++level, execsz, exec_file, cred, EBA_NONE); + + if (!error) { + /* + * Close this script as the sh interpreter + * will open and close it later on. + */ + (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, cred, NULL); + } done: VN_RELE(nvp); args->pathname = opath;
--- a/usr/src/uts/common/os/exec.c Mon Feb 22 19:28:08 2010 +0100 +++ b/usr/src/uts/common/os/exec.c Mon Feb 22 13:53:44 2010 -0500 @@ -523,7 +523,7 @@ struct cred *cred, int brand_action) { - struct vnode *vp; + struct vnode *vp, *execvp = NULL; proc_t *pp = ttoproc(curthread); struct execsw *eswp; int error = 0; @@ -549,11 +549,11 @@ } if ((error = execpermissions(*vpp, &vattr, args)) != 0) - goto bad; + goto bad_noclose; - /* need to open vnode for stateful file systems like rfs */ + /* need to open vnode for stateful file systems */ if ((error = VOP_OPEN(vpp, FREAD, CRED(), NULL)) != 0) - goto bad; + goto bad_noclose; vp = *vpp; /* @@ -704,16 +704,31 @@ if (setid & PRIV_INCREASE) setidfl |= EXECSETID_PRIVS; + execvp = pp->p_exec; + if (execvp) + VN_HOLD(execvp); + error = (*eswp->exec_func)(vp, uap, args, idatap, level, execsz, setidfl, exec_file, cred, brand_action); rw_exit(eswp->exec_lock); if (error != 0) { if (newcred != NULL) crfree(newcred); + if (execvp) + VN_RELE(execvp); goto bad; } if (level == 0) { + if (execvp != NULL) { + /* + * Close the previous executable only if we are + * at level 0. + */ + (void) VOP_CLOSE(execvp, FREAD, 1, (offset_t)0, + cred, NULL); + } + mutex_enter(&pp->p_crlock); if (newcred != NULL) { /* @@ -783,9 +798,14 @@ if (args->traceinval) prinvalidate(&pp->p_user); } - + if (execvp) + VN_RELE(execvp); return (0); + bad: + (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, cred, NULL); + +bad_noclose: if (error == 0) error = ENOEXEC;
--- a/usr/src/uts/common/os/exit.c Mon Feb 22 19:28:08 2010 +0100 +++ b/usr/src/uts/common/os/exit.c Mon Feb 22 13:53:44 2010 -0500 @@ -538,10 +538,6 @@ p->p_exec = NULLVP; p->p_execdir = NULLVP; mutex_exit(&p->p_lock); - if (exec_vp) - VN_RELE(exec_vp); - if (execdir_vp) - VN_RELE(execdir_vp); pr_free_watched_pages(p); @@ -577,6 +573,17 @@ */ relvm(); + if (exec_vp) { + /* + * Close this executable which has been opened when the process + * was created by getproc(). + */ + (void) VOP_CLOSE(exec_vp, FREAD, 1, (offset_t)0, CRED(), NULL); + VN_RELE(exec_vp); + } + if (execdir_vp) + VN_RELE(execdir_vp); + /* * Release held contracts. */
--- a/usr/src/uts/common/os/fork.c Mon Feb 22 19:28:08 2010 +0100 +++ b/usr/src/uts/common/os/fork.c Mon Feb 22 13:53:44 2010 -0500 @@ -974,6 +974,28 @@ goto bad; } + mutex_enter(&pp->p_lock); + cp->p_exec = pp->p_exec; + cp->p_execdir = pp->p_execdir; + mutex_exit(&pp->p_lock); + + if (cp->p_exec) { + VN_HOLD(cp->p_exec); + /* + * Each VOP_OPEN() must be paired with a corresponding + * VOP_CLOSE(). In this case, the executable will be + * closed for the child in either proc_exit() or gexec(). + */ + if (VOP_OPEN(&cp->p_exec, FREAD, CRED(), NULL) != 0) { + VN_RELE(cp->p_exec); + cp->p_exec = NULLVP; + cp->p_execdir = NULLVP; + goto bad; + } + } + if (cp->p_execdir) + VN_HOLD(cp->p_execdir); + /* * If not privileged make sure that this user hasn't exceeded * v.v_maxup processes, and that users collectively haven't @@ -1011,12 +1033,9 @@ cp->p_flag = pp->p_flag & (SJCTL|SNOWAIT|SNOCD); cp->p_sessp = pp->p_sessp; sess_hold(pp); - cp->p_exec = pp->p_exec; - cp->p_execdir = pp->p_execdir; cp->p_brand = pp->p_brand; if (PROC_IS_BRANDED(pp)) BROP(pp)->b_copy_procdata(cp, pp); - cp->p_bssbase = pp->p_bssbase; cp->p_brkbase = pp->p_brkbase; cp->p_brksize = pp->p_brksize; @@ -1164,10 +1183,6 @@ */ cp->p_fixalignment = pp->p_fixalignment; - if (cp->p_exec) - VN_HOLD(cp->p_exec); - if (cp->p_execdir) - VN_HOLD(cp->p_execdir); *cpp = cp; return (0);