DF-0202 / fix.diff
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; } |