diff options
author | Jamie Gritton <jamie@FreeBSD.org> | 2021-01-22 18:56:24 +0000 |
---|---|---|
committer | Jamie Gritton <jamie@FreeBSD.org> | 2021-02-04 23:13:47 +0000 |
commit | 7726fc9940d688af35753a374391de48bad1e1ca (patch) | |
tree | 9cac848300d33228f44bc4140ac577ff99095686 | |
parent | 3f3b216c0b4b90e02b5637f5b07cc9446e1bcee7 (diff) | |
download | src-7726fc9940d688af35753a374391de48bad1e1ca.tar.gz src-7726fc9940d688af35753a374391de48bad1e1ca.zip |
MFC jail: fix dangling reference bug from 6754ae2572eb
The change to use refcounts for pr_uref was mishandled in
prison_proc_free, so killing a jail's last process could add
an extra reference, leaving it an unkillable zombie.
(cherry picked from commit 195cd6ae2481dd5ad555ed65c226b6f20908d66a)
-rw-r--r-- | sys/kern/kern_jail.c | 10 |
1 files changed, 1 insertions, 9 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 318f81fb13be..064f1afa4133 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -2705,7 +2705,6 @@ prison_proc_hold(struct prison *pr) void prison_proc_free(struct prison *pr) { - int lasturef; /* * Locking is only required when releasing the last reference. @@ -2714,11 +2713,7 @@ prison_proc_free(struct prison *pr) */ KASSERT(refcount_load(&pr->pr_uref) > 0, ("Trying to kill a process in a dead prison (jid=%d)", pr->pr_id)); - if (refcount_release_if_not_last(&pr->pr_uref)) - return; - mtx_lock(&pr->pr_mtx); - lasturef = refcount_release(&pr->pr_uref); - if (lasturef) { + if (!refcount_release_if_not_last(&pr->pr_uref)) { /* * Don't remove the last user reference in this context, * which is expected to be a process that is not only locked, @@ -2726,11 +2721,8 @@ prison_proc_free(struct prison *pr) * prison_free() won't re-submit the task. */ refcount_acquire(&pr->pr_ref); - mtx_unlock(&pr->pr_mtx); taskqueue_enqueue(taskqueue_thread, &pr->pr_task); - return; } - mtx_unlock(&pr->pr_mtx); } /* |