I'm not very familiar with kernel controls but I have a feeling that
the kernel panics are coming from how I'm using them, mainly because
I simply do not know very much about how they work (there's not much
documentation on them). The panic itself seems to occur when data is
sent out (ctl_enqueue'd), although I have no way of being certain.
It seems to have something to do with memory allocation. One other
thing is that at the end of my ctl_sendfunc (called when the client
sends data to the kext), I always call mbuf_freem() on the mbut_t
structure passed in, I saw this done in some Brian's Peer-Guardian
source, however I don't know anything about its proper usage.
Short answer: don't free the buffer.
Long answer: If you really need to free mbufs, you probably should be
using freem_list so that it will clean up an mbuf chain, but failing to
do so would just cause a slight leak, not a panic. However, in this case,
you are actually causing a double free.
The calling code does appear to release the mbuf, though I had to trace my
way back a half dozen functions to find where it does. If you look at the
file "kern/uipc_socket.c" in the xnu sources, you'll see what's going on.
At about line 1401 (depending on what version you're looking at), when it
dereferences the function pointer:
*so->so_proto->pr_usrreqs->pru_send
it is (through an intermediary function) calling your ctl_send_func callback.
Then, it releases the entire mbuf chain. Since your send function essentially
turned one node somewhere in that chain into a dangling reference to an
already-freed object, the behavior of the second free will behave somewhat
nondeterministically, depending on what else is allocating or releasing
memory at the time.
I'll add something to the docs the next time it gets updated.
I just wanted to chime in here, since my code was referenced. When I started my project, it was on 10.4.2 and I originally did not free the incoming mbuf. However, I then noticed an immediate mbuf leak using netstat -m and fairly quickly, all mbufs were exhausted on the machine. Adding in the free solved the problem. Also, this code has been running on all versions of 10.4.2+ since Fall 2005 without issue.
Finally, looking at the code you referenced Dave (using xnu-792.6.61), the mbuf is not freed as pru_send is called in the while(resid) loop and top/control are zero'd at the end of every iteration of that loop.