diff options
Diffstat (limited to 'sys/kern/kern_jail.c')
| -rw-r--r-- | sys/kern/kern_jail.c | 23 | 
1 files changed, 12 insertions, 11 deletions
| diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 3697d95fe0e5..267b60ffb5bc 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -1088,6 +1088,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)  	else {  		if (!(flags & (JAIL_USE_DESC | JAIL_AT_DESC | JAIL_GET_DESC |  		    JAIL_OWN_DESC))) { +			error = EINVAL;  			vfs_opterror(opts, "unexpected desc");  			goto done_errmsg;  		} @@ -2518,6 +2519,7 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)  	} else if (error == 0) {  		if (!(flags & (JAIL_USE_DESC | JAIL_AT_DESC | JAIL_GET_DESC |  		    JAIL_OWN_DESC))) { +			error = EINVAL;  			vfs_opterror(opts, "unexpected desc");  			goto done;  		} @@ -2909,12 +2911,6 @@ prison_remove(struct prison *pr)  {  	sx_assert(&allprison_lock, SA_XLOCKED);  	mtx_assert(&pr->pr_mtx, MA_OWNED); -	if (!prison_isalive(pr)) { -		/* Silently ignore already-dying prisons. */ -		mtx_unlock(&pr->pr_mtx); -		sx_xunlock(&allprison_lock); -		return; -	}  	prison_deref(pr, PD_KILL | PD_DEREF | PD_LOCKED | PD_LIST_XLOCKED);  } @@ -3461,12 +3457,17 @@ prison_deref(struct prison *pr, int flags)  			/* Kill the prison and its descendents. */  			KASSERT(pr != &prison0,  			    ("prison_deref trying to kill prison0")); -			if (!(flags & PD_DEREF)) { -				prison_hold(pr); -				flags |= PD_DEREF; +			if (!prison_isalive(pr)) { +				/* Silently ignore already-dying prisons. */ +				flags &= ~PD_KILL; +			} else { +				if (!(flags & PD_DEREF)) { +					prison_hold(pr); +					flags |= PD_DEREF; +				} +				flags = prison_lock_xlock(pr, flags); +				prison_deref_kill(pr, &freeprison);  			} -			flags = prison_lock_xlock(pr, flags); -			prison_deref_kill(pr, &freeprison);  		}  		if (flags & PD_DEUREF) {  			/* Drop a user reference. */ | 
