site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com On Jan 18, 2007, at 4:45 PM, David Gatwood wrote: On Jan 18, 2007, at 12:28 PM, Greg <greg@kinostudios.com> wrote: 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. error = (*so->so_proto->pr_usrreqs->pru_send)(so, sendflags, top, addr, control, p); So which is it for ctl_send: free or don't? Brian Bergstrand <http://www.bergstrand.org/brian/> PGP Key ID: 0xB6C7B6A2 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Darwin) iD8DBQFFr//VedHYW7bHtqIRAtBWAKDO5nafLyU0lZfpHgLPEiR9MD4jVQCg2pLQ Vg/mR3ETLZkxhPPXiHlAHdM= =AhVJ -----END PGP SIGNATURE----- ---- Matt _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... On Jan 19, 2007, at 2:02 PM, darwin-kernel-request@lists.apple.com wrote: 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. <snip> ------------------------------ When you get the mbuf from the ctl_send handler your kext owns the mbuf and is responsible for disposal. However, disposal can mean things other than directly calling mbuf_freem(), e.g. ctl_enqueuembuf (), sock_sendmbuf(), or any other routine that implicitly consumes an mbuf chain. Also, if you are modifying mbuf payloads, be aware of mbufs with 'external data' (often referred to as mbuf clusters). External data is payload data that is referenced by multiple mbufs, and you could be modifying data out from underneath another part of the OS. This email sent to site_archiver@lists.apple.com