DragonFlyBSD Kernel Audit
DF-2936 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/kern_module.c
+++ b/sys/kern/kern_module.c
@@ -104,13 +104,22 @@
 	    panic("module_register_init: register of module failed! %d", error);
 	mod = module_lookupbyname(data->name);
 	if (mod == NULL)
 	    panic("module_register_init: module STILL not found!");
 #endif
     }
     error = MOD_EVENT(mod, MOD_LOAD);
     if (error) {
-	module_unload(mod);	/* ignore error */
-	module_release(mod);
+	/*
+	 * DF-2936: Do NOT destroy the module here.  The containing
+	 * linker file is still resident (and kldload(2) reports
+	 * success, since SYSINIT errors cannot propagate), so tearing
+	 * the registry entry down behind the linker's back desynchronizes
+	 * the module lifecycle from the file lifecycle: the module
+	 * becomes invisible to modstat(2)/kldstat while its code and
+	 * SYSUNINITs remain resident.  Leave the registration in place;
+	 * linker_file_unload() dispatches MOD_UNLOAD and drops the
+	 * registration reference exactly once at file unload time.
+	 */
 	kprintf("module_register_init: MOD_LOAD (%s, %lx, %p) error %d\n",
 	       data->name, (u_long)data->evhand, data->priv, error);
     }