diff options
| author | Donghai Qiao <Donghai.Qiao@Sun.COM> | 2010-02-22 13:53:44 -0500 |
|---|---|---|
| committer | Donghai Qiao <Donghai.Qiao@Sun.COM> | 2010-02-22 13:53:44 -0500 |
| commit | a4aeef46cda1835da2b19f8f62b4526de6521e6c (patch) | |
| tree | 88f8fa8685907fe8c2d2d5853d7dd20f7e0d5639 /usr/src/uts | |
| parent | 9d3952ab10f8677fdabc8594d26cc1e7d6acdfc4 (diff) | |
| download | illumos-gate-a4aeef46cda1835da2b19f8f62b4526de6521e6c.tar.gz | |
4492533 Filesystems may need VOP_CLOSE() for executables following a VOP_OPEN()
Diffstat (limited to 'usr/src/uts')
| -rw-r--r-- | usr/src/uts/common/exec/intp/intp.c | 12 | ||||
| -rw-r--r-- | usr/src/uts/common/exec/java/java.c | 13 | ||||
| -rw-r--r-- | usr/src/uts/common/exec/shbin/shbin.c | 10 | ||||
| -rw-r--r-- | usr/src/uts/common/os/exec.c | 30 | ||||
| -rw-r--r-- | usr/src/uts/common/os/exit.c | 15 | ||||
| -rw-r--r-- | usr/src/uts/common/os/fork.c | 29 |
6 files changed, 87 insertions, 22 deletions
diff --git a/usr/src/uts/common/exec/intp/intp.c b/usr/src/uts/common/exec/intp/intp.c index 378e1a0aab..e81957f275 100644 --- a/usr/src/uts/common/exec/intp/intp.c +++ b/usr/src/uts/common/exec/intp/intp.c @@ -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 @@ intpexec( 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; diff --git a/usr/src/uts/common/exec/java/java.c b/usr/src/uts/common/exec/java/java.c index bcf61453c9..7cf9126e8d 100644 --- a/usr/src/uts/common/exec/java/java.c +++ b/usr/src/uts/common/exec/java/java.c @@ -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 @@ javaexec(vnode_t *vp, struct execa *uap, struct uarg *args, 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); diff --git a/usr/src/uts/common/exec/shbin/shbin.c b/usr/src/uts/common/exec/shbin/shbin.c index 7fdd45793b..a6cf129d9d 100644 --- a/usr/src/uts/common/exec/shbin/shbin.c +++ b/usr/src/uts/common/exec/shbin/shbin.c @@ -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 @@ shbinexec( 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; diff --git a/usr/src/uts/common/os/exec.c b/usr/src/uts/common/os/exec.c index 1f17eafdf5..2f03e83563 100644 --- a/usr/src/uts/common/os/exec.c +++ b/usr/src/uts/common/os/exec.c @@ -523,7 +523,7 @@ gexec( 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 @@ gexec( } 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 @@ gexec( 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 @@ gexec( 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; diff --git a/usr/src/uts/common/os/exit.c b/usr/src/uts/common/os/exit.c index 6b7ebc38d7..cf2e3de913 100644 --- a/usr/src/uts/common/os/exit.c +++ b/usr/src/uts/common/os/exit.c @@ -538,10 +538,6 @@ proc_exit(int why, int what) 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 @@ proc_exit(int why, int what) */ 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. */ diff --git a/usr/src/uts/common/os/fork.c b/usr/src/uts/common/os/fork.c index a607142fd5..f75ef84034 100644 --- a/usr/src/uts/common/os/fork.c +++ b/usr/src/uts/common/os/fork.c @@ -974,6 +974,28 @@ getproc(proc_t **cpp, pid_t pid, uint_t flags) 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 @@ getproc(proc_t **cpp, pid_t pid, uint_t flags) 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 @@ getproc(proc_t **cpp, pid_t pid, uint_t flags) */ 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); |
