DragonFlyBSD Kernel Audit
DF-0181 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -222,8 +222,16 @@
 		pr = p->p_ucred->cr_prison;
 	if (p && pr) {
 		if (!PRISON_CAP_ISSET(pr->pr_caps,
-			PRISON_CAP_SYS_SET_HOSTNAME) && req->newptr)
+			PRISON_CAP_SYS_SET_HOSTNAME) && req->newptr) {
+			/*
+			 * We are holding SYSCTL_XLOCK (acquired above for
+			 * the write path); must release it before returning
+			 * or the global sysctl subsystem deadlocks.  (DF-0181)
+			 */
+			SYSCTL_XUNLOCK();
+			SYSCTL_SLOCK();
 			return(EPERM);
+		}
 		error = sysctl_handle_string(oidp,
 		    p->p_ucred->cr_prison->pr_host,
 		    sizeof p->p_ucred->cr_prison->pr_host, req);