DragonFlyBSD Kernel Audit
DF-0019 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/usched_bsd4.c b/sys/kern/usched_bsd4.c
--- a/sys/kern/usched_bsd4.c
+++ b/sys/kern/usched_bsd4.c
@@ -1480,7 +1480,8 @@
 	 * Limit the number of checks/queue to a configurable value to
 	 * minimize the contention (we are in a locked region
 	 */
-	while (checks < usched_bsd4_queue_checks) {
+	while (checks < (usched_bsd4_queue_checks > 0 ?
+			 usched_bsd4_queue_checks : 1)) {
 		if (CPUMASK_TESTMASK(lp->lwp_cpumask, cpumask) == 0 ||
 		    (CPUMASK_TESTMASK(siblings,
 				      lp->lwp_thread->td_gd->gd_cpumask) == 0 &&
@@ -1881,6 +1882,23 @@
 	return (0);
 }
 
+/* sysctl queue_checks parameter — reject <= 0 to avoid NULL-deref panic */
+static int
+sysctl_usched_bsd4_queue_checks(SYSCTL_HANDLER_ARGS)
+{
+	int error, new_val;
+
+	new_val = usched_bsd4_queue_checks;
+
+	error = sysctl_handle_int(oidp, &new_val, 0, req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	if (new_val < 1)
+		return (EINVAL);
+	usched_bsd4_queue_checks = new_val;
+	return (0);
+}
+
 /*
  * Setup our scheduler helpers.  Note that curprocmask bit 0 has already
  * been cleared by rqinit() and we should not mess with it further.
@@ -2040,10 +2058,12 @@
 			       &usched_bsd4_upri_affinity, 1,
 			       "Number of PPQs in user priority check");
 
-		SYSCTL_ADD_INT(&usched_bsd4_sysctl_ctx,
+		SYSCTL_ADD_PROC(&usched_bsd4_sysctl_ctx,
 			       SYSCTL_CHILDREN(usched_bsd4_sysctl_tree),
-			       OID_AUTO, "queue_checks", CTLFLAG_RW,
-			       &usched_bsd4_queue_checks, 5,
+			       OID_AUTO, "queue_checks",
+			       CTLTYPE_INT | CTLFLAG_RW,
+			       NULL, sizeof usched_bsd4_queue_checks,
+			       sysctl_usched_bsd4_queue_checks, "I",
 			       "LWPs to check from a queue before giving up");
 
 		SYSCTL_ADD_PROC(&usched_bsd4_sysctl_ctx,