DragonFlyBSD Kernel Audit
DF-0202 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -81,6 +81,14 @@
 	   &umtx_timeout_max, 0, "");
 
 /*
+ * Rate-limit the "can't translate" diagnostic kprintf in umtx_sleep/
+ * umtx_wakeup so an unprivileged user cannot flood the kernel msgbuf /
+ * dmesg / serial console by looping on an unmapped address.  (DF-0202)
+ */
+static struct timeval umtx_phys_lasterr;
+static const struct timeval umtx_phys_err_interval = { 1, 0 }; /* 1/s */
+
+/*
  * If the contents of the userland-supplied pointer matches the specified
  * value enter an interruptable sleep for up to <timeout> microseconds.
  * If the contents does not match then return immediately.
@@ -148,10 +156,11 @@
     } while (waddr == (void *)(intptr_t)-1 && value != -1);
 
     if (value == -1 && waddr == (void *)(intptr_t)-1) {
-	kprintf("umtx_sleep() (A): WARNING can't translate %p (%s %d/%d)\n",
-		uptr, td->td_comm,
-		(int)td->td_proc->p_pid,
-		(int)td->td_lwp->lwp_tid);
+	if (ratecheck(&umtx_phys_lasterr, &umtx_phys_err_interval))
+		kprintf("umtx_sleep() (A): WARNING can't translate %p (%s %d/%d)\n",
+			uptr, td->td_comm,
+			(int)td->td_proc->p_pid,
+			(int)td->td_lwp->lwp_tid);
 	return EINVAL;
     }
 
@@ -287,10 +296,11 @@
     } while (waddr == (void *)(intptr_t)-1 && value != -1);
 
     if (value == -1 && waddr == (void *)(intptr_t)-1) {
-	kprintf("umtx_wakeup() (A): WARNING can't translate %p (%s %d/%d)\n",
-		uptr, td->td_comm,
-		(int)td->td_proc->p_pid,
-		(int)td->td_lwp->lwp_tid);
+	if (ratecheck(&umtx_phys_lasterr, &umtx_phys_err_interval))
+		kprintf("umtx_wakeup() (A): WARNING can't translate %p (%s %d/%d)\n",
+			uptr, td->td_comm,
+			(int)td->td_proc->p_pid,
+			(int)td->td_lwp->lwp_tid);
 	return EINVAL;
     }