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:
parent
5d69bac493
commit
33a9ed9d0e
@ -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);
|
||||
|
@ -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 *));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 *));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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) */ {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -328,6 +328,7 @@ ktrace(curp, uap)
|
||||
error = ESRCH;
|
||||
goto done;
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
if (descend)
|
||||
ret |= ktrsetchildren(curp, p, ops, facs, vp);
|
||||
else
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 *));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user