DF-1075 / df1075_fixed_pattern.c
/* * DF-1075 "FIXED PATTERN" harness โ replicates the CORRECTED allocation * order from the fix: read descriptor FIRST, then allocate with the real * multicast filter count, then memcpy. This module must NOT panic. * * Contrast with df1075_harness.c (buggy pattern: kmalloc(0) โ ZERO_LENGTH_PTR * โ memcpy โ panic). * * The fix moves sc_mcfilters allocation from kue_attach() to kue_attach_post() * AFTER kue_ctl(KUE_CMD_GET_ETHER_DESCRIPTOR) fills sc->sc_desc. So * KUE_MCFILTCNT(sc) now reflects the device-reported count (e.g. 32), the * kmalloc gets a real size, and the memcpy writes to valid memory. * * Load: kldload ./df1075_fixed_pattern.ko * Effect: prints success messages, returns 0, NO PANIC. */ #include <sys/param.h> #include <sys/module.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/malloc.h> #include <sys/errno.h> #include <sys/types.h> #define HARNESS_ETHER_ADDR_LEN 6 /* Simulate the device-reported kue_mcastfilt value (N=32 filters). * Real KL5KUSB101B hardware advertises 128 (if_kue.c:51 comment). */ #define HARNESS_NFILTERS_FROM_DESC 32 MALLOC_DECLARE(M_HARNESS2); MALLOC_DEFINE(M_HARNESS2, "df1075_fixed", "DF-1075 fixed pattern"); static int df1075_fixed_event(module_t mod, int type, void *arg) { char *mcfilters; char fake_mac[HARNESS_ETHER_ADDR_LEN] = {0x33, 0x33, 0xff, 0x00, 0x00, 0x01}; switch (type) { case MOD_LOAD: /* * FIXED kue_attach_post() pattern (if_kue.c after fix): * kue_ctl(... KUE_CMD_GET_ETHER_DESCRIPTOR ...); // fills sc_desc * sc->sc_mcfilters = kmalloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, ...); * KUE_MCFILTCNT(sc) is now 32 (from the descriptor), so size=192. */ mcfilters = kmalloc(HARNESS_NFILTERS_FROM_DESC * HARNESS_ETHER_ADDR_LEN, M_HARNESS2, M_WAITOK); kprintf("DF-1075-FIXED: kmalloc(%d*%d=%d) returned %p\n", HARNESS_NFILTERS_FROM_DESC, HARNESS_ETHER_ADDR_LEN, HARNESS_NFILTERS_FROM_DESC * HARNESS_ETHER_ADDR_LEN, mcfilters); if (mcfilters == NULL) { kprintf("DF-1075-FIXED: allocation FAILED (unexpected)\n"); return (ENOMEM); } if (mcfilters == (void *)-8) { kprintf("DF-1075-FIXED: BUG STILL PRESENT: got ZERO_LENGTH_PTR!\n"); return (EFAULT); } /* * kue_setmulti() memcpy โ now writes into a properly-sized buffer. */ memcpy(&mcfilters[0], fake_mac, HARNESS_ETHER_ADDR_LEN); kprintf("DF-1075-FIXED: memcpy into &mcfilters[0]=%p SUCCEEDED, no panic\n", &mcfilters[0]); kprintf("DF-1075-FIXED: wrote %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned char)mcfilters[0], (unsigned char)mcfilters[1], (unsigned char)mcfilters[2], (unsigned char)mcfilters[3], (unsigned char)mcfilters[4], (unsigned char)mcfilters[5]); kfree(mcfilters, M_HARNESS2); kprintf("DF-1075-FIXED: kfree OK โ fix verified, no panic\n"); return (0); case MOD_UNLOAD: return (0); default: return (EOPNOTSUPP); } } static moduledata_t df1075_fixed_mod = { "df1075_fixed", df1075_fixed_event, NULL }; DECLARE_MODULE(df1075_fixed, df1075_fixed_mod, SI_SUB_EXEC, SI_ORDER_ANY); MODULE_VERSION(df1075_fixed, 1); |