Hello Everyone,
Straight to the point: Why does this part of a KEXT crash?
/* IP Filter */
errno_t
pre(ipf_input_func)( void *cookie,
mbuf_t *data,
int offset,
u_int8_t protocol )
{
char *tag;
size_t len;
if (pre(connectedProcesses) == 0) return KERN_SUCCESS;
if (protocol == IPPROTO_ESP) {
if ( mbuf_tag_allocate( *data,
pre(mbufTag),
1,
strlen(STR(ESP_MARKER)) + 1,
MBUF_DONTWAIT,
(void **)&tag ) == 0) {
bcopy(STR(ESP_MARKER), tag, strlen(STR(ESP_MARKER)) + 1);
}
} else if ( mbuf_tag_find( *data,
pre(mbufTag),
1,
&len,
(void **) &tag ) == 0) {
if (len == strlen(STR(ESP_MARKER)) + 1
&& memcmp(tag, STR(ESP_MARKER), len) == 0) {
size_t mbufSize,
space = -1;
mbuf_tag_free(*data, pre(mbufTag), 1);
mbufSize = (mbuf_flags(*data) & MBUF_PKTHDR) ?
mbuf_pkthdr_len(*data) : mbuf_len(*data);
if ( ctl_getenqueuespace( pre(userSpaceSock),
0,
&space ) == 0
&& space >= mbufSize ) {
mbuf_t dupe;
if (mbuf_dup(*data, MBUF_DONTWAIT, &dupe) == 0) {
if (ctl_enqueuembuf ( pre(userSpaceSock),
0,
dupe,
0) != 0 ) {
printf("Failed to send\n");
mbuf_freem(dupe);
}
} else printf("Failed to dupe\n");
} else printf("Not enough space: %d >= %d\n",
space, mbufSize);
} else printf("Marker does not match\n");
}
return KERN_SUCCESS;
}
I know where it crashes, it crashes in
/xnu-792.2.4/bsd/kern/uipc_mbuf.c:1267
where a manual panic is created:
"m_freem_list: m_nextpkt of m_next != NULL"
Fine, but I did the following as well (just from top of my head,
excute stupid coding errors, of course the version I tried had no
such errors):
mbuf_t dupe2 = dupe;
while (dupe2) {
if (mbuf_nextpkt(dupe2)) mbuf_setnextpkt(dupe2, NULL);
dupe2 = mbuf_next(dupe2);
}
BTW, I'll did the same for *data in another test and then for both.
So there was definately no m_nextpkt set along the chain. Modifying
the code to send the original mbuf (*data) and then not freeing it
(EJUSTRETURN as ctl_getenqueuespace consumes the package on
success) works just fine. So I don't see how this could be my mistake.
I tried not to equeue the package at all, just dupe and then
mbuf_freem and I run into a panic, too. Haven't checked so far if
it's the same one.
Oh, BTW pre(...) is a makro, it expands the name to a more unique one:
#define pre3(x,y) x ## y
#define pre2(x,y) pre3(x,y)
#define pre(x) pre2(FUNCTION_PREFIX, x)
and FUNCTION_PREFIX is a long, unique reverted domain name (no
string). This does not relate to the problem. STR converts defines
to strings:
#define STR2(x) #x
#define STR(x) STR2(x)
And I also know that the above function is anything but high-
performance, however it was just quick and dirty as a proof of
concept, that did not work so far, cause it panics.
Any help appreciated, thank you very much!
--
Best Regards,
Markus Hanauska
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40apple.com
This email sent to email@hidden