Instrumented-module proof (kprintf at every workBuf/encode alloc/free, one BINARY2ASCII ERANGE call, guest dmesg): DBG wbuf+ 0xfffff8011821b000 <- struct composite workBuf alloc DBG elem etype=0xffffffff82606080 off=0 (uint8 version) DBG elem etype=0xffffffff82606080 off=1 (uint8 spare) DBG elem etype=0xffffffff82605fc0 off=2 (uint16 arglen) DBG elem etype=0xffffffff82605ec0 off=4 (hint32 flags) DBG elem etype=0xffffffff82605f00 off=8 (uint32 token) DBG elem etype=0xffffffff82605f00 off=12 (uint32 typecookie) DBG elem etype=0xffffffff82605f00 off=16 (uint32 cmd) DBG elem etype=0xffffffff82605c40 off=20 (cmdbuf fixedstring -> ng_string_unparse) DBG strunp off=20 len=19980 <- strlen walks the attacker bytes DBG enc+ 0xfffff801183c0000 <- ng_encode_string alloc ~80KB DBG wbuf- 0xfffff8011821b000 invoke <- workBuf freed correctly !! no "DBG enc-" — encode buffer LEAKED Per-call leak = the ng_encode_string buffer (strlen(raw)*4+3, raw is attacker-controlled, len 19980 -> ~80KB). ng_string_unparse's NG_PARSE_APPEND("%s", s) hits cbuflen (20480) and `return (ERANGE)` without kfree(s) — sys/netgraph/netgraph/ng_parse.c:727-731. ng7 fixed exactly this (frees s via ng_parse_append error path).