summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2016-11-03 13:34:36 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2016-11-03 17:08:45 +0000
commit319f1706dddd0b2e45c61122ee4a33201f63a466 (patch)
treee331941be4a987254301ef022cc98f0810754798 /usr/src/uts
parentcb5adfa07a7aefc440f5a55351017de82213ea5c (diff)
downloadillumos-joyent-319f1706dddd0b2e45c61122ee4a33201f63a466.tar.gz
OS-5761 some code is careless about p_lock when accessing u_cdir
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Approved by: Patrick Mooney <patrick.mooney@joyent.com>
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_brand.c2
-rw-r--r--usr/src/uts/common/brand/lx/procfs/lx_prsubr.c2
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_getcwd.c2
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_stat.c2
-rw-r--r--usr/src/uts/common/exec/elf/elf_notes.c4
-rw-r--r--usr/src/uts/common/fs/lxproc/lxpr_subr.c4
-rw-r--r--usr/src/uts/common/fs/vfs.c2
-rw-r--r--usr/src/uts/common/os/core.c4
-rw-r--r--usr/src/uts/common/os/exec.c5
-rw-r--r--usr/src/uts/common/os/fork.c2
-rw-r--r--usr/src/uts/common/syscall/uadmin.c4
-rw-r--r--usr/src/uts/common/syscall/umount.c11
12 files changed, 36 insertions, 8 deletions
diff --git a/usr/src/uts/common/brand/lx/os/lx_brand.c b/usr/src/uts/common/brand/lx/os/lx_brand.c
index c615a50f43..fbca57a418 100644
--- a/usr/src/uts/common/brand/lx/os/lx_brand.c
+++ b/usr/src/uts/common/brand/lx/os/lx_brand.c
@@ -2505,9 +2505,11 @@ lx_native_exec(uint8_t osabi, const char **interp)
* Processes which chroot directly into /native will be able to
* function as expected with no need for the prefix.
*/
+ mutex_enter(&curproc->p_lock);
if (VN_CMP(curproc->p_user.u_rdir, curproc->p_zone->zone_rootvp)) {
*interp = "/native";
}
+ mutex_exit(&curproc->p_lock);
return (B_TRUE);
}
diff --git a/usr/src/uts/common/brand/lx/procfs/lx_prsubr.c b/usr/src/uts/common/brand/lx/procfs/lx_prsubr.c
index f4897385d1..4658e95044 100644
--- a/usr/src/uts/common/brand/lx/procfs/lx_prsubr.c
+++ b/usr/src/uts/common/brand/lx/procfs/lx_prsubr.c
@@ -526,6 +526,7 @@ lxpr_getnode(vnode_t *dp, lxpr_nodetype_t type, proc_t *p, int desc)
if (p->p_stat == SZOMB) {
lxpnp->lxpr_realvp = NULL;
} else {
+ ASSERT(MUTEX_HELD(&p->p_lock));
up = PTOU(p);
lxpnp->lxpr_realvp = up->u_cdir;
ASSERT(lxpnp->lxpr_realvp != NULL);
@@ -541,6 +542,7 @@ lxpr_getnode(vnode_t *dp, lxpr_nodetype_t type, proc_t *p, int desc)
if (p->p_stat == SZOMB) {
lxpnp->lxpr_realvp = NULL;
} else {
+ ASSERT(MUTEX_HELD(&p->p_lock));
up = PTOU(p);
lxpnp->lxpr_realvp =
up->u_rdir != NULL ? up->u_rdir : rootdir;
diff --git a/usr/src/uts/common/brand/lx/syscall/lx_getcwd.c b/usr/src/uts/common/brand/lx/syscall/lx_getcwd.c
index 7fcc594d81..275a781fa0 100644
--- a/usr/src/uts/common/brand/lx/syscall/lx_getcwd.c
+++ b/usr/src/uts/common/brand/lx/syscall/lx_getcwd.c
@@ -31,8 +31,10 @@ lx_getcwd(char *buf, int size)
vnode_t *vp;
char path[MAXPATHLEN + 1];
+ mutex_enter(&curproc->p_lock);
vp = PTOU(curproc)->u_cdir;
VN_HOLD(vp);
+ mutex_exit(&curproc->p_lock);
if ((error = vnodetopath(NULL, vp, path, sizeof (path), CRED())) != 0) {
VN_RELE(vp);
return (set_errno(error));
diff --git a/usr/src/uts/common/brand/lx/syscall/lx_stat.c b/usr/src/uts/common/brand/lx/syscall/lx_stat.c
index 9e06cfbe46..9af0080138 100644
--- a/usr/src/uts/common/brand/lx/syscall/lx_stat.c
+++ b/usr/src/uts/common/brand/lx/syscall/lx_stat.c
@@ -429,8 +429,10 @@ lx_fstatat64(int fd, char *name, void *outp, int flag)
* vnode for that fd.
*/
if (fd == AT_FDCWD) {
+ mutex_enter(&curproc->p_lock);
vp = PTOU(curproc)->u_cdir;
VN_HOLD(vp);
+ mutex_exit(&curproc->p_lock);
cr = CRED();
crhold(cr);
} else {
diff --git a/usr/src/uts/common/exec/elf/elf_notes.c b/usr/src/uts/common/exec/elf/elf_notes.c
index 4037507dda..7453f6c745 100644
--- a/usr/src/uts/common/exec/elf/elf_notes.c
+++ b/usr/src/uts/common/exec/elf/elf_notes.c
@@ -26,7 +26,7 @@
/*
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
- * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright 2016, Joyent, Inc.
*/
#include <sys/types.h>
@@ -336,11 +336,13 @@ write_elfnotes(proc_t *p, int sig, vnode_t *vp, offset_t offset,
/* open file table */
+ mutex_enter(&p->p_lock);
vroot = PTOU(p)->u_rdir;
if (vroot == NULL)
vroot = rootdir;
VN_HOLD(vroot);
+ mutex_exit(&p->p_lock);
fip = P_FINFO(p);
diff --git a/usr/src/uts/common/fs/lxproc/lxpr_subr.c b/usr/src/uts/common/fs/lxproc/lxpr_subr.c
index 3c1405d4af..6667233693 100644
--- a/usr/src/uts/common/fs/lxproc/lxpr_subr.c
+++ b/usr/src/uts/common/fs/lxproc/lxpr_subr.c
@@ -24,7 +24,7 @@
*/
/*
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright 2016, Joyent, Inc.
*/
#include <sys/varargs.h>
@@ -413,6 +413,7 @@ lxpr_getnode(vnode_t *dp, lxpr_nodetype_t type, proc_t *p, int fd)
if (p->p_stat == SZOMB) {
lxpnp->lxpr_realvp = NULL;
} else {
+ ASSERT(MUTEX_HELD(&p->p_lock));
up = PTOU(p);
lxpnp->lxpr_realvp = up->u_cdir;
ASSERT(lxpnp->lxpr_realvp != NULL);
@@ -428,6 +429,7 @@ lxpr_getnode(vnode_t *dp, lxpr_nodetype_t type, proc_t *p, int fd)
if (p->p_stat == SZOMB) {
lxpnp->lxpr_realvp = NULL;
} else {
+ ASSERT(MUTEX_HELD(&p->p_lock));
up = PTOU(p);
lxpnp->lxpr_realvp =
up->u_rdir != NULL ? up->u_rdir : rootdir;
diff --git a/usr/src/uts/common/fs/vfs.c b/usr/src/uts/common/fs/vfs.c
index c1b5c12542..fe99756e79 100644
--- a/usr/src/uts/common/fs/vfs.c
+++ b/usr/src/uts/common/fs/vfs.c
@@ -852,9 +852,11 @@ vfs_mountroot(void)
for (p = practive; p != NULL; p = p->p_next) {
ASSERT(p == &p0 || p->p_parent == &p0);
+ mutex_enter(&p->p_lock);
PTOU(p)->u_cdir = rootdir;
VN_HOLD(PTOU(p)->u_cdir);
PTOU(p)->u_rdir = NULL;
+ mutex_exit(&p->p_lock);
}
mutex_exit(&pidlock);
diff --git a/usr/src/uts/common/os/core.c b/usr/src/uts/common/os/core.c
index d4dddbe477..e7634b0a09 100644
--- a/usr/src/uts/common/os/core.c
+++ b/usr/src/uts/common/os/core.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ * Copyright 2016, Joyent Inc.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -124,6 +124,7 @@ remove_core_file(char *fp, enum core_types core_type)
/*
* Determine what rootvp to use.
*/
+ mutex_enter(&curproc->p_lock);
if (core_type == CORE_PROC) {
rootvp = (PTOU(curproc)->u_rdir == NULL ?
curproc->p_zone->zone_rootvp : PTOU(curproc)->u_rdir);
@@ -139,6 +140,7 @@ remove_core_file(char *fp, enum core_types core_type)
VN_HOLD(startvp);
if (rootvp != rootdir)
VN_HOLD(rootvp);
+ mutex_exit(&curproc->p_lock);
if ((error = lookuppnvp(&pn, NULL, NO_FOLLOW, &dvp, &vp, rootvp,
startvp, CRED())) != 0) {
pn_free(&pn);
diff --git a/usr/src/uts/common/os/exec.c b/usr/src/uts/common/os/exec.c
index c330028d2b..2ab4d1f023 100644
--- a/usr/src/uts/common/os/exec.c
+++ b/usr/src/uts/common/os/exec.c
@@ -257,8 +257,10 @@ exec_common(const char *fname, const char **argp, const char **envp,
* only if the pathname does not contain a "/" the resolved path
* points to a file in the current working (attribute) directory.
*/
- if ((p->p_user.u_cdir->v_flag & V_XATTRDIR) != 0 &&
+ mutex_enter(&p->p_lock);
+ if ((PTOU(p)->u_cdir->v_flag & V_XATTRDIR) != 0 &&
strchr(resolvepn.pn_path, '/') == NULL) {
+ mutex_exit(&p->p_lock);
if (dir != NULL)
VN_RELE(dir);
error = EACCES;
@@ -267,6 +269,7 @@ exec_common(const char *fname, const char **argp, const char **envp,
VN_RELE(vp);
goto out;
}
+ mutex_exit(&p->p_lock);
bzero(exec_file, MAXCOMLEN+1);
(void) strncpy(exec_file, pn.pn_path, MAXCOMLEN);
diff --git a/usr/src/uts/common/os/fork.c b/usr/src/uts/common/os/fork.c
index 9fbce63a4c..7e198910b4 100644
--- a/usr/src/uts/common/os/fork.c
+++ b/usr/src/uts/common/os/fork.c
@@ -1219,6 +1219,7 @@ getproc(proc_t **cpp, pid_t pid, uint_t flags)
*/
fcnt_add(P_FINFO(pp), 1);
+ mutex_enter(&pp->p_lock);
if (PTOU(pp)->u_cdir) {
VN_HOLD(PTOU(pp)->u_cdir);
} else {
@@ -1232,6 +1233,7 @@ getproc(proc_t **cpp, pid_t pid, uint_t flags)
VN_HOLD(PTOU(pp)->u_rdir);
if (PTOU(pp)->u_cwd)
refstr_hold(PTOU(pp)->u_cwd);
+ mutex_exit(&pp->p_lock);
/*
* copy the parent's uarea.
diff --git a/usr/src/uts/common/syscall/uadmin.c b/usr/src/uts/common/syscall/uadmin.c
index 68aa1a95f5..7aac5b52a7 100644
--- a/usr/src/uts/common/syscall/uadmin.c
+++ b/usr/src/uts/common/syscall/uadmin.c
@@ -22,7 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright 2013 Joyent, Inc. All rights reserved.
+ * Copyright 2016 Joyent, Inc.
*/
#include <sys/param.h>
@@ -251,6 +251,7 @@ kadmin(int cmd, int fcn, void *mdep, cred_t *credp)
* do not release these resources.
*/
if (ttoproc(curthread) != &p0) {
+ mutex_enter(&curproc->p_lock);
VN_RELE(PTOU(curproc)->u_cdir);
if (PTOU(curproc)->u_rdir)
VN_RELE(PTOU(curproc)->u_rdir);
@@ -260,6 +261,7 @@ kadmin(int cmd, int fcn, void *mdep, cred_t *credp)
PTOU(curproc)->u_cdir = rootdir;
PTOU(curproc)->u_rdir = NULL;
PTOU(curproc)->u_cwd = NULL;
+ mutex_exit(&curproc->p_lock);
}
/*
diff --git a/usr/src/uts/common/syscall/umount.c b/usr/src/uts/common/syscall/umount.c
index a2deedb163..b25f89b6d5 100644
--- a/usr/src/uts/common/syscall/umount.c
+++ b/usr/src/uts/common/syscall/umount.c
@@ -22,6 +22,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2016 Joyent, Inc.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -125,6 +126,7 @@ umount2(char *pathp, int flag)
struct pathname pn;
struct vfs *vfsp;
int error;
+ boolean_t altroot;
/*
* Some flags are disallowed through the system call interface.
@@ -154,9 +156,12 @@ umount2(char *pathp, int flag)
* isn't in an environment with an alternate root (to the zone's root)
* directory, i.e. chroot(2).
*/
- if (secpolicy_fs_unmount(CRED(), NULL) != 0 ||
- (PTOU(curproc)->u_rdir != NULL &&
- PTOU(curproc)->u_rdir != curproc->p_zone->zone_rootvp) ||
+ mutex_enter(&curproc->p_lock);
+ altroot = (PTOU(curproc)->u_rdir != NULL &&
+ PTOU(curproc)->u_rdir != curproc->p_zone->zone_rootvp);
+ mutex_exit(&curproc->p_lock);
+
+ if (secpolicy_fs_unmount(CRED(), NULL) != 0 || altroot ||
(vfsp = vfs_mntpoint2vfsp(pn.pn_path)) == NULL) {
vnode_t *fsrootvp;