⬢ DragonFlyBSD Kernel Audit
DF-5680 / df5680_mod.c
← back to finding ↓ download raw
/*
 * DF-5680 — in-kernel internalize probe (fix validation).
 *
 * Calls prop_dictionary_internalize() directly in the running kernel for
 * the DF-5680 inputs, removing all ambiguity of the DM ioctl error
 * plumbing (dm_check_version() returns EIO for any dict lacking a
 * "version" array, which masked the control's success in the ioctl rig).
 *
 * Expected on the FIXED kernel:
 *   control -> dict OK, data size=5   (non-regression)
 *   plain   -> dict OK, data size=5   (non-regression)
 *   huge    -> NULL                   (2^63 rejected, no panic)
 *   hang    -> NULL                   (8GiB rejected, no wedge)
 * On a STOCK kernel "huge" panics (kmem_slab_alloc kernel_map exhaustion)
 * and "hang" wedges the system — do not load there for those inputs.
 */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <libprop/proplib.h>

static const char *xml_control =
    "<plist version=\"1.0\"><dict><key>a</key>"
    "<data size=\"5\">SGVsbG8=</data></dict></plist>";
static const char *xml_plain =
    "<plist version=\"1.0\"><dict><key>a</key>"
    "<data>SGVsbG8=</data></dict></plist>";
static const char *xml_huge =
    "<plist version=\"1.0\"><dict><key>a</key>"
    "<data size=\"9223372036854775808\">QQ==</data></dict></plist>";
static const char *xml_hang =
    "<plist version=\"1.0\"><dict><key>a</key>"
    "<data size=\"8589934592\">QQ==</data></dict></plist>";

static void
probe(const char *tag, const char *xml)
{
	prop_dictionary_t d = prop_dictionary_internalize(xml);
	prop_data_t pd;

	if (d == NULL) {
		kprintf("DF5680MOD: %-7s -> NULL (rejected, kernel alive)\n",
		    tag);
		return;
	}
	pd = prop_dictionary_get(d, "a");
	kprintf("DF5680MOD: %-7s -> dict OK, data size=%zu\n", tag,
	    pd != NULL ? prop_data_size(pd) : (size_t)-1);
	prop_object_release(d);
}

static int
df5680_modevent(module_t mod __unused, int type, void *arg __unused)
{
	switch (type) {
	case MOD_LOAD:
		probe("control", xml_control);
		probe("plain", xml_plain);
		probe("huge", xml_huge);
		probe("hang", xml_hang);
		kprintf("DF5680MOD: completed without panic/wedge\n");
		return (0);
	default:
		return (EOPNOTSUPP);
	}
}

static moduledata_t df5680_mod = {
	"df5680mod",
	df5680_modevent,
	NULL
};

DECLARE_MODULE(df5680mod, df5680_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);