DragonFlyBSD Kernel Audit
DF-2936 / boom.c
← back to finding ↓ download raw
/*
 * DF-2936 — module lifecycle desync: module_register_init destroys the
 * module registry entry when MOD_LOAD fails, but the containing KLD load
 * is still reported as successful and the file stays resident.
 *
 * Expected (buggy) behavior when kldload(2)'ed as root:
 *   1. kldload returns SUCCESS (file id) even though MOD_LOAD failed.
 *   2. "boom MOD_LOAD -> deliberately failing" then
 *      "boom MOD_UNLOAD dispatched" appear at LOAD time.
 *   3. The module is GONE from the module registry (kldstat -m boom:
 *      no such module) while the file boom.ko remains loaded.
 *   4. kldunload boom succeeds WITHOUT dispatching MOD_UNLOAD again
 *      (module already destroyed), but DOES run the module's SYSUNINIT
 *      for the long-dead module.
 */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/systm.h>

static int
boom_modevent(module_t mod, int what, void *arg)
{
	switch (what) {
	case MOD_LOAD:
		kprintf("DF2936: boom MOD_LOAD -> deliberately failing (ret 5)\n");
		return (5);			/* deliberate MOD_LOAD failure */
	case MOD_UNLOAD:
		kprintf("DF2936: boom MOD_UNLOAD dispatched\n");
		return (0);
	case MOD_SHUTDOWN:
		return (0);
	default:
		return (EOPNOTSUPP);
	}
}

static moduledata_t boom_mod = { "boom", boom_modevent, NULL };
DECLARE_MODULE(boom, boom_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);

/*
 * Runs at kldunload time (linker_file_sysuninit) — i.e. AFTER the module
 * was already unregistered and freed at load-failure time.
 */
static void
boom_sysuninit(void *unused)
{
	kprintf("DF2936: boom SYSUNINIT running (module destroyed at load time!)\n");
}
SYSUNINIT(boom_sysuninit, SI_SUB_DRIVERS, SI_ORDER_ANY, boom_sysuninit, NULL);