DF-2396 / fix.diff
--- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1473,12 +1473,20 @@ #endif } + /* + * Mark the handler as running so sysctl_remove_oid_locked()'s + * drain loop actually drains: without this, an oid freed under a + * racing reader leaves a dangling oid / freed arg1 (DF-2396). + */ + atomic_add_int(&oid->oid_running, 1); if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) error = oid->oid_handler(oid, (int *)arg1 + indx, arg2 - indx, req); else error = oid->oid_handler(oid, oid->oid_arg1, oid->oid_arg2, req); + if (atomic_fetchadd_int(&oid->oid_running, -1) == 1) + wakeup(&oid->oid_running); if ((oid->oid_kind & CTLFLAG_NOLOCK) == 0) lockmgr(&oid->oid_lock, LK_RELEASE); |