diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-11-03 13:34:36 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-11-03 17:08:45 +0000 |
| commit | 319f1706dddd0b2e45c61122ee4a33201f63a466 (patch) | |
| tree | e331941be4a987254301ef022cc98f0810754798 /usr/src/uts | |
| parent | cb5adfa07a7aefc440f5a55351017de82213ea5c (diff) | |
| download | illumos-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.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/procfs/lx_prsubr.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_getcwd.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_stat.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/exec/elf/elf_notes.c | 4 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/lxproc/lxpr_subr.c | 4 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/vfs.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/os/core.c | 4 | ||||
| -rw-r--r-- | usr/src/uts/common/os/exec.c | 5 | ||||
| -rw-r--r-- | usr/src/uts/common/os/fork.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/syscall/uadmin.c | 4 | ||||
| -rw-r--r-- | usr/src/uts/common/syscall/umount.c | 11 |
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; |
