diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2023-07-07 17:19:33 +0000 |
|---|---|---|
| committer | Gordon Tetlow <gordon@FreeBSD.org> | 2024-06-18 17:26:29 +0000 |
| commit | eb410545d00d55a40c4c30eb42b9d2ef5bb2361d (patch) | |
| tree | 042e9d94ac755d8aaff8c0474d7ba5fb7dae04b4 | |
| parent | d45cf1d2f1249d5b30c9fa0d35476dc9b9ee0321 (diff) | |
killpg(): more carefully avoid LoR
Approved by: so
Security: FreeBSD-EN-24:12.killpg
(cherry picked from commit 7a70f17ac4bd64dc1a5020f963ba4380cf37b7e5)
(cherry picked from commit cd73b38955f62d9c05ded8e641a7462ca0f06179)
| -rw-r--r-- | sys/kern/kern_proc.c | 15 | ||||
| -rw-r--r-- | sys/kern/kern_prot.c | 6 |
2 files changed, 15 insertions, 6 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 61c389f0b345..0db3718e15ff 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -587,8 +587,12 @@ enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp, struct session *sess) ("enterpgrp: session leader attempted setpgrp")); old_pgrp = p->p_pgrp; - if (!sx_try_xlock(&old_pgrp->pg_killsx)) + if (!sx_try_xlock(&old_pgrp->pg_killsx)) { + sx_xunlock(&proctree_lock); + sx_xlock(&old_pgrp->pg_killsx); + sx_xunlock(&old_pgrp->pg_killsx); return (ERESTART); + } MPASS(old_pgrp == p->p_pgrp); if (sess != NULL) { @@ -656,11 +660,18 @@ enterthispgrp(struct proc *p, struct pgrp *pgrp) ("%s: p %p belongs to pgrp %p", __func__, p, pgrp)); old_pgrp = p->p_pgrp; - if (!sx_try_xlock(&old_pgrp->pg_killsx)) + if (!sx_try_xlock(&old_pgrp->pg_killsx)) { + sx_xunlock(&proctree_lock); + sx_xlock(&old_pgrp->pg_killsx); + sx_xunlock(&old_pgrp->pg_killsx); return (ERESTART); + } MPASS(old_pgrp == p->p_pgrp); if (!sx_try_xlock(&pgrp->pg_killsx)) { sx_xunlock(&old_pgrp->pg_killsx); + sx_xunlock(&proctree_lock); + sx_xlock(&pgrp->pg_killsx); + sx_xunlock(&pgrp->pg_killsx); return (ERESTART); } diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index a91b7ec3015f..5dea43971e3d 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -345,10 +345,8 @@ again: error = EPERM; } else { error = enterpgrp(p, p->p_pid, newpgrp, newsess); - if (error == ERESTART) { - sx_xunlock(&proctree_lock); + if (error == ERESTART) goto again; - } MPASS(error == 0); td->td_retval[0] = p->p_pid; newpgrp = NULL; @@ -458,11 +456,11 @@ again: error = enterthispgrp(targp, pgrp); } done: - sx_xunlock(&proctree_lock); KASSERT(error == 0 || newpgrp != NULL, ("setpgid failed and newpgrp is NULL")); if (error == ERESTART) goto again; + sx_xunlock(&proctree_lock); uma_zfree(pgrp_zone, newpgrp); return (error); } |
