diff options
author | cognet <cognet@FreeBSD.org> | 2003-07-04 02:21:28 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2003-07-04 02:21:28 +0000 |
commit | 944ca52c58f2f01b55d450a473099cc3def1c2b2 (patch) | |
tree | f2c38feec5f98da1c2e324b759b285fb28432eeb /sys | |
parent | 4ae39a51c0daaa85c91db9c17c4966813f0ad132 (diff) | |
download | FreeBSD-src-944ca52c58f2f01b55d450a473099cc3def1c2b2.zip FreeBSD-src-944ca52c58f2f01b55d450a473099cc3def1c2b2.tar.gz |
In setpgrp(), don't assume a pgrp won't exist if the provided pgid is the same
as the target process' pid, it may exist if the process forked before leaving
the pgrp.
Thix fixes a panic that happens when calling setpgid to make a process
re-enter the pgrp with the same pgid as its pid if the pgrp still exists.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_prot.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 1ef1ee8..848b82c 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -436,22 +436,23 @@ setpgid(struct thread *td, register struct setpgid_args *uap) } if (uap->pgid == 0) uap->pgid = targp->p_pid; - if (uap->pgid == targp->p_pid) { - if (targp->p_pgid == uap->pgid) - goto done; - error = enterpgrp(targp, uap->pgid, newpgrp, NULL); - if (error == 0) - newpgrp = NULL; - } else { - if ((pgrp = pgfind(uap->pgid)) == NULL || - pgrp->pg_session != curp->p_session) { - if (pgrp != NULL) - PGRP_UNLOCK(pgrp); + if ((pgrp = pgfind(uap->pgid)) == NULL) { + if (uap->pgid == targp->p_pid) { + error = enterpgrp(targp, uap->pgid, newpgrp, + NULL); + if (error == 0) + newpgrp = NULL; + } else error = EPERM; + } else { + if (pgrp == targp->p_pgrp) { + PGRP_UNLOCK(pgrp); goto done; } - if (pgrp == targp->p_pgrp) { + if (pgrp->pg_id != targp->p_pid && + pgrp->pg_session != curp->p_session) { PGRP_UNLOCK(pgrp); + error = EPERM; goto done; } PGRP_UNLOCK(pgrp); |