diff options
35 files changed, 385 insertions, 285 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 6f22200e0746..f1c7fb588c19 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -542,8 +542,6 @@ linprocfs_doexelink(curp, p, pfs, uio) char *freepath = NULL; p = PFIND(pfs->pfs_pid); - if (p != NULL) - PROC_LOCK(p); if (p == NULL || p->p_cred == NULL || p->p_ucred == NULL) { if (p != NULL) PROC_UNLOCK(p); diff --git a/sys/compat/linprocfs/linprocfs.h b/sys/compat/linprocfs/linprocfs.h index 5cea78a8c55f..862ea19263a5 100644 --- a/sys/compat/linprocfs/linprocfs.h +++ b/sys/compat/linprocfs/linprocfs.h @@ -107,7 +107,7 @@ struct reg; struct fpreg; struct dbreg; -#define PFIND(pid) ((pid) ? pfind(pid) : &proc0) +#define PFIND(pid) (pfind(pid)) void linprocfs_exit __P((struct proc *)); int linprocfs_freevp __P((struct vnode *)); diff --git a/sys/compat/linprocfs/linprocfs_misc.c b/sys/compat/linprocfs/linprocfs_misc.c index 6f22200e0746..f1c7fb588c19 100644 --- a/sys/compat/linprocfs/linprocfs_misc.c +++ b/sys/compat/linprocfs/linprocfs_misc.c @@ -542,8 +542,6 @@ linprocfs_doexelink(curp, p, pfs, uio) char *freepath = NULL; p = PFIND(pfs->pfs_pid); - if (p != NULL) - PROC_LOCK(p); if (p == NULL || p->p_cred == NULL || p->p_ucred == NULL) { if (p != NULL) PROC_UNLOCK(p); diff --git a/sys/compat/linprocfs/linprocfs_subr.c b/sys/compat/linprocfs/linprocfs_subr.c index 809db3cd0c9e..d48d3370e857 100644 --- a/sys/compat/linprocfs/linprocfs_subr.c +++ b/sys/compat/linprocfs/linprocfs_subr.c @@ -199,8 +199,10 @@ linprocfs_rw(ap) p = PFIND(pfs->pfs_pid); if (p == NULL) return (EINVAL); + PROC_UNLOCK(p); } + mp_fixme("pfs_lockowner needs a lock"); while (pfs->pfs_lockowner) { tsleep(&pfs->pfs_lockowner, PRIBIO, "pfslck", 0); } diff --git a/sys/compat/linprocfs/linprocfs_vnops.c b/sys/compat/linprocfs/linprocfs_vnops.c index ecec2d4b39b4..d402cfcaf0d8 100644 --- a/sys/compat/linprocfs/linprocfs_vnops.c +++ b/sys/compat/linprocfs/linprocfs_vnops.c @@ -164,8 +164,11 @@ linprocfs_open(ap) p2 = PFIND(pfs->pfs_pid); if (p2 == NULL) return (ENOENT); - if (pfs->pfs_pid && p_can(ap->a_p, p2, P_CAN_SEE, NULL)) + if (pfs->pfs_pid && p_can(ap->a_p, p2, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p2); return (ENOENT); + } + PROC_UNLOCK(p2); } if (nd->nd_action == procfs_domem) { @@ -216,14 +219,12 @@ linprocfs_close(ap) * has gone away or forgotten about it. */ if ((ap->a_vp->v_usecount < 2) && (p = PFIND(pfs->pfs_pid))) { - PROC_LOCK(p); if (!(p->p_pfsflags & PF_LINGER)) { p->p_stops = 0; p->p_step = 0; - PROC_UNLOCK(p); wakeup(&p->p_step); - } else - PROC_UNLOCK(p); + } + PROC_UNLOCK(p); } } @@ -250,19 +251,17 @@ linprocfs_ioctl(ap) if (procp == NULL) return ENOTTY; - if ((error = p_can(p, procp, P_CAN_DEBUG, NULL))) + if ((error = p_can(p, procp, P_CAN_DEBUG, NULL))) { + PROC_UNLOCK(procp); return (error == ESRCH ? ENOENT : error); + } switch (ap->a_command) { case PIOCBIS: - PROC_LOCK(procp); procp->p_stops |= *(unsigned int*)ap->a_data; - PROC_UNLOCK(procp); break; case PIOCBIC: - PROC_LOCK(procp); procp->p_stops &= ~*(unsigned int*)ap->a_data; - PROC_UNLOCK(procp); break; case PIOCSFL: /* @@ -271,20 +270,17 @@ linprocfs_ioctl(ap) */ #define NFLAGS (PF_ISUGID) flags = (unsigned char)*(unsigned int*)ap->a_data; - if (flags & NFLAGS && (error = suser(p))) + if (flags & NFLAGS && (error = suser(p))) { + PROC_UNLOCK(procp); return error; - PROC_LOCK(procp); + } procp->p_pfsflags = flags; - PROC_UNLOCK(procp); break; case PIOCGFL: - PROC_LOCK(procp); *(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags; - PROC_UNLOCK(procp); /* FALLTHROUGH */ case PIOCSTATUS: psp = (struct procfs_status *)ap->a_data; - PROC_LOCK(procp); psp->state = (procp->p_step == 0); psp->flags = procp->p_pfsflags; psp->events = procp->p_stops; @@ -294,11 +290,9 @@ linprocfs_ioctl(ap) } else { psp->why = psp->val = 0; /* Not defined values */ } - PROC_UNLOCK(procp); break; case PIOCWAIT: psp = (struct procfs_status *)ap->a_data; - PROC_LOCK(procp); if (procp->p_step == 0) { error = msleep(&procp->p_stype, &procp->p_mtx, PWAIT | PCATCH, "piocwait", 0); @@ -312,10 +306,8 @@ linprocfs_ioctl(ap) psp->events = procp->p_stops; psp->why = procp->p_stype; /* why it stopped */ psp->val = procp->p_xstat; /* any extra info */ - PROC_UNLOCK(procp); break; case PIOCCONT: /* Restart a proc */ - PROC_LOCK(procp); if (procp->p_step == 0) { PROC_UNLOCK(procp); return EINVAL; /* Can only start a stopped process */ @@ -328,12 +320,13 @@ linprocfs_ioctl(ap) psignal(procp, signo); } procp->p_step = 0; - PROC_UNLOCK(procp); wakeup(&procp->p_step); break; default: + PROC_UNLOCK(procp); return (ENOTTY); } + PROC_UNLOCK(procp); return 0; } @@ -466,14 +459,15 @@ linprocfs_getattr(ap) procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - PROC_LOCK(procp); if (procp->p_cred == NULL || procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } - PROC_UNLOCK(procp); - if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) + if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) { + PROC_UNLOCK(procp); return (ENOENT); + } + PROC_UNLOCK(procp); } else { procp = NULL; } @@ -589,8 +583,11 @@ linprocfs_access(ap) procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) + if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) { + PROC_UNLOCK(procp); return (ENOENT); + } + PROC_UNLOCK(procp); } vap = &vattr; @@ -676,8 +673,11 @@ linprocfs_lookup(ap) if (p == NULL) goto done; - if (p_can(curp, p, P_CAN_SEE, NULL)) + if (p_can(curp, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); goto done; + } + PROC_UNLOCK(p); error = linprocfs_allocvp(dvp->v_mount, vpp, pid, proc_dir); } @@ -746,8 +746,11 @@ linprocfs_readdir(ap) p = PFIND(pfs->pfs_pid); if (p == NULL) goto done; - if (p_can(curproc, p, P_CAN_SEE, NULL)) + if (p_can(curproc, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); goto done; + } + PROC_UNLOCK(p); } /* diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index ffb280cf9a27..fe422a993c00 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -558,10 +558,11 @@ linux_getpgid(struct proc *p, struct linux_getpgid_args *args) if (args->pid != p->p_pid) { if (!(curp = pfind(args->pid))) return ESRCH; + p->p_retval[0] = curp->p_pgid; + PROC_UNLOCK(curp); } else - curp = p; - p->p_retval[0] = curp->p_pgid; + p->p_retval[0] = p->p_pgid; return 0; } diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 7e6ddd7a13ec..8a35e845c78e 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -1010,6 +1010,7 @@ svr4_sys_pgrpsys(p, uap) * the session leader. */ *retval = (register_t) p->p_session->s_leader->p_pid; + PROC_UNLOCK(p); return 0; case 3: /* setsid() */ @@ -1022,6 +1023,7 @@ svr4_sys_pgrpsys(p, uap) return ESRCH; *retval = (int) p->p_pgrp->pg_id; + PROC_UNLOCK(p); return 0; case 5: /* setpgid(pid, pgid); */ @@ -1264,11 +1266,10 @@ loop: q->p_oppid = 0; q->p_flag &= ~(P_TRACED | P_WAITED); PROC_UNLOCK(q); - PROC_LOCK(t); psignal(t, SIGCHLD); + wakeup(t); PROC_UNLOCK(t); sx_xunlock(&proctree_lock); - wakeup(t); return 0; } } diff --git a/sys/dev/syscons/scmouse.c b/sys/dev/syscons/scmouse.c index fab57da071c9..ccfc2f2a33cc 100644 --- a/sys/dev/syscons/scmouse.c +++ b/sys/dev/syscons/scmouse.c @@ -604,6 +604,7 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, mouse_info_t buf; scr_stat *cur_scp; scr_stat *scp; + struct proc *p1; int s; int f; @@ -755,15 +756,15 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, cur_scp->status &= ~MOUSE_HIDDEN; - if (cur_scp->mouse_signal) { + if (cur_scp->mouse_signal && cur_scp->mouse_proc) { /* has controlling process died? */ - if (cur_scp->mouse_proc && - (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){ + if (cur_scp->mouse_proc != (p1 = pfind(cur_scp->mouse_pid))) { cur_scp->mouse_signal = 0; cur_scp->mouse_proc = NULL; cur_scp->mouse_pid = 0; + if (p1) + PROC_UNLOCK(p1); } else { - PROC_LOCK(cur_scp->mouse_proc); psignal(cur_scp->mouse_proc, cur_scp->mouse_signal); PROC_UNLOCK(cur_scp->mouse_proc); break; @@ -811,14 +812,14 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, cur_scp->status &= ~MOUSE_HIDDEN; - if (cur_scp->mouse_signal) { - if (cur_scp->mouse_proc && - (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){ + if (cur_scp->mouse_signal && cur_scp->mouse_proc) { + if (cur_scp->mouse_proc != (p1 = pfind(cur_scp->mouse_pid))){ cur_scp->mouse_signal = 0; cur_scp->mouse_proc = NULL; cur_scp->mouse_pid = 0; + if (p1) + PROC_UNLOCK(p1); } else { - PROC_LOCK(cur_scp->mouse_proc); psignal(cur_scp->mouse_proc, cur_scp->mouse_signal); PROC_UNLOCK(cur_scp->mouse_proc); break; diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 6d0840025b89..2601c4e64807 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -839,14 +839,20 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case VT_SETMODE: /* set screen switcher mode */ { struct vt_mode *mode; + struct proc *p1; mode = (struct vt_mode *)data; DPRINTF(5, ("sc%d: VT_SETMODE ", sc->unit)); if (scp->smode.mode == VT_PROCESS) { - if (scp->proc == pfind(scp->pid) && scp->proc != p) { + p1 = pfind(scp->pid); + if (scp->proc == p1 && scp->proc != p) { + if (p1) + PROC_UNLOCK(p1); DPRINTF(5, ("error EPERM\n")); return EPERM; } + if (p1) + PROC_UNLOCK(p1); } s = spltty(); if (mode->mode == VT_AUTO) { @@ -2067,6 +2073,7 @@ int sc_switch_scr(sc_softc_t *sc, u_int next_scr) { struct tty *tp; + struct proc *p; int s; DPRINTF(5, ("sc0: sc_switch_scr() %d ", next_scr + 1)); @@ -2086,7 +2093,10 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr) if (sc->switch_in_progress && (sc->cur_scp->smode.mode == VT_PROCESS) && sc->cur_scp->proc) { - if (sc->cur_scp->proc != pfind(sc->cur_scp->pid)) { + p = pfind(sc->cur_scp->pid); + if (sc->cur_scp->proc != p) { + if (p) + PROC_UNLOCK(p); /* * The controlling process has died!!. Do some clean up. * NOTE:`cur_scp->proc' and `cur_scp->smode.mode' @@ -2119,6 +2129,8 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr) DPRINTF(5, ("waiting nothing, ")); } } else { + if (p) + PROC_UNLOCK(p); /* * The controlling process is alive, but not responding... * It is either buggy or it may be just taking time. @@ -2283,8 +2295,12 @@ do_switch_scr(sc_softc_t *sc, int s) static int vt_proc_alive(scr_stat *scp) { + struct proc *p; + if (scp->proc) { - if (scp->proc == pfind(scp->pid)) + if ((p = pfind(scp->pid)) != NULL) + PROC_UNLOCK(p); + if (scp->proc == p) return TRUE; scp->proc = NULL; scp->smode.mode = VT_AUTO; diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h index f0000267b5d7..1c8e5e191fb9 100644 --- a/sys/fs/procfs/procfs.h +++ b/sys/fs/procfs/procfs.h @@ -115,7 +115,7 @@ struct reg; struct fpreg; struct dbreg; -#define PFIND(pid) ((pid) ? pfind(pid) : &proc0) +#define PFIND(pid) (pfind(pid)) void procfs_exit __P((struct proc *)); int procfs_freevp __P((struct vnode *)); diff --git a/sys/fs/procfs/procfs_dbregs.c b/sys/fs/procfs/procfs_dbregs.c index c21597fdb437..948756904d70 100644 --- a/sys/fs/procfs/procfs_dbregs.c +++ b/sys/fs/procfs/procfs_dbregs.c @@ -97,10 +97,6 @@ int procfs_validdbregs(p) struct proc *p; { - int valid; - PROC_LOCK(p); - valid = (p->p_flag & P_SYSTEM) == 0; - PROC_UNLOCK(p); - return (valid); + return ((p->p_flag & P_SYSTEM) == 0); } diff --git a/sys/fs/procfs/procfs_fpregs.c b/sys/fs/procfs/procfs_fpregs.c index 49853c48fc7f..6249f5245ade 100644 --- a/sys/fs/procfs/procfs_fpregs.c +++ b/sys/fs/procfs/procfs_fpregs.c @@ -94,10 +94,6 @@ int procfs_validfpregs(p) struct proc *p; { - int valid; - PROC_LOCK(p); - valid = (p->p_flag & P_SYSTEM) == 0; - PROC_UNLOCK(p); - return (valid); + return ((p->p_flag & P_SYSTEM) == 0); } diff --git a/sys/fs/procfs/procfs_regs.c b/sys/fs/procfs/procfs_regs.c index f0e627d73c88..12efe8530f47 100644 --- a/sys/fs/procfs/procfs_regs.c +++ b/sys/fs/procfs/procfs_regs.c @@ -95,10 +95,6 @@ int procfs_validregs(p) struct proc *p; { - int valid; - PROC_LOCK(p); - valid = (p->p_flag & P_SYSTEM) == 0; - PROC_UNLOCK(p); - return (valid); + return ((p->p_flag & P_SYSTEM) == 0); } diff --git a/sys/fs/procfs/procfs_subr.c b/sys/fs/procfs/procfs_subr.c index 035eb7568c1a..b960b13e3d25 100644 --- a/sys/fs/procfs/procfs_subr.c +++ b/sys/fs/procfs/procfs_subr.c @@ -252,11 +252,13 @@ procfs_rw(ap) int rtval; p = PFIND(pfs->pfs_pid); - if (p == 0) + if (p == NULL) return (EINVAL); + PROC_UNLOCK(p); if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) return (EACCES); + mp_fixme("pfs_lockowner needs a lock"); while (pfs->pfs_lockowner) { tsleep(&pfs->pfs_lockowner, PRIBIO, "pfslck", 0); } diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c index 5dbd01e8946d..c253295c323f 100644 --- a/sys/fs/procfs/procfs_vnops.c +++ b/sys/fs/procfs/procfs_vnops.c @@ -136,34 +136,39 @@ procfs_open(ap) { struct pfsnode *pfs = VTOPFS(ap->a_vp); struct proc *p1, *p2; + int error = 0; p2 = PFIND(pfs->pfs_pid); if (p2 == NULL) return (ENOENT); - if (pfs->pfs_pid && p_can(ap->a_p, p2, P_CAN_SEE, NULL)) - return (ENOENT); + if (pfs->pfs_pid && p_can(ap->a_p, p2, P_CAN_SEE, NULL)) { + error = ENOENT; + goto out; + } switch (pfs->pfs_type) { case Pmem: if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) || - ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) - return (EBUSY); + ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) { + error = EBUSY; + goto out; + } p1 = ap->a_p; if (p_can(p1, p2, P_CAN_DEBUG, NULL) && - !procfs_kmemaccess(p1)) - return (EPERM); + !procfs_kmemaccess(p1)) { + error = EPERM; + } if (ap->a_mode & FWRITE) pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); - return (0); - default: break; } - - return (0); +out: + PROC_UNLOCK(p2); + return (error); } /* @@ -199,14 +204,12 @@ procfs_close(ap) * has gone away or forgotten about it. */ if ((ap->a_vp->v_usecount < 2) && (p = pfind(pfs->pfs_pid))) { - PROC_LOCK(p); if (!(p->p_pfsflags & PF_LINGER)) { p->p_stops = 0; p->p_step = 0; - PROC_UNLOCK(p); wakeup(&p->p_step); - } else - PROC_UNLOCK(p); + } + PROC_UNLOCK(p); } break; default: @@ -237,19 +240,17 @@ procfs_ioctl(ap) return ENOTTY; } - if ((error = p_can(p, procp, P_CAN_DEBUG, NULL))) + if ((error = p_can(p, procp, P_CAN_DEBUG, NULL))) { + PROC_UNLOCK(procp); return (error == ESRCH ? ENOENT : error); + } switch (ap->a_command) { case PIOCBIS: - PROC_LOCK(procp); procp->p_stops |= *(unsigned int*)ap->a_data; - PROC_UNLOCK(procp); break; case PIOCBIC: - PROC_LOCK(procp); procp->p_stops &= ~*(unsigned int*)ap->a_data; - PROC_UNLOCK(procp); break; case PIOCSFL: /* @@ -258,20 +259,17 @@ procfs_ioctl(ap) */ #define NFLAGS (PF_ISUGID) flags = (unsigned char)*(unsigned int*)ap->a_data; - if (flags & NFLAGS && (error = suser(p))) + if (flags & NFLAGS && (error = suser(p))) { + PROC_UNLOCK(procp); return error; - PROC_LOCK(procp); + } procp->p_pfsflags = flags; - PROC_UNLOCK(procp); break; case PIOCGFL: - PROC_LOCK(procp); *(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags; - PROC_UNLOCK(procp); /* FALLTHROUGH */ case PIOCSTATUS: psp = (struct procfs_status *)ap->a_data; - PROC_LOCK(procp); psp->state = (procp->p_step == 0); psp->flags = procp->p_pfsflags; psp->events = procp->p_stops; @@ -281,11 +279,9 @@ procfs_ioctl(ap) } else { psp->why = psp->val = 0; /* Not defined values */ } - PROC_UNLOCK(procp); break; case PIOCWAIT: psp = (struct procfs_status *)ap->a_data; - PROC_LOCK(procp); if (procp->p_step == 0) { error = msleep(&procp->p_stype, &procp->p_mtx, PWAIT | PCATCH, "piocwait", 0); @@ -299,10 +295,8 @@ procfs_ioctl(ap) psp->events = procp->p_stops; psp->why = procp->p_stype; /* why it stopped */ psp->val = procp->p_xstat; /* any extra info */ - PROC_UNLOCK(procp); break; case PIOCCONT: /* Restart a proc */ - PROC_LOCK(procp); if (procp->p_step == 0) { PROC_UNLOCK(procp); return EINVAL; /* Can only start a stopped process */ @@ -315,12 +309,13 @@ procfs_ioctl(ap) psignal(procp, signo); } procp->p_step = 0; - PROC_UNLOCK(procp); wakeup(&procp->p_step); break; default: + PROC_UNLOCK(procp); return (ENOTTY); } + PROC_UNLOCK(procp); return 0; } @@ -436,15 +431,16 @@ procfs_getattr(ap) procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - PROC_LOCK(procp); if (procp->p_cred == NULL || procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } - PROC_UNLOCK(procp); - if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) + if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) { + PROC_UNLOCK(procp); return (ENOENT); + } + PROC_UNLOCK(procp); } error = 0; @@ -657,8 +653,11 @@ procfs_access(ap) procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) + if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) { + PROC_UNLOCK(procp); return (ENOENT); + } + PROC_UNLOCK(procp); } vap = &vattr; @@ -728,8 +727,11 @@ procfs_lookup(ap) if (p == NULL) break; - if (p_can(curp, p, P_CAN_SEE, NULL)) + if (p_can(curp, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); break; + } + PROC_UNLOCK(p); return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc)); @@ -747,8 +749,10 @@ procfs_lookup(ap) (pt->pt_valid == NULL || (*pt->pt_valid)(p))) goto found; } + PROC_UNLOCK(p); break; found: + PROC_UNLOCK(p); return (procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, pt->pt_pfstype)); @@ -824,8 +828,10 @@ procfs_readdir(ap) p = PFIND(pfs->pfs_pid); if (p == NULL) break; - if (p_can(curproc, p, P_CAN_SEE, NULL)) + if (p_can(curproc, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); break; + } for (pt = &proc_targets[i]; uio->uio_resid >= delen && i < nproc_targets; pt++, i++) { @@ -841,6 +847,7 @@ procfs_readdir(ap) if ((error = uiomove((caddr_t)dp, delen, uio)) != 0) break; } + PROC_UNLOCK(p); break; } @@ -962,8 +969,6 @@ procfs_readlink(ap) */ case Pfile: procp = PFIND(pfs->pfs_pid); - if (procp != NULL) - PROC_LOCK(procp); if (procp == NULL || procp->p_cred == NULL || procp->p_ucred == NULL) { if (procp != NULL) diff --git a/sys/i386/isa/pcvt/pcvt_ext.c b/sys/i386/isa/pcvt/pcvt_ext.c index 3f0e95452154..15686f4f5d06 100644 --- a/sys/i386/isa/pcvt/pcvt_ext.c +++ b/sys/i386/isa/pcvt/pcvt_ext.c @@ -59,6 +59,7 @@ static int tri9000_col( int ); static int v7_1024i_col( int ); static int s3_928_col( int ); static int cl_gd542x_col( int ); +static void fallback_to_auto(struct video_state *vsx); /* storage to save video timing values of 80 columns text mode */ static union { @@ -2267,6 +2268,24 @@ reset_usl_modes (struct video_state *vsx) set_auto_mode (vsx); } +/* + * Fallback to VT_AUTO if controlling process died. + */ +static void +fallback_to_auto(struct video_state *vsx) +{ + struct proc *p; + + if(vsx->proc) { + p = pfind(vsx->pid); + if (p != NULL) { + PROC_UNLOCK(p); + if (vsx->proc != p) + set_auto_mode(vsx); + } + } +} + /*---------------------------------------------------------------------------* * switch to virtual screen n (0 ... PCVT_NSCREENS-1), VT_USL version * (the name vgapage() stands for historical reasons) @@ -2280,12 +2299,8 @@ vgapage(int new_screen) return EINVAL; /* fallback to VT_AUTO if controlling processes died */ - if(vsp->proc && vsp->proc != pfind(vsp->pid)) - set_auto_mode(vsp); - - if(vs[new_screen].proc - && vs[new_screen].proc != pfind(vs[new_screen].pid)) - set_auto_mode(&vs[new_screen]); + fallback_to_auto(vsp); + fallback_to_auto(&vs[new_screen]); if (!vt_switch_pending && new_screen == current_video_screen) return 0; @@ -2424,8 +2439,7 @@ usl_vt_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) } /* Check for server died */ - if(vsp->proc && vsp->proc != pfind(vsp->pid)) - set_auto_mode(vsp); + fallback_to_auto(vsp); /* Check for server already running */ if (vsp->smode.mode == VT_PROCESS && vsp->proc != p) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 90023ee9c1a8..9a0a25c0ac9d 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -486,8 +486,11 @@ fsetown(pgid, sigiop) * restrict FSETOWN to the current process or process * group for maximum safety. */ - if (proc->p_session != curproc->p_session) + if (proc->p_session != curproc->p_session) { + PROC_UNLOCK(proc); return (EPERM); + } + PROC_UNLOCK(proc); pgrp = NULL; } else /* if (pgid < 0) */ { diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 2cf1de9dfe05..4156460552a2 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -170,8 +170,10 @@ filt_procattach(struct knote *kn) p = pfind(kn->kn_id); if (p == NULL) return (ESRCH); - if ((error = p_can(curproc, p, P_CAN_SEE, NULL))) + if ((error = p_can(curproc, p, P_CAN_SEE, NULL))) { + PROC_UNLOCK(p); return (error); + } kn->kn_ptr.p_proc = p; kn->kn_flags |= EV_CLEAR; /* automatically set */ @@ -185,7 +187,6 @@ filt_procattach(struct knote *kn) kn->kn_flags &= ~EV_FLAG1; } - PROC_LOCK(p); SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext); PROC_UNLOCK(p); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 3267b21b2574..209210d3ffc9 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -496,11 +496,10 @@ loop: p->p_oppid = 0; proc_reparent(p, t); PROC_UNLOCK(p); - PROC_LOCK(t); psignal(t, SIGCHLD); + wakeup((caddr_t)t); PROC_UNLOCK(t); sx_xunlock(&proctree_lock); - wakeup((caddr_t)t); return (0); } } diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 93a2443fdd3a..393d3da314fc 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -328,6 +328,7 @@ ktrace(curp, uap) error = ESRCH; goto done; } + PROC_UNLOCK(p); if (descend) ret |= ktrsetchildren(curp, p, ops, facs, vp); else diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 67e78bba60fb..8019a27f4877 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -119,15 +119,16 @@ int inferior(p) register struct proc *p; { - int rval = 1; + int rval; - sx_slock(&proctree_lock); - for (; p != curproc; p = p->p_pptr) - if (p->p_pid == 0) { - rval = 0; - break; - } - sx_sunlock(&proctree_lock); + PROC_LOCK_ASSERT(p, MA_OWNED); + if (p == curproc) + return (1); + if (p->p_pid == 0) + return (0); + PROC_LOCK(p->p_pptr); + rval = inferior(p->p_pptr); + PROC_UNLOCK(p->p_pptr); return (rval); } @@ -142,8 +143,10 @@ pfind(pid) sx_slock(&allproc_lock); LIST_FOREACH(p, PIDHASH(pid), p_hash) - if (p->p_pid == pid) + if (p->p_pid == pid) { + PROC_LOCK(p); break; + } sx_sunlock(&allproc_lock); return (p); } @@ -188,8 +191,12 @@ enterpgrp(p, pgid, mksess) */ KASSERT(p->p_pid == pgid, ("enterpgrp: new pgrp and pid != pgid")); - if ((np = pfind(savepid)) == NULL || np != p) + if ((np = pfind(savepid)) == NULL || np != p) { + if (np != NULL) + PROC_UNLOCK(np); return (ESRCH); + } + PROC_UNLOCK(np); MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, M_WAITOK); if (mksess) { @@ -523,8 +530,10 @@ zpfind(pid_t pid) sx_slock(&allproc_lock); LIST_FOREACH(p, &zombproc, p_list) - if (p->p_pid == pid) + if (p->p_pid == pid) { + PROC_LOCK(p); break; + } sx_sunlock(&allproc_lock); return (p); } @@ -535,16 +544,27 @@ sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb) { struct kinfo_proc kinfo_proc; int error; + struct proc *np; pid_t pid = p->p_pid; fill_kinfo_proc(p, &kinfo_proc); error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc)); if (error) return (error); - if (!doingzomb && pid && (pfind(pid) != p)) + if (doingzomb) + np = zpfind(pid); + else { + if (pid == 0) + return (0); + np = pfind(pid); + } + if (np == NULL) return EAGAIN; - if (doingzomb && zpfind(pid) != p) + if (np != p) { + PROC_UNLOCK(np); return EAGAIN; + } + PROC_UNLOCK(np); return (0); } @@ -563,8 +583,11 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) p = pfind((pid_t)name[0]); if (!p) return (0); - if (p_can(curproc, p, P_CAN_SEE, NULL)) + if (p_can(curproc, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); return (0); + } + PROC_UNLOCK(p); error = sysctl_out_proc(p, req, 0); return (error); } @@ -669,8 +692,11 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS) if (!p) return (0); - if ((!ps_argsopen) && p_can(curproc, p, P_CAN_SEE, NULL)) + if ((!ps_argsopen) && p_can(curproc, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); return (0); + } + PROC_UNLOCK(p); if (req->newptr && curproc != p) return (EPERM); @@ -680,9 +706,9 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS) if (req->newptr == NULL) return (error); + PROC_LOCK(p); if (p->p_args && --p->p_args->ar_ref == 0) FREE(p->p_args, M_PARGS); - PROC_LOCK(p); p->p_args = NULL; PROC_UNLOCK(p); diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 8aa90180fccb..33095af67328 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -145,16 +145,18 @@ getpgid(p, uap) struct proc *pt; int error; - pt = p; if (uap->pid == 0) - goto found; - - if ((pt = pfind(uap->pid)) == 0) - return ESRCH; - if ((error = p_can(p, pt, P_CAN_SEE, NULL))) - return (error); -found: - p->p_retval[0] = pt->p_pgrp->pg_id; + p->p_retval[0] = p->p_pgrp->pg_id; + else { + if ((pt = pfind(uap->pid)) == NULL) + return ESRCH; + if ((error = p_can(p, pt, P_CAN_SEE, NULL))) { + PROC_UNLOCK(pt); + return (error); + } + p->p_retval[0] = pt->p_pgrp->pg_id; + PROC_UNLOCK(pt); + } return 0; } @@ -175,16 +177,18 @@ getsid(p, uap) struct proc *pt; int error; - pt = p; if (uap->pid == 0) - goto found; - - if ((pt = pfind(uap->pid)) == 0) - return ESRCH; - if ((error = p_can(p, pt, P_CAN_SEE, NULL))) - return (error); -found: - p->p_retval[0] = pt->p_session->s_sid; + p->p_retval[0] = p->p_session->s_sid; + else { + if ((pt = pfind(uap->pid)) == NULL) + return ESRCH; + if ((error = p_can(p, pt, P_CAN_SEE, NULL))) { + PROC_UNLOCK(pt); + return (error); + } + p->p_retval[0] = pt->p_session->s_sid; + PROC_UNLOCK(pt); + } return 0; } @@ -360,24 +364,42 @@ setpgid(curp, uap) if (uap->pgid < 0) return (EINVAL); if (uap->pid != 0 && uap->pid != curp->p_pid) { - if ((targp = pfind(uap->pid)) == 0 || !inferior(targp)) + if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) { + if (targp) + PROC_UNLOCK(targp); return (ESRCH); - if ((error = p_can(curproc, targp, P_CAN_SEE, NULL))) + } + if ((error = p_can(curproc, targp, P_CAN_SEE, NULL))) { + PROC_UNLOCK(targp); return (error); - if (targp->p_pgrp == NULL || targp->p_session != curp->p_session) + } + if (targp->p_pgrp == NULL || + targp->p_session != curp->p_session) { + PROC_UNLOCK(targp); return (EPERM); - if (targp->p_flag & P_EXEC) + } + if (targp->p_flag & P_EXEC) { + PROC_UNLOCK(targp); return (EACCES); - } else + } + } else { targp = curp; - if (SESS_LEADER(targp)) + PROC_LOCK(curp); /* XXX: not needed */ + } + if (SESS_LEADER(targp)) { + PROC_UNLOCK(targp); return (EPERM); + } if (uap->pgid == 0) uap->pgid = targp->p_pid; else if (uap->pgid != targp->p_pid) if ((pgrp = pgfind(uap->pgid)) == 0 || - pgrp->pg_session != curp->p_session) + pgrp->pg_session != curp->p_session) { + PROC_UNLOCK(targp); return (EPERM); + } + /* XXX: We should probably hold the lock across enterpgrp. */ + PROC_UNLOCK(targp); return (enterpgrp(targp, uap->pgid, 0)); } diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 805d6aafe246..06af873b611f 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -94,14 +94,15 @@ getpriority(curp, uap) case PRIO_PROCESS: if (uap->who == 0) - p = curp; - else + low = curp->p_nice; + else { p = pfind(uap->who); - if (p == 0) - break; - if (p_can(curp, p, P_CAN_SEE, NULL)) - break; - low = p->p_nice; + if (p == NULL) + break; + if (p_can(curp, p, P_CAN_SEE, NULL) == 0) + low = p->p_nice; + PROC_UNLOCK(p); + } break; case PRIO_PGRP: { @@ -159,14 +160,15 @@ setpriority(curp, uap) case PRIO_PROCESS: if (uap->who == 0) - p = curp; - else + error = donice(curp, curp, uap->prio); + else { p = pfind(uap->who); - if (p == 0) - break; - if (p_can(curp, p, P_CAN_SEE, NULL)) - break; - error = donice(curp, p, uap->prio); + if (p == 0) + break; + if (p_can(curp, p, P_CAN_SEE, NULL) == 0) + error = donice(curp, p, uap->prio); + PROC_UNLOCK(p); + } found++; break; @@ -254,9 +256,10 @@ rtprio(curp, uap) if (error) return (error); - if (uap->pid == 0) + if (uap->pid == 0) { p = curp; - else + PROC_LOCK(p); + } else p = pfind(uap->pid); if (p == 0) @@ -267,15 +270,18 @@ rtprio(curp, uap) if ((error = p_can(curp, p, P_CAN_SEE, NULL))) return (error); pri_to_rtp(&p->p_pri, &rtp); + PROC_UNLOCK(p); return (copyout(&rtp, uap->rtp, sizeof(struct rtprio))); case RTP_SET: if ((error = p_can(curp, p, P_CAN_SCHED, NULL))) - return (error); + goto out; /* disallow setting rtprio in most cases if not superuser */ if (suser(curp) != 0) { /* can't set someone else's */ - if (uap->pid) - return (EPERM); + if (uap->pid) { + error = EPERM; + goto out; + } /* can't set realtime priority */ /* * Realtime priority has to be restricted for reasons which should be @@ -287,15 +293,21 @@ rtprio(curp, uap) #if 0 if (RTP_PRIO_IS_REALTIME(rtp.type)) #endif - if (rtp.type != RTP_PRIO_NORMAL) - return (EPERM); + if (rtp.type != RTP_PRIO_NORMAL) { + error = EPERM; + goto out; + } } if (rtp_to_pri(&rtp, &p->p_pri) == 0) - return (0); - return (EINVAL); + error = 0; + else + error = EINVAL; default: - return (EINVAL); + error = EINVAL; } +out: + PROC_UNLOCK(p); + return (error); } int diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index e3f2fdbe5a01..b38723794386 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -898,19 +898,12 @@ killpg1(cp, sig, pgid, all) PROC_UNLOCK(p); continue; } - PROC_UNLOCK(p); - /* - * XXX: this locking needs work.. specifically the - * session checks.. - */ - if (p_cansignal(cp, p, sig)) - continue; - nfound++; - if (sig) { - PROC_LOCK(p); - psignal(p, sig); - PROC_UNLOCK(p); + if (p_cansignal(cp, p, sig) == 0) { + nfound++; + if (sig) + psignal(p, sig); } + PROC_UNLOCK(p); } sx_sunlock(&allproc_lock); } else { @@ -930,22 +923,19 @@ killpg1(cp, sig, pgid, all) PROC_UNLOCK(p); continue; } - PROC_UNLOCK(p); mtx_lock_spin(&sched_lock); if (p->p_stat == SZOMB) { mtx_unlock_spin(&sched_lock); + PROC_UNLOCK(p); continue; } mtx_unlock_spin(&sched_lock); - /* XXX: locking b0rked */ - if (p_cansignal(cp, p, sig)) - continue; - nfound++; - if (sig) { - PROC_LOCK(p); - psignal(p, sig); - PROC_UNLOCK(p); + if (p_cansignal(cp, p, sig) == 0) { + nfound++; + if (sig) + psignal(p, sig); } + PROC_UNLOCK(p); } } return (nfound ? 0 : ESRCH); @@ -971,14 +961,13 @@ kill(cp, uap) /* kill single process */ if ((p = pfind(uap->pid)) == NULL) return (ESRCH); - /* XXX: locking b0rked */ - if (p_cansignal(cp, p, uap->signum)) - return (EPERM); - if (uap->signum) { - PROC_LOCK(p); - psignal(p, uap->signum); + if (p_cansignal(cp, p, uap->signum)) { PROC_UNLOCK(p); + return (EPERM); } + if (uap->signum) + psignal(p, uap->signum); + PROC_UNLOCK(p); return (0); } switch (uap->pid) { diff --git a/sys/kern/p1003_1b.c b/sys/kern/p1003_1b.c index 860176a8e25f..0d1fd0e08506 100644 --- a/sys/kern/p1003_1b.c +++ b/sys/kern/p1003_1b.c @@ -87,9 +87,10 @@ int p31b_proc(struct proc *p, pid_t pid, struct proc **pp) int ret = 0; struct proc *other_proc = 0; - if (pid == 0) + if (pid == 0) { other_proc = p; - else + PROC_LOCK(p); + } else other_proc = pfind(pid); if (other_proc) @@ -100,6 +101,7 @@ int p31b_proc(struct proc *p, pid_t pid, struct proc **pp) *pp = other_proc; else ret = EPERM; + PROC_UNLOCK(other_proc); } else ret = ESRCH; diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index a779711d549a..9414574b57d4 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1034,10 +1034,12 @@ selrecord(selector, sip) mtx_lock_spin(&sched_lock); if (p->p_wchan == (caddr_t)&selwait) { mtx_unlock_spin(&sched_lock); + PROC_UNLOCK(p); sip->si_flags |= SI_COLL; return; } mtx_unlock_spin(&sched_lock); + PROC_UNLOCK(p); } sip->si_pid = mypid; } @@ -1067,12 +1069,9 @@ selwakeup(sip) setrunnable(p); else unsleep(p); - mtx_unlock_spin(&sched_lock); - } else { - mtx_unlock_spin(&sched_lock); - PROC_LOCK(p); + } else p->p_flag &= ~P_SELECT; - PROC_UNLOCK(p); - } + mtx_unlock_spin(&sched_lock); + PROC_UNLOCK(p); } } diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 4255c142c7a5..f6af557219e4 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -211,14 +211,17 @@ ptrace(curp, uap) int write; write = 0; - if (uap->req == PT_TRACE_ME) + if (uap->req == PT_TRACE_ME) { p = curp; - else { + PROC_LOCK(p); + } else { if ((p = pfind(uap->pid)) == NULL) return ESRCH; } - if (p_can(curp, p, P_CAN_SEE, NULL)) + if (p_can(curp, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); return (ESRCH); + } /* * Permissions check @@ -230,19 +233,21 @@ ptrace(curp, uap) case PT_ATTACH: /* Self */ - if (p->p_pid == curp->p_pid) + if (p->p_pid == curp->p_pid) { + PROC_UNLOCK(p); return EINVAL; + } /* Already traced */ - PROC_LOCK(p); if (p->p_flag & P_TRACED) { PROC_UNLOCK(p); return EBUSY; } - PROC_UNLOCK(p); - if ((error = p_can(curp, p, P_CAN_DEBUG, NULL))) + if ((error = p_can(curp, p, P_CAN_DEBUG, NULL))) { + PROC_UNLOCK(p); return error; + } /* OK */ break; @@ -276,7 +281,6 @@ ptrace(curp, uap) case PT_SETDBREGS: #endif /* not being traced... */ - PROC_LOCK(p); if ((p->p_flag & P_TRACED) == 0) { PROC_UNLOCK(p); return EPERM; @@ -296,15 +300,16 @@ ptrace(curp, uap) return EBUSY; } mtx_unlock_spin(&sched_lock); - PROC_UNLOCK(p); /* OK */ break; default: + PROC_UNLOCK(p); return EINVAL; } + PROC_UNLOCK(p); #ifdef FIX_SSTEP /* * Single step fixup ala procfs @@ -374,7 +379,6 @@ ptrace(curp, uap) struct proc *pp; pp = pfind(p->p_oppid); - PROC_LOCK(p); proc_reparent(p, pp ? pp : initproc); } else PROC_LOCK(p); diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h index f0000267b5d7..1c8e5e191fb9 100644 --- a/sys/miscfs/procfs/procfs.h +++ b/sys/miscfs/procfs/procfs.h @@ -115,7 +115,7 @@ struct reg; struct fpreg; struct dbreg; -#define PFIND(pid) ((pid) ? pfind(pid) : &proc0) +#define PFIND(pid) (pfind(pid)) void procfs_exit __P((struct proc *)); int procfs_freevp __P((struct vnode *)); diff --git a/sys/miscfs/procfs/procfs_dbregs.c b/sys/miscfs/procfs/procfs_dbregs.c index c21597fdb437..948756904d70 100644 --- a/sys/miscfs/procfs/procfs_dbregs.c +++ b/sys/miscfs/procfs/procfs_dbregs.c @@ -97,10 +97,6 @@ int procfs_validdbregs(p) struct proc *p; { - int valid; - PROC_LOCK(p); - valid = (p->p_flag & P_SYSTEM) == 0; - PROC_UNLOCK(p); - return (valid); + return ((p->p_flag & P_SYSTEM) == 0); } diff --git a/sys/miscfs/procfs/procfs_fpregs.c b/sys/miscfs/procfs/procfs_fpregs.c index 49853c48fc7f..6249f5245ade 100644 --- a/sys/miscfs/procfs/procfs_fpregs.c +++ b/sys/miscfs/procfs/procfs_fpregs.c @@ -94,10 +94,6 @@ int procfs_validfpregs(p) struct proc *p; { - int valid; - PROC_LOCK(p); - valid = (p->p_flag & P_SYSTEM) == 0; - PROC_UNLOCK(p); - return (valid); + return ((p->p_flag & P_SYSTEM) == 0); } diff --git a/sys/miscfs/procfs/procfs_regs.c b/sys/miscfs/procfs/procfs_regs.c index f0e627d73c88..12efe8530f47 100644 --- a/sys/miscfs/procfs/procfs_regs.c +++ b/sys/miscfs/procfs/procfs_regs.c @@ -95,10 +95,6 @@ int procfs_validregs(p) struct proc *p; { - int valid; - PROC_LOCK(p); - valid = (p->p_flag & P_SYSTEM) == 0; - PROC_UNLOCK(p); - return (valid); + return ((p->p_flag & P_SYSTEM) == 0); } diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c index 035eb7568c1a..b960b13e3d25 100644 --- a/sys/miscfs/procfs/procfs_subr.c +++ b/sys/miscfs/procfs/procfs_subr.c @@ -252,11 +252,13 @@ procfs_rw(ap) int rtval; p = PFIND(pfs->pfs_pid); - if (p == 0) + if (p == NULL) return (EINVAL); + PROC_UNLOCK(p); if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) return (EACCES); + mp_fixme("pfs_lockowner needs a lock"); while (pfs->pfs_lockowner) { tsleep(&pfs->pfs_lockowner, PRIBIO, "pfslck", 0); } diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c index 5dbd01e8946d..c253295c323f 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -136,34 +136,39 @@ procfs_open(ap) { struct pfsnode *pfs = VTOPFS(ap->a_vp); struct proc *p1, *p2; + int error = 0; p2 = PFIND(pfs->pfs_pid); if (p2 == NULL) return (ENOENT); - if (pfs->pfs_pid && p_can(ap->a_p, p2, P_CAN_SEE, NULL)) - return (ENOENT); + if (pfs->pfs_pid && p_can(ap->a_p, p2, P_CAN_SEE, NULL)) { + error = ENOENT; + goto out; + } switch (pfs->pfs_type) { case Pmem: if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) || - ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) - return (EBUSY); + ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) { + error = EBUSY; + goto out; + } p1 = ap->a_p; if (p_can(p1, p2, P_CAN_DEBUG, NULL) && - !procfs_kmemaccess(p1)) - return (EPERM); + !procfs_kmemaccess(p1)) { + error = EPERM; + } if (ap->a_mode & FWRITE) pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); - return (0); - default: break; } - - return (0); +out: + PROC_UNLOCK(p2); + return (error); } /* @@ -199,14 +204,12 @@ procfs_close(ap) * has gone away or forgotten about it. */ if ((ap->a_vp->v_usecount < 2) && (p = pfind(pfs->pfs_pid))) { - PROC_LOCK(p); if (!(p->p_pfsflags & PF_LINGER)) { p->p_stops = 0; p->p_step = 0; - PROC_UNLOCK(p); wakeup(&p->p_step); - } else - PROC_UNLOCK(p); + } + PROC_UNLOCK(p); } break; default: @@ -237,19 +240,17 @@ procfs_ioctl(ap) return ENOTTY; } - if ((error = p_can(p, procp, P_CAN_DEBUG, NULL))) + if ((error = p_can(p, procp, P_CAN_DEBUG, NULL))) { + PROC_UNLOCK(procp); return (error == ESRCH ? ENOENT : error); + } switch (ap->a_command) { case PIOCBIS: - PROC_LOCK(procp); procp->p_stops |= *(unsigned int*)ap->a_data; - PROC_UNLOCK(procp); break; case PIOCBIC: - PROC_LOCK(procp); procp->p_stops &= ~*(unsigned int*)ap->a_data; - PROC_UNLOCK(procp); break; case PIOCSFL: /* @@ -258,20 +259,17 @@ procfs_ioctl(ap) */ #define NFLAGS (PF_ISUGID) flags = (unsigned char)*(unsigned int*)ap->a_data; - if (flags & NFLAGS && (error = suser(p))) + if (flags & NFLAGS && (error = suser(p))) { + PROC_UNLOCK(procp); return error; - PROC_LOCK(procp); + } procp->p_pfsflags = flags; - PROC_UNLOCK(procp); break; case PIOCGFL: - PROC_LOCK(procp); *(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags; - PROC_UNLOCK(procp); /* FALLTHROUGH */ case PIOCSTATUS: psp = (struct procfs_status *)ap->a_data; - PROC_LOCK(procp); psp->state = (procp->p_step == 0); psp->flags = procp->p_pfsflags; psp->events = procp->p_stops; @@ -281,11 +279,9 @@ procfs_ioctl(ap) } else { psp->why = psp->val = 0; /* Not defined values */ } - PROC_UNLOCK(procp); break; case PIOCWAIT: psp = (struct procfs_status *)ap->a_data; - PROC_LOCK(procp); if (procp->p_step == 0) { error = msleep(&procp->p_stype, &procp->p_mtx, PWAIT | PCATCH, "piocwait", 0); @@ -299,10 +295,8 @@ procfs_ioctl(ap) psp->events = procp->p_stops; psp->why = procp->p_stype; /* why it stopped */ psp->val = procp->p_xstat; /* any extra info */ - PROC_UNLOCK(procp); break; case PIOCCONT: /* Restart a proc */ - PROC_LOCK(procp); if (procp->p_step == 0) { PROC_UNLOCK(procp); return EINVAL; /* Can only start a stopped process */ @@ -315,12 +309,13 @@ procfs_ioctl(ap) psignal(procp, signo); } procp->p_step = 0; - PROC_UNLOCK(procp); wakeup(&procp->p_step); break; default: + PROC_UNLOCK(procp); return (ENOTTY); } + PROC_UNLOCK(procp); return 0; } @@ -436,15 +431,16 @@ procfs_getattr(ap) procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - PROC_LOCK(procp); if (procp->p_cred == NULL || procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } - PROC_UNLOCK(procp); - if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) + if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) { + PROC_UNLOCK(procp); return (ENOENT); + } + PROC_UNLOCK(procp); } error = 0; @@ -657,8 +653,11 @@ procfs_access(ap) procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) + if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) { + PROC_UNLOCK(procp); return (ENOENT); + } + PROC_UNLOCK(procp); } vap = &vattr; @@ -728,8 +727,11 @@ procfs_lookup(ap) if (p == NULL) break; - if (p_can(curp, p, P_CAN_SEE, NULL)) + if (p_can(curp, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); break; + } + PROC_UNLOCK(p); return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc)); @@ -747,8 +749,10 @@ procfs_lookup(ap) (pt->pt_valid == NULL || (*pt->pt_valid)(p))) goto found; } + PROC_UNLOCK(p); break; found: + PROC_UNLOCK(p); return (procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, pt->pt_pfstype)); @@ -824,8 +828,10 @@ procfs_readdir(ap) p = PFIND(pfs->pfs_pid); if (p == NULL) break; - if (p_can(curproc, p, P_CAN_SEE, NULL)) + if (p_can(curproc, p, P_CAN_SEE, NULL)) { + PROC_UNLOCK(p); break; + } for (pt = &proc_targets[i]; uio->uio_resid >= delen && i < nproc_targets; pt++, i++) { @@ -841,6 +847,7 @@ procfs_readdir(ap) if ((error = uiomove((caddr_t)dp, delen, uio)) != 0) break; } + PROC_UNLOCK(p); break; } @@ -962,8 +969,6 @@ procfs_readlink(ap) */ case Pfile: procp = PFIND(pfs->pfs_pid); - if (procp != NULL) - PROC_LOCK(procp); if (procp == NULL || procp->p_cred == NULL || procp->p_ucred == NULL) { if (procp != NULL) diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c index 54c51dca00ab..a5f73d66f825 100644 --- a/sys/pc98/pc98/syscons.c +++ b/sys/pc98/pc98/syscons.c @@ -841,14 +841,20 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case VT_SETMODE: /* set screen switcher mode */ { struct vt_mode *mode; + struct proc *p1; mode = (struct vt_mode *)data; DPRINTF(5, ("sc%d: VT_SETMODE ", sc->unit)); if (scp->smode.mode == VT_PROCESS) { - if (scp->proc == pfind(scp->pid) && scp->proc != p) { + p1 = pfind(scp->pid); + if (scp->proc == p1 && scp->proc != p) { + if (p1) + PROC_UNLOCK(p1); DPRINTF(5, ("error EPERM\n")); return EPERM; } + if (p1) + PROC_UNLOCK(p1); } s = spltty(); if (mode->mode == VT_AUTO) { @@ -2081,6 +2087,7 @@ int sc_switch_scr(sc_softc_t *sc, u_int next_scr) { struct tty *tp; + struct proc *p; int s; DPRINTF(5, ("sc0: sc_switch_scr() %d ", next_scr + 1)); @@ -2100,7 +2107,10 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr) if (sc->switch_in_progress && (sc->cur_scp->smode.mode == VT_PROCESS) && sc->cur_scp->proc) { - if (sc->cur_scp->proc != pfind(sc->cur_scp->pid)) { + p = pfind(sc->cur_scp->pid); + if (sc->cur_scp->proc != p) { + if (p) + PROC_UNLOCK(p); /* * The controlling process has died!!. Do some clean up. * NOTE:`cur_scp->proc' and `cur_scp->smode.mode' @@ -2133,6 +2143,8 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr) DPRINTF(5, ("waiting nothing, ")); } } else { + if (p) + PROC_UNLOCK(p); /* * The controlling process is alive, but not responding... * It is either buggy or it may be just taking time. @@ -2297,8 +2309,12 @@ do_switch_scr(sc_softc_t *sc, int s) static int vt_proc_alive(scr_stat *scp) { + struct proc *p; + if (scp->proc) { - if (scp->proc == pfind(scp->pid)) + if ((p = pfind(scp->pid)) != NULL) + PROC_UNLOCK(p); + if (scp->proc == p) return TRUE; scp->proc = NULL; scp->smode.mode = VT_AUTO; diff --git a/sys/posix4/p1003_1b.c b/sys/posix4/p1003_1b.c index 860176a8e25f..0d1fd0e08506 100644 --- a/sys/posix4/p1003_1b.c +++ b/sys/posix4/p1003_1b.c @@ -87,9 +87,10 @@ int p31b_proc(struct proc *p, pid_t pid, struct proc **pp) int ret = 0; struct proc *other_proc = 0; - if (pid == 0) + if (pid == 0) { other_proc = p; - else + PROC_LOCK(p); + } else other_proc = pfind(pid); if (other_proc) @@ -100,6 +101,7 @@ int p31b_proc(struct proc *p, pid_t pid, struct proc **pp) *pp = other_proc; else ret = EPERM; + PROC_UNLOCK(other_proc); } else ret = ESRCH; |