Bug #2660
closedUse of IPDIVERT causes kernel crashes
Description
Hello. I was trying to set up NAT on DragonFly machine and got a crash. I
have a following configuration:
1) Machine A with DragonFlyBSD 3.4
2) Machine B (the one which crashes) with DragonFlyBSD
3.6.1.24.gd9a9-RELEASE x86_64 (from git branch DragonFly_RELEASE_3_6)
3) Machine C is a vkernel machine hosted by B
Machine B kernel was compiled with following lines in config:
IPFIREWALL
IPFIREWALL_VERBOSE
IPFIREWALL_VERBOSE_LIMIT=100
IPFIREWALL_DEFAULT_TO_ACCEPT
IPDIVERT
Machine B has 2 network interfaces: nfe0 (with connection to A) and tap0
(with connection to C) configured as follows:
$ ifconfig nfe0 192.168.10.1 netmask 255.255.255.0 up (A has an address
192.168.10.2 assigned to re0 which is the interface on the other side)
$ ifconfig tap0 192.168.20.1 netmask 255.255.255.0 up (C has an address
192.168.20.2 assigned to vke0)
So I do as follows:
On machine A:
$ route add default 192.168.10.1
On machine B:
$ sysctl net.inet.ip.forwarding=1
$ ipfw -f flush (accept all because of line in config)
$ natd -interface tap0
$ ipfw add 100 divert natd ip from any to any in via tap0
$ ipfw add 110 divert natd ip from any to any out via tap0
Again, on machine A:
$ ping 192.168.20.2
Machine B crashes. 100% repeatable
Here is a part of the backtrace:
#11 0xffffffff8092429f in calltrap ()
at /usr/src/sys/platform/pc64/x86_64/exception.S:188
#12 0xffffffff80673d22 in ip_input (m=m@entry=0xffffffe0f49ce800)
at /usr/src/sys/netinet/ip_input.c:684
#13 0xffffffff8066813a in div_output (control=<optimized out>,
sin=0xffffffe0f605a130, m=0xffffffe0f49ce800, so=0xffffffe0bf0ff7c0)
at /usr/src/sys/netinet/ip_divert.c:373
#14 div_send (msg=0xffffffe0f54896a0) at
/usr/src/sys/netinet/ip_divert.c:514
#15 0xffffffff8061be6a in netmsg_service_loop (arg=<optimized out>)
at /usr/src/sys/net/netisr.c:319
#16 0xffffffff80571c57 in lwkt_deschedule_self (td=<optimized out>)
at /usr/src/sys/kern/lwkt_thread.c:327
Crash dump (129 Mb) is here:
https://drive.google.com/uc?id=0B1NArWn4pLpxazAxYjJOQVRMeGM&export=download
Vasily
Updated by tuxillo over 10 years ago
- Category set to Networking
- Status changed from New to In Progress
- Assignee set to tuxillo
- Target version set to 3.8
Hi Vasily,
The panic is caused by a null-pointer dereference, see below:
#12 0xffffffff80673d22 in ip_input (m=m@entry=0xffffffe0f49ce800) at /usr/src/sys/netinet/ip_input.c:684
684 if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
But rcvif is NULL:
(kgdb) p m->M_dat.MH.MH_pkthdr->rcvif
$3 = (struct ifnet *) 0x0
I'm going to try to reproduce your setup.
Cheers,
Antonio Huete
Updated by shamaz over 10 years ago
2014-04-09 11:05 GMT+04:00 <bugtracker-admin@leaf.dragonflybsd.org>:
Issue #2660 has been updated by tuxillo.
Category set to Networking
Status changed from New to In Progress
Assignee set to tuxillo
Target version set to 3.8.0Hi Vasily,
The panic is caused by a null-pointer dereference, see below:
#12 0xffffffff80673d22 in ip_input (m=m@entry=0xffffffe0f49ce800) at
/usr/src/sys/netinet/ip_input.c:684
684 if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {But rcvif is NULL:
(kgdb) p m->M_dat.MH.MH_pkthdr->rcvif
$3 = (struct ifnet *) 0x0I'm going to try to reproduce your setup.
Cheers,
Antonio Huete----------------------------------------
Bug #2660: Use of IPDIVERT causes kernel crashes
http://bugs.dragonflybsd.org/issues/2660#change-11913
- Author: shamaz
- Status: In Progress
- Priority: Normal
- Assignee: tuxillo
- Category: Networking
- Target version: 3.8.0
----------------------------------------
Hello. I was trying to set up NAT on DragonFly machine and got a crash. I
have a following configuration:1) Machine A with DragonFlyBSD 3.4
2) Machine B (the one which crashes) with DragonFlyBSD
3.6.1.24.gd9a9-RELEASE x86_64 (from git branch DragonFly_RELEASE_3_6)
3) Machine C is a vkernel machine hosted by BMachine B kernel was compiled with following lines in config:
IPFIREWALL
IPFIREWALL_VERBOSE
IPFIREWALL_VERBOSE_LIMIT=100
IPFIREWALL_DEFAULT_TO_ACCEPT
IPDIVERTMachine B has 2 network interfaces: nfe0 (with connection to A) and tap0
(with connection to C) configured as follows:$ ifconfig nfe0 192.168.10.1 netmask 255.255.255.0 up (A has an address
192.168.10.2 assigned to re0 which is the interface on the other side)
$ ifconfig tap0 192.168.20.1 netmask 255.255.255.0 up (C has an address
192.168.20.2 assigned to vke0)So I do as follows:
On machine A:
$ route add default 192.168.10.1On machine B:
$ sysctl net.inet.ip.forwarding=1
$ ipfw -f flush (accept all because of line in config)
$ natd -interface tap0
$ ipfw add 100 divert natd ip from any to any in via tap0
$ ipfw add 110 divert natd ip from any to any out via tap0Again, on machine A:
$ ping 192.168.20.2Machine B crashes. 100% repeatable
Here is a part of the backtrace:
#11 0xffffffff8092429f in calltrap ()
at /usr/src/sys/platform/pc64/x86_64/exception.S:188
#12 0xffffffff80673d22 in ip_input (m=m@entry=0xffffffe0f49ce800)
at /usr/src/sys/netinet/ip_input.c:684
#13 0xffffffff8066813a in div_output (control=<optimized out>,
sin=0xffffffe0f605a130, m=0xffffffe0f49ce800, so=0xffffffe0bf0ff7c0)
at /usr/src/sys/netinet/ip_divert.c:373
#14 div_send (msg=0xffffffe0f54896a0) at
/usr/src/sys/netinet/ip_divert.c:514
#15 0xffffffff8061be6a in netmsg_service_loop (arg=<optimized out>)
at /usr/src/sys/net/netisr.c:319
#16 0xffffffff80571c57 in lwkt_deschedule_self (td=<optimized out>)
at /usr/src/sys/kern/lwkt_thread.c:327Crash dump (129 Mb) is here:
https://drive.google.com/uc?id=0B1NArWn4pLpxazAxYjJOQVRMeGM&export=downloadVasily
--
You have received this notification because you have either subscribed to
it, or are involved in it.
To change your notification preferences, please click here:
http://bugs.dragonflybsd.org/my/account
I've just found out in my little investigation, that this is an old bug
fixed in FreeBSD in 2004. Look at this commit:
https://github.com/freebsd/freebsd/commit/66acd3ba6eb9d3017cc3cdf36d1268749512dd82
So it is OK, that m->m_pkthdr.rcvif == NULL, all we need is just to check
it explicitly. I'll write if this solution works for me (it should)
Updated by shamaz over 10 years ago
2014-04-10 16:25 GMT+04:00 Vasily Postnicov <shamaz.mazum@gmail.com>:
I've just found out in my little investigation, that this is an old bug
fixed in FreeBSD in 2004. Look at this commit:https://github.com/freebsd/freebsd/commit/66acd3ba6eb9d3017cc3cdf36d1268749512dd82
So it is OK, that m->m_pkthdr.rcvif == NULL, all we need is just to check
it explicitly. I'll write if this solution works for me (it should)
Yes, it works (I can ping machine C form A, no panic)
Updated by tuxillo over 10 years ago
- Status changed from In Progress to Closed
- % Done changed from 0 to 100
Applied in changeset f82a5263036fc2c7c21fe66b4f29d49d25dbeaa0.