Re: NKE ip filter conflic with ipfw
Re: NKE ip filter conflic with ipfw
- Subject: Re: NKE ip filter conflic with ipfw
- From: Jan Deng <email@hidden>
- Date: Tue, 25 Aug 2009 14:49:23 +0800
Hi Vincent,
Thanks! Seems you are right. I changed the code to return EJUSTRETURN instead of 0 when ipf_inject_output failed, and this issue can't be reproduced again!
Thank you very much!
Best Regards,
jan
2009/8/25 Vincent Lubet
<email@hidden>
Jan,
This is the backtrace with symbols:
1 mach_kernel 0x0012b4c6 panic + 0x1a6 (/SourceCache/xnu/xnu-1228.15.4/osfmk/kern/debug.c:279)
2 mach_kernel 0x003a5b39 m_free + 0x24 (/SourceCache/xnu/xnu-1228.15.4/bsd/kern/uipc_mbuf.c:2744)
3 mach_kernel 0x003a8051 m_pullup + 0x1d1 (/SourceCache/xnu/xnu-1228.15.4/bsd/kern/uipc_mbuf.c:4196)
4 mach_kernel 0x00234a1e divert_packet + 0x2b (/SourceCache/xnu/xnu-1228.15.4/bsd/netinet/ip_divert.c:218)
5 mach_kernel 0x00244cce ip_output_list + 0x184d (/SourceCache/xnu/xnu-1228.15.4/bsd/netinet/ip_output.c:1163)
6 mach_kernel 0x0024bcd3 tcp_ip_output + 0xf7 (/SourceCache/xnu/xnu-1228.15.4/bsd/netinet/tcp_output.c:1703)
7 mach_kernel 0x0024d4c2 tcp_output + 0x17ab (/SourceCache/xnu/xnu-1228.15.4/bsd/netinet/tcp_output.c:1523)
8 mach_kernel 0x002503f9 tcp_fasttimo + 0x119 (/SourceCache/xnu/xnu-1228.15.4/bsd/netinet/tcp_timer.c:294)
9 mach_kernel 0x0013ebde thread_call_thread + 0xe9 (/SourceCache/xnu/xnu-1228.15.4/osfmk/kern/thread_call.c:839)
10 mach_kernel 0x001a14fc call_continuation + 0x1c
Fri Aug 21 18:59:24 2009
panic(cpu 0 caller 0x003A5B39): "m_free: freeing an already freed mbuf"@/SourceCache/xnu/xnu-1228.15.4/bsd/kern/uipc_mbuf.c:2741
So this is a double free problem.
I suspect it may be the way you handle an error coming back from ipf_inject_output() as ipf_inject_output() will always free the mbuf when it returns a non-zero error code.
Vincent
On Aug 23, 2009, at 6:16 PM, Jan Deng wrote:
Hi Vincent,
Here is the panic log:
Fri Aug 21 18:59:24 2009
panic(cpu 0 caller 0x003A5B39): "m_free: freeing an already freed mbuf"@/SourceCache/xnu/xnu-1228.15.4/bsd/kern/uipc_mbuf.c:2741
Backtrace (CPU 0), Frame : Return Address (4 potential args on stack)
0x2139bad8 : 0x12b4c6 (0x45f91c 0x2139bb0c 0x13355c 0x0)
0x2139bb28 : 0x3a5b39 (0x49af18 0x37 0x2139bbf8 0x1b5c638d)
0x2139bb68 : 0x3a8051 (0x1d2fdf00 0x1d2ff744 0x0 0x2139bbc4)
0x2139bba8 : 0x234a1e (0x1d2ff700 0x14 0x0 0x23a6c68)
0x2139bbf8 : 0x244cce (0x1d2ff700 0x0 0x21dc 0xa)
0x2139bdb8 : 0x24bcd3 (0x1d2ff700 0x0 0x0 0x6298208)
0x2139be28 : 0x24d4c2 (0x0 0x0 0x0 0x140394)
0x2139bf58 : 0x2503f9 (0x6298270 0x2 0x1 0x1a436f)
0x2139bf78 : 0x13ebde (0x0 0x0 0x0 0x0)
0x2139bfc8 : 0x1a14fc (0x522b60 0x0 0x1a40b5 0x4f5d3c8)
Backtrace terminated-invalid frame pointer 0
BSD process name corresponding to current thread: kernel_task
Mac OS version:
9L30
Kernel version:
Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386
System model name: Macmini2,1 (Mac-F4208EAA)
System uptime in nanoseconds: 6042789067204
Best Regards,
jan
2009/8/22 Vincent Lubet <email@hidden>
What kind of panic do you get? Could you share the panic log?
Vincent
On Aug 21, 2009, at 5:11 AM, Jan Deng wrote:
Hi all,
I write an NKE ip filter, it works fine normally. But when I set an ipfw rule to limit the net speed. The system will always panic when I visit website.
The rule I added is:
ipfw pipe 1 config bw 512Kbit/s
ipfw add 400 pipe 1 ip from any to any
The panic log said "m_free: freeing an already freed mbuf".
I collect the panic dump and the stack shows like this:
#0 0x001b0b60 in Debugger (message=0x80010033 <Address 0x80010033 out of bounds>)
#1 0x0012b4c6 in panic (str=0x1 <Address 0x1 out of bounds>) at /SourceCache/xnu/xnu-1228.15.4/osfmk/kern/debug.c:275
#2 0x003a5b39 in m_free (m=0x1d248c00) at /SourceCache/xnu/xnu-1228.15.4/bsd/kern/uipc_mbuf.c:2741
#3 0x003a8051 in m_pullup (n=0x1d248c00, len=20) at /SourceCache/xnu/xnu-1228.15.4/bsd/kern/uipc_mbuf.c:4196
#4 0x00234a1e in divert_packet (m=0x1d24a500, incoming=0, port=8668, rule=10) at /SourceCache/xnu/xnu-1228.15.4/bsd/netinet/ip_divert.c:218
#5 0x00244cce in ip_output_list (m0=0x1d24a500, packetchain=0, opt=0x0, ro=<value temporarily unavailable, due to optimizations>, flags=256, imo=0x0, ipoa=0x3c823d0c) at /SourceCache/xnu/xnu-1228.15.4/bsd/netinet/ip_output.c:1160
#6 0x0024bcd3 in tcp_ip_output (so=0x5e0b000, tp=<value temporarily unavailable, due to optimizations>, pkt=0x1d24a500, cnt=0, opt=0x0, flags=256) at /SourceCache/xnu/xnu-1228.15.4/bsd/netinet/tcp_output.c:1701
#7 0x0024d4c2 in tcp_output (tp=0x5e0b270) at /SourceCache/xnu/xnu-1228.15.4/bsd/netinet/tcp_output.c:1523
#8 0x003aafb0 in soconnectlock (so=0x5e0b000, nam=0x3c823ed8, dolock=0) at /SourceCache/xnu/xnu-1228.15.4/bsd/kern/uipc_socket.c:1245
#9 0x003b2733 in connect_nocancel (p=0x3e59794, uap=0x58930c0, retval=0x5893104) at /SourceCache/xnu/xnu-1228.15.4/bsd/kern/uipc_syscalls.c:645
#10 0x003e3a7f in unix_syscall (state=0x4ca3680) at /SourceCache/xnu/xnu-1228.15.4/bsd/dev/i386/systemcalls.c:184
#11 0x001a1c0a in lo_unix_scall () at pmap.h:176
Cannot access memory at address 0xb02cb97c
Here is my code, I will redirect all TCP traffic to Port 80:
errno_t ip_output(void *cookie, mbuf_t *data, ipf_pktopts_t options)
{
...
//if the traffic is from browser to remote http server, change the destination ip and port to 127.0.0.1:6668
if(type == CONNTRACK_TYPE_REDIRECT)
{
org_port = p_tcp_header->th_dport;
/* change header here */
// change dest ip to 127.0.0.1
modifyDstAddress(p_ip_header, NULL);
p_tcp_header->th_dport = htons(localProxy_port);
mbuf_outbound_finalize( *data, PF_INET, 0 );
mbuf_copyback(*data, 0, payloadOffset+sizeof(struct tcphdr), p_ip_header, M_WAITOK);
if(ipf_inject_output(*data, IP_V(p_ip_header) == IPVERSION?ipfilter_ref:ipfilter_ref6, options) != 0) {
/* restore ip/tcp header and bypass */
modifyDstAddress(p_ip_header, &dst_ip);
p_tcp_header->th_dport = org_port;
mbuf_copyback(*data, 0, payloadOffset+sizeof(struct tcphdr), p_ip_header, M_NOWAIT);
return 0;
}
return EJUSTREURN;
}
//if the traffic is from local proxy (127.0.0.1:6668) to browser, modify the source ip and port from 127.0.0.1:6668 to remote http server's ip and port, and modify the destination ip to 127.0.0.1
else if(type == CONNTRACK_TYPE_REDIRECT_REVERSE)
{
LOG(LOG_DEBUG, "ip_output, type is REDIRECT_REVERSE, reverse packet\n");
modifySrcAddress(p_ip_header, &ip);
p_tcp_header->th_sport = port;
mbuf_outbound_finalize( *data, PF_INET, 0 );
mbuf_copyback(*data, 0, payloadOffset+sizeof(struct tcphdr), p_ip_header, M_WAITOK);
return 0;
}
}
Is there any sample code or detail guideline about ip filter development? I don't know if my code fit the standard. In fact, my kext will always panic with any ipfw rule before I adding mbuf_outbound_finalize(). After I calling this function, I find that most rules will not cause OS panic, but the ones I listed still do.
I don't know if it is because my code is not fit the standard or there is other cause.
Could any one help me? Thanks!
Best Regards,
jan
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden