summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
authorDonghai Qiao <Donghai.Qiao@Sun.COM>2010-02-22 13:53:44 -0500
committerDonghai Qiao <Donghai.Qiao@Sun.COM>2010-02-22 13:53:44 -0500
commita4aeef46cda1835da2b19f8f62b4526de6521e6c (patch)
tree88f8fa8685907fe8c2d2d5853d7dd20f7e0d5639 /usr/src/uts
parent9d3952ab10f8677fdabc8594d26cc1e7d6acdfc4 (diff)
downloadillumos-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.c12
-rw-r--r--usr/src/uts/common/exec/java/java.c13
-rw-r--r--usr/src/uts/common/exec/shbin/shbin.c10
-rw-r--r--usr/src/uts/common/os/exec.c30
-rw-r--r--usr/src/uts/common/os/exit.c15
-rw-r--r--usr/src/uts/common/os/fork.c29
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);