Change the pfind() and zpfind() functions to lock the process that they

find before releasing the allproc lock and returning.

Reviewed by:	-smp, dfr, jake
This commit is contained in:
John Baldwin 2001-04-24 00:51:53 +00:00
parent 5d69bac493
commit 33a9ed9d0e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=75893
35 changed files with 385 additions and 285 deletions

View File

@ -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);

View File

@ -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 *));

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}
/*

View File

@ -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;
}

View File

@ -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 @@ svr4_sys_waitsys(p, uap)
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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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 *));

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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)

View File

@ -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) */ {

View File

@ -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);

View File

@ -496,11 +496,10 @@ wait1(q, uap, compat)
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);
}
}

View File

@ -328,6 +328,7 @@ ktrace(curp, uap)
error = ESRCH;
goto done;
}
PROC_UNLOCK(p);
if (descend)
ret |= ktrsetchildren(curp, p, ops, facs, vp);
else

View File

@ -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);

View File

@ -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));
}

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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 *));

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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;

View File

@ -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;