⬢ DragonFlyBSD Kernel Audit
DF-5693 / fix.diff
← back to finding ↓ download raw
--- a/sys/libprop/prop_bool.c
+++ b/sys/libprop/prop_bool.c
@@ -105,9 +105,34 @@ _prop_bool_equals(prop_object_t v1, prop_object_t v2,
 		return (_PROP_OBJECT_EQUALS_FALSE);
 }
 
+#if defined(_KERNEL)
+static int	_prop_bool_init(void);
+#endif
+
 _PROP_ONCE_DECL(_prop_bool_init_once)
 
+#if defined(_KERNEL)
+/*
+ * DF-5693: complete the lazy singleton initialization single-threaded
+ * at SI_SUB_PROP, the same SYSINIT point the other proplib registries
+ * bootstrap at.  The kernel flavor of _PROP_ONCE_RUN
+ * (prop_object_impl.h:302-303) is a cmpset-once with no completion
+ * barrier: a CPU that loses the cmpset proceeds immediately and runs
+ * the _prop_bool_alloc body (prop_bool.c:132-135) against singletons
+ * whose po_type / pb_value may not be stored yet.  Nothing in the
+ * kernel consumes prop_bool during boot, so the cmpset window is live
+ * at the first-ever <true/>/<false/> internalize (e.g. a dm ioctl
+ * plist), which on an MP system can be two concurrent first uses.
+ * Bootstrapping here closes the window without adding a spin to the
+ * hot path; the #ifdef keeps the shared userland libprop build
+ * (lib/libprop compiles this very file with -D_LIBPROP) intact.
+ */
+static void
+_prop_bool_bootstrap(void *unused __unused)
+{
+	_PROP_ONCE_RUN(_prop_bool_init_once, _prop_bool_init);
+}
+
+SYSINIT(prop_bool, SI_SUB_PROP, SI_ORDER_ANY,
+	(sysinit_cfunc_t)_prop_bool_bootstrap, NULL);
+#endif /* _KERNEL */
+
 static int
 _prop_bool_init(void)
 {