Multicast filter buffer allocated before device descriptor is read -> OOB write / kernel panic on interface up
| Field | Value |
|---|---|
| ID | DF-1075 |
| Status | new |
| Severity | Medium |
| CVSS 3.1 | CVSS:3.1/AV:P/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H |
| CWE | CWE-131 Incorrect Calculation of Buffer Size (CWE-787 consequence) |
| File | sys/bus/u4b/net/if_kue.c |
| Lines | 488-493 (allocation in kue_attach), 439-440 (descriptor read in kue_attach_post), 381-385 (memcpy in kue_setmulti) |
| Area | bus/u4b/net (Kawasaki LSI KL5KUSB101B USB Ethernet) |
| Confidence | certain |
| Discovered | 2026-07-14 |
| Reported | pending |
| Known CVE | none |
| CVE match | dfly_specific |
Summary
kue_attach() allocates sc->sc_mcfilters using KUE_MCFILTCNT(sc), but the device
descriptor that KUE_MCFILTCNT reads has not been fetched yet at that point (it is only
read later in kue_attach_post()). The softc is zero-initialised by newbus, so
KUE_MCFILTCNT(sc) is 0, kmalloc(0) returns the sentinel ZERO_LENGTH_PTR = (void *)-8
(kern_slaballoc.c:193, 890), and the NULL check at line 490 passes because
(void *)-8 != NULL. Later, a malicious (or even legitimate) USB device reports
kue_mcastfilt >= 1 in GET_ETHER_DESCRIPTOR; on the next multicast reconfiguration (which
happens automatically when the interface is brought up due to default IPv6 multicast),
kue_setmulti() memcpy()s ETHER_ADDR_LEN bytes into &ZERO_LENGTH_PTR[0] =
0xFFFF...FFF8 on x86-64, an unmapped kernel address, causing a page fault and immediate
kernel panic. The write target is the fixed ZERO_LENGTH_PTR sentinel, which the attacker
cannot redirect, so this is a reliable DoS with no path to code execution.
Root cause
Walkthrough:
-
kue_attach()(if_kue.c:468) runs first; at line 488 it callssc->sc_mcfilters = kmalloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, M_USBDEV, M_WAITOK). -
KUE_MCFILTCNTis defined inif_kuereg.h:69as(UGETW((x)->sc_desc.kue_mcastfilt) & 0x7FFF)β i.e., it reads auint16out of the device descriptor. At this instantsc_descis whatever newbus left: device softcs are zero-allocated withM_ZEROatsubr_bus.c:1953-1954, sokue_mcastfilt = {0, 0},KUE_MCFILTCNT(sc) = 0, and0 * ETHER_ADDR_LEN = 0. -
DragonFlyBSD's slab allocator returns the sentinel
ZERO_LENGTH_PTRforkmalloc(0)(kern_slaballoc.c:888-891, withZERO_LENGTH_PTR = (void *)-8at line 193). -
The subsequent
if (sc->sc_mcfilters == NULL)test atif_kue.c:490does NOT catch this because(void *)-8is non-NULL. -
kue_attach()then callsuether_ifattach()(line 501), which queuesue_attach_post_task; the post task callskue_attach_post()(if_kue.c:422-444), which loads firmware, resets the chip, and only THEN reads the descriptor at lines 439-440 viakue_ctl(KUE_CMD_GET_ETHER_DESCRIPTOR, &sc->sc_desc, sizeof(sc->sc_desc)). A malicious device supplieskue_mcastfiltencoding any value N >= 1, soKUE_MCFILTCNT(sc)now returns N. Thesc_mcfiltersbuffer is NEVER reallocated β it is still the 0-byteZERO_LENGTH_PTR. -
When
kue_setmulti()(if_kue.c:354-398) runs in response toSIOCADDMULTI(queued fromuether_ioctl()atusb_ethernet.c:497-504), the loop at lines 373-387 iteratesifrom 0; for each AF_LINK multicast entry withi < KUE_MCFILTCNT(sc)it executesmemcpy(KUE_MCFILT(sc, i), ..., ETHER_ADDR_LEN)(lines 383-385). -
KUE_MCFILT(sc, i)expands (if_kuereg.h:70-71) to(char *)&sc->sc_mcfilters[i * ETHER_ADDR_LEN], which fori = 0is(char *)ZERO_LENGTH_PTR + 0 = (char *)0xFFFFFFFFFFFFFFF8on x86-64. The first suchmemcpywrites 6 bytes starting at an unmapped kernel address and the CPU traps with a page fault, immediately panic'ing the kernel.
Because every iteration writes to the fixed sentinel (which is always unmapped), there is no path by which the attacker can land the write on a mapped, attacker-influenced region β this caps impact at denial of service.
Note that real KL5KUSB101B hardware reportedly advertises a 128-entry filter (comment at
if_kue.c:51), so this bug does not require a malicious device; any genuine kue(4)
NIC whose firmware reports a non-zero multicast filter count will panic the host the moment
its interface is brought up with IPv6 enabled.
Threat model & preconditions
- Attacker position: Anyone who can attach a USB device to the target β physical
plug-in, USB-C charging station, compromised USB hub, or a BadUSB / Rubber-Ducky-class
gadget. No kernel privileges and no authentication are needed. The device must merely
present one of the ~30 supported (VID, PID) pairs (
if_kue.c:104-139, all trivially spoofable via a USB gadget), accept theKUE_CMD_SEND_SCANfirmware-download requests (return success / stall βkue_load_fwignores some failures andkue_attach_postignores the rest at line 430-433), and respond toKUE_CMD_GET_ETHER_DESCRIPTORwithkue_mcastfilt >= 1. - Privileges gained or impact: Complete system crash / reboot (A:H). No confidentiality
or integrity impact because the write address is the unredirectable
ZERO_LENGTH_PTRsentinel in unmapped KVA. - Required config or capabilities: Default kernel with
kue. LocalueNinterface brought up (often automatic via NetworkManager / dhcpcd / default IPv6). - Reachability: Trigger sequence:
1. Plug in malicious kue-identifying USB device.
2.
kuedriver attaches βkue_attach()(allocates 0-byte buffer) βkue_attach_post()(reads malicious descriptor). 3. Interface is brought up (ifconfig ueN upβ commonly done automatically). 4. IPv6 stack installs the solicited-node and all-nodes multicast addresses (33:33:00:00:00:01,33:33:ff:<last3>) β firesSIOCADDMULTIβkue_setmulti()β OOB write β page fault β kernel panic.
Proof of PoC
Two-part PoC.
(A) Malicious USB device side β implemented as a Linux USB gadget (Pi Zero W / BeagleBone / any configfs-gadget target) or a Facedancer board.
- Device descriptor:
bcdDevice != 0x0202(sokue_load_fwdoesn't early-return atif_kue.c:305-306) and one of thekue_devs[]VID/PID tuples, e.g.idVendor=0x04cf(KLSI),idProduct=0x0001(DUH3E10BT). - Control endpoint handlers:
1. ACK or accept the three
KUE_CMD_SEND_SCAN (0xFF)OUT requests carryingkue_code_seg/kue_fix_seg/kue_trig_seg(size and content do not matter βkue_ctljust needs to return success). 2. Respond to the vendor IN requestbmRequestType=0xC0 bRequest=0x00(KUE_CMD_GET_ETHER_DESCRIPTOR) with a 16-bytekue_ether_descwhose bytes[12..13](kue_mcastfilt) are little-endian >= 1, e.g.0x20 0x00(N=32); the remaining bytes can be anything.
(B) Host trigger β after the device enumerates and the kue driver attaches:
sudo ifconfig ue0 up # or just wait for dhcpcd / NetworkManager to do it.
On a DragonFlyBSD host with IPv6 enabled (the default), the in-kernel IPv6 code will
immediately add 33:33:00:00:00:01 and 33:33:ff:xx:xx:xx to the interface, triggering
SIOCADDMULTI and thus kue_setmulti(). The first memcpy into &ZERO_LENGTH_PTR[0]
panics the kernel.
Build & run
# gadget descriptor Python (pyusb/facedancer) runs on the attacker device python3 kue_evil_gadget.py # host side: nothing to compile, just bring up the interface sudo ifconfig ue0 up
Expected output
Fatal trap 12: page fault while in kernel mode fault virtual address = 0xFFFFFFFFFFFFFFF8 cpuid = 0 instruction pointer = 0x<PC inside memcpy> kue_setmulti(...) at if_kue.c:383 ... panic: from-rights-free
Impact
Reliable kernel panic from a USB plug-in + interface up. The write is to the
unredirectable ZERO_LENGTH_PTR sentinel so no code-execution primitive. Medium severity
per "physical access + automatic trigger" + "reliable DoS". Affects both malicious and
legitimate kue NICs.
Recommended fix
Move the sc_mcfilters allocation from kue_attach() (where KUE_MCFILTCNT is 0 because
the descriptor has not been read) into kue_attach_post() (where it has just been read),
and guard the kfree() in kue_detach() because DragonFlyBSD's kfree(NULL) panics
(kern_slaballoc.c:1406-1407) while kfree(ZERO_LENGTH_PTR) is a no-op β so removing the
early kmalloc(0) leaves sc_mcfilters == NULL on the uether_ifattach-failure path,
which must not be freed.
--- a/sys/bus/u4b/net/if_kue.c
+++ b/sys/bus/u4b/net/if_kue.c
@@ -435,6 +435,17 @@ kue_attach_post(struct usb_ether *ue)
/* read ethernet descriptor */
kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
0, &sc->sc_desc, sizeof(sc->sc_desc));
+
+ /*
+ * Allocate the multicast filter buffer now that the device has
+ * reported its multicast filter capacity in the descriptor above.
+ * This MUST happen here, not in kue_attach(): at kue_attach() time
+ * the descriptor has not been fetched yet and the zero-initialised
+ * softc would yield KUE_MCFILTCNT(sc)==0, producing a zero-length
+ * allocation that kue_setmulti() would later write past.
+ */
+ sc->sc_mcfilters = kmalloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
+ M_USBDEV, M_WAITOK);
/* copy in ethernet address */
memcpy(ue->ue_eaddr, sc->sc_desc.kue_macaddr, sizeof(ue->ue_eaddr));
}
@@ -485,13 +496,6 @@ kue_attach(device_t dev)
goto detach;
}
- sc->sc_mcfilters = kmalloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
- M_USBDEV, M_WAITOK);
- if (sc->sc_mcfilters == NULL) {
- device_printf(dev, "failed allocating USB memory\n");
- goto detach;
- }
-
ue->ue_sc = sc;
ue->ue_dev = dev;
ue->ue_udev = uaa->device;
@@ -514,12 +518,15 @@ static int
kue_detach(device_t dev)
{
struct kue_softc *sc = device_get_softc(dev);
struct usb_ether *ue = &sc->sc_ue;
usbd_transfer_unsetup(sc->sc_xfer, KUE_N_TRANSFER);
uether_ifdetach(ue);
+
+ /* kfree(NULL) panics on DragonFlyBSD, so guard the free for the
+ * uether_ifattach-failure path where kue_attach_post never ran. */
+ if (sc->sc_mcfilters != NULL)
+ kfree(sc->sc_mcfilters, M_USBDEV);
lockuninit(&sc->sc_lock);
- kfree(sc->sc_mcfilters, M_USBDEV);
return (0);
}
A defense-in-depth follow-up would also cap KUE_MCFILTCNT (e.g.
min(UGETW(...) & 0x7FFF, 128)) so a malicious device cannot force a ~192 KB allocation,
and would widen the i * ETHER_ADDR_LEN argument to kue_ctl() / USETW(wLength) so it
does not silently truncate when i * 6 > 65535.
References
sys/bus/u4b/net/if_kue.c:488-493β the premature allocationsys/bus/u4b/net/if_kue.c:439-440β descriptor read inkue_attach_postsys/bus/u4b/net/if_kue.c:381-385βmemcpy(KUE_MCFILT(sc, i), ..., ETHER_ADDR_LEN)sys/bus/u4b/net/if_kuereg.h:69-71βKUE_MCFILTCNT/KUE_MCFILTmacrossys/kern/kern_slaballoc.c:193, 888-891βZERO_LENGTH_PTRandkmalloc(0)sys/kern/subr_bus.c:1953-1954β newbusM_ZEROsoftc allocation- CWE-131 Incorrect Calculation of Buffer Size
- CWE-787 Out-of-bounds Write
Timeline
- 2026-07-14 Discovered during automated audit.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1075 Β· 15 files| File | Type | Description | Size | |
|---|---|---|---|---|
| df1075_harness.c | trigger-source | kernel-module harness replicating the exact buggy kmalloc(0)+memcpy pattern from if_kue.c | 3.4 KB | view raw |
| df1075_fixed_pattern.c | exploit-chain | fixed-pattern harness demonstrating corrected allocation order (no panic) | 3.0 KB | view raw |
| Makefile | build-script | kmod Makefile for buggy harness | 190 B | β download |
| Makefile.fixed | build-script | kmod Makefile for fixed-pattern harness | 131 B | β download |
| build.sh | build-log | build script for both harnesses | 439 B | view raw |
| run.sh | run-log | run script (buggy/fixed modes) | 1.4 KB | view raw |
| panic_full.txt | panic-signature | Fatal trap 12: page fault at 0xFFFFFFFFFFFFFFF8 from buggy harness on unpatched #0 kernel | 987 B | view raw |
| panic.txt | panic-signature | panic excerpt with DF-1075 harness kprintf markers | 677 B | view raw |
| fix.diff | suggested-fix | git-apply-able fix: move sc_mcfilters alloc to kue_attach_post, guard kfree in kue_detach | 1.8 KB | view raw |
| fix_build.log | build-log | full nativekernel build output for single-fix kernel (rc=0) | 5.6 MB | β download |
| env.txt | environment | uname, cc version, sysctl, patched source line numbers | 650 B | view raw |
| VERDICT.md | verdict | full narrative: mechanism, source trace, harness proof, fix validation | 5.7 KB | β raw |
| README.md | readme | human-readable PoC overview and reproduction instructions | 2.9 KB | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-1075 PoC β Multicast filter buffer allocated before device descriptor is read
Bug
kue_attach() (sys/bus/u4b/net/if_kue.c:488-493) allocates
sc->sc_mcfilters = kmalloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, ...) BEFORE
the device descriptor is read. At this point sc_desc is zero-initialised,
so KUE_MCFILTCNT(sc) == 0, and kmalloc(0) returns ZERO_LENGTH_PTR =
(void *)-8. The NULL check at line 490 does not catch (void *)-8. Later,
kue_attach_post() reads the real descriptor (if_kue.c:439-440), but the
buffer is never reallocated. When kue_setmulti() memcpy's into
KUE_MCFILT(sc, 0) = &sc->sc_mcfilters[0] = (char *)-8, the kernel panics
with a page fault at the unmapped ZERO_LENGTH_PTR address.
PoC approach
The actual kue(4) driver requires physical USB hardware (a KLSI
KL5KUSB101B USB-Ethernet adapter or a malicious USB gadget). This KVM guest
has no USB devices. The bug is therefore demonstrated by:
- Source-level trace β every cited line confirmed in
sys/. - Kernel-module harness (
df1075_harness.c) that replicates the exact buggykmalloc(0)+memcpypattern and produces the predicted panic.
The real attacker-side PoC (for hardware-equipped targets):
- Malicious USB gadget presenting a supported (VID, PID) (e.g. 0x04cf:0x0001),
accepting KUE_CMD_SEND_SCAN firmware-download requests, and responding to
KUE_CMD_GET_ETHER_DESCRIPTOR with kue_mcastfilt >= 1.
- Host brings up the interface (ifconfig ue0 up, often automatic).
- IPv6 adds multicast addresses β SIOCADDMULTI β kue_setmulti() β panic.
Build (inside the guest, as root)
cd /root/poc_df1075 && make # buggy-pattern harness
cd /root/poc_df1075_fixed && make # fixed-pattern harness
Run
# On UNPATCHED kernel (#0): loads buggy harness β guest panics
kldload /root/poc_df1075/df1075_harness.ko
# On FIXED kernel (#1): loads fixed-pattern harness β no panic
kldload /root/poc_df1075_fixed/df1075_fixed.ko
dmesg | tail -6
Expected output
Buggy harness (unpatched #0):
Fatal trap 12: page fault while in kernel mode fault virtual address = 0xfffffffffffffff8 fault code = supervisor write data, page not present Stopped at df1075_modevent+0x91: movl $0x3333,(%rbx)
Guest is down (DDB prompt).
Fixed-pattern harness (patched #1):
DF-1075-FIXED: kmalloc(32*6=192) returned 0xfffff8004f22ccd0 DF-1075-FIXED: memcpy into &mcfilters[0]=0xfffff8004f22ccd0 SUCCEEDED, no panic DF-1075-FIXED: wrote 33:33:ff:00:00:01 DF-1075-FIXED: kfree OK β fix verified, no panic
Guest stays up.
Impact
Reliable kernel panic (DoS) from USB device plug-in + interface up. The write
target is the fixed ZERO_LENGTH_PTR sentinel ((void *)-8), which the
attacker cannot redirect, so there is no path to code execution. Medium
severity (physical access + automatic trigger). Affects both malicious and
legitimate kue NICs.
DF-1075 β Multicast filter buffer allocated before device descriptor is read β OOB write / kernel panic
Finding
kue_attach() in sys/bus/u4b/net/if_kue.c allocates sc->sc_mcfilters
via kmalloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, ...) at a point where the
device descriptor (sc->sc_desc) has NOT been fetched yet. Because the softc
is zero-initialised by newbus (M_ZERO), KUE_MCFILTCNT(sc) reads
UGETW(sc_desc.kue_mcastfilt) & 0x7FFF == 0, so the allocation is
kmalloc(0). DragonFlyBSD's slab allocator returns ZERO_LENGTH_PTR =
(void *)-8 for zero-length allocations
(sys/kern/kern_slaballoc.c:888-891, #define ZERO_LENGTH_PTR ((void *)-8)
at line 193). The subsequent NULL check at if_kue.c:490 does NOT catch
this because (void *)-8 != NULL.
Later, kue_attach_post() fetches the real descriptor (if_kue.c:439-440)
and a malicious (or legitimate) device reports kue_mcastfilt >= 1. The
sc_mcfilters buffer is NEVER reallocated. When kue_setmulti() runs
(if_kue.c:383-385), it does memcpy(KUE_MCFILT(sc, i), ..., ETHER_ADDR_LEN)
where KUE_MCFILT(sc, 0) = &sc->sc_mcfilters[0] = (char *)-8 + 0 β an
unmapped kernel address. The write faults and the kernel panics.
Impact: Reliable kernel panic (DoS) from USB device attachment + interface
up. The write target is the fixed ZERO_LENGTH_PTR sentinel, which the
attacker cannot redirect, so there is no path to code execution. Medium
severity (physical access + automatic trigger).
Verification approach
This KVM guest has no USB hardware β usbconfig list returns "No device
match", and QEMU cannot emulate a KLSI KL5KUSB101B adapter. The actual
kue(4) driver cannot be triggered. Therefore the bug is verified by:
- Source-level trace β every cited line confirmed in
sys/. - Kernel-module harness replicating the exact buggy allocation+write pattern, which produces the exact predicted panic.
Source trace (all confirmed)
| Claim | Citation | Verified |
|---|---|---|
kue_attach() allocates sc_mcfilters before descriptor read |
if_kue.c:488-493 |
β |
KUE_MCFILTCNT(sc) reads sc_desc.kue_mcastfilt via UGETW |
if_kuereg.h:69 |
β |
UGETW({0,0}) == 0 |
usb_endian.h:49-51 |
β |
NULL check passes ((void*)-8 != NULL) |
if_kue.c:490 |
β |
kmalloc(0) returns ZERO_LENGTH_PTR |
kern_slaballoc.c:888-891 |
β |
ZERO_LENGTH_PTR = (void *)-8 |
kern_slaballoc.c:193 |
β |
Descriptor read happens later in kue_attach_post |
if_kue.c:439-440 |
β |
sc_mcfilters never reallocated |
(absence β grep confirms no other kmalloc of sc_mcfilters) | β |
kue_setmulti memcpy into KUE_MCFILT(sc, 0) |
if_kue.c:383-385 |
β |
KUE_MCFILT(sc, 0) = &sc->sc_mcfilters[0] = (char*)-8 |
if_kuereg.h:70-71 |
β |
Harness proof (buggy pattern on unpatched #0 kernel)
A kernel module (df1075_harness.c) replicates the exact driver pattern:
mcfilters = kmalloc(0 * 6, M_HARNESS, M_WAITOK); // kue_attach:488
// NULL check passes (ZERO_LENGTH_PTR != NULL) // kue_attach:490
memcpy(&mcfilters[0], mac, 6); // kue_setmulti:383-385
Loading it on the unpatched #0 kernel produced (from boot.log):
DF-1075: kmalloc(0) returned 0xfffffffffffffff8 (ZERO_LENGTH_PTR expected 0xfffffffffffffff8) DF-1075: NULL check would PASS (BUG: missed) (bug: sentinel is non-NULL) DF-1075: about to memcpy 6 bytes into &mcfilters[0] = 0xfffffffffffffff8 DF-1075: THIS SHOULD PANIC WITH: Fatal trap 12: page fault Fatal trap 12: page fault while in kernel mode fault virtual address = 0xfffffffffffffff8 fault code = supervisor write data, page not present Stopped at df1075_modevent+0x91: movl $0x3333,(%rbx)
The fault address 0xFFFFFFFFFFFFFFF8 is exactly ZERO_LENGTH_PTR. The
fault code "supervisor write data, page not present" confirms a write to an
unmapped address. The movl $0x3333,(%rbx) instruction is the memcpy writing
the first 4 bytes of the multicast address 33:33:00:00:00:01 into %rbx
which holds 0xFFFFFFFFFFFFFFF8.
This matches the finding's predicted output exactly.
Fix
The fix moves the sc_mcfilters allocation from kue_attach() to
kue_attach_post() (after the descriptor is read), and guards the
kfree() in kue_detach() with a NULL check (since kue_attach_post may
not have run on the uether_ifattach-failure path, and kfree(NULL)
panics on DragonFlyBSD).
See fix.diff.
Fix validation
The fixed kernel (#1, built from patched source) was validated:
- Patch applies cleanly β
patch -p1succeeded, all 3 hunks. - Kernel compiles β
make -j6 nativekernelrc=0. - Fixed source verified β
sc_mcfilterskmalloc now at line 453 inkue_attach_post()(after descriptor read at 439-440); old allocation removed fromkue_attach();kfreeguarded at line 533-534. - Fixed-pattern harness (
df1075_fixed_pattern.c) loaded on the patched#1kernel βkmalloc(192)returned0xfffff8004f22ccd0(valid KVA), memcpy succeeded, NO panic:DF-1075-FIXED: kmalloc(32*6=192) returned 0xfffff8004f22ccd0 DF-1075-FIXED: memcpy into &mcfilters[0]=0xfffff8004f22ccd0 SUCCEEDED, no panic DF-1075-FIXED: wrote 33:33:ff:00:00:01 DF-1075-FIXED: kfree OK β fix verified, no panic
The actual kue(4) driver cannot be triggered without USB hardware, so
fix_status = not_testable for the live driver β but the before/after
harness validation confirms the mechanism is closed.
Verdict
REPRODUCED (panic via harness replicating the exact driver code pattern).
Impact: panic (DoS) β write to unredirectable ZERO_LENGTH_PTR sentinel,
no escalation path. Fix: VALIDATED (compiles, allocation moved, harness
before/after confirms mechanism closed).
Fix verification
not_testablenot_testable (no USB HW). Compile+boot+harness validated: buggy harness panics on #0, fixed-pattern harness succeeds on #1.
BEFORE: Fatal trap 12 at 0xfffffffffffffff8. AFTER: kmalloc(192) valid, memcpy succeeds.
Confirmed kernel references
Detail
Exploit chain
none -- DoS only (write to fixed ZERO_LENGTH_PTR sentinel, unredirectable). USB device-only trigger. No escalation path.
Evidence (decisive lines)
BEFORE: kmalloc(0)=0xfffffffffffffff8, Fatal trap 12 page fault at that addr. AFTER: kmalloc(192)=valid ptr, memcpy succeeds.
PoC changes
Authored: df1075_harness.c (kld replicating buggy pattern), df1075_fixed_pattern.c (corrected), fix.diff (move alloc to kue_attach_post + guard kfree), VERDICT.md, manifest.json.
Verified recommended fix
Move sc_mcfilters kmalloc from kue_attach to kue_attach_post (after descriptor read at :439-440). Remove NULL check (M_WAITOK). Guard kfree in kue_detach with NULL check. Matches finding proposal. Full diff in findings/poc/DF-1075/fix.diff.
Verdict
REPRODUCED (kld harness). kue_attach if_kue.c:488-493 kmalloc(KUE_MCFILTCNT6) BEFORE descriptor read -> sc_desc zero -> count=0 -> kmalloc(0)=ZERO_LENGTH_PTR(-8) -> NULL check passes (-8!=NULL) -> kue_setmulti memcpy to (void)-8 -> page fault. Harness panics: Fatal trap 12 at 0xfffffffffffffff8.
No comments yet.