Date: Fri, 5 Sep 2003 12:40:02 +0300 From: Jan Mikael Melen <jmgm@iki.fi> To: freebsd-net@freebsd.org Cc: snap-users@kame.net Subject: Fatal trap 12 in binding V6 socket in FreeBSD 5.1-p2 Message-ID: <200309051240.02622.jmgm@iki.fi>
next in thread | raw e-mail | index | archive | help
--Boundary-00=_ynFW/5DArZtlAdr Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Has anyone else seen that in the FreeBSD 5.1-p2 if one is binding to a socket that has earliear been closed but the tcp connection is still in time wait state will cause a panic in kernel with following error code: Fatal trap 12: page fault while in kernel mode fault virtual address = 0x6 fault code = supervisor read, page not present instruction pointer = 0x8:0xc03aa50e stack pointer = 0x10:0xdcc62c0c frame pointer = 0x10:0xdcc62c54 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, def32 1, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 current process = 33485 trap number = 12 panic: page fault It seems that the problem is in the in6_pcbbind where the in6_pcblookup_local is called (in6_pcb.c:231). If the socket has been closed the t->inp_socket struct has been already freed and set null but the t exists because there exists a state time wait still for the connection and that's why the lookup_local will return a valid value for t. After the lookup_local has returned the in6_pcbbinf will try to access t->inp_socket->so_options which of course will cause a Fatal trap because it is a NULL pointer. I've included as an attachment a patch that I have used to fix the problem and allso as attached a short program which can be used to regenerate the problem in unpatched FreeBSD 5.1-p2. It seems that this problem also exists in the KAME SNAP. BR. Jan --Boundary-00=_ynFW/5DArZtlAdr Content-Type: text/x-diff; charset="us-ascii"; name="patch.p0" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch.p0" *** in6_pcb.c Fri Sep 5 09:22:32 2003 --- in6_pcb.c Fri Sep 5 09:44:16 2003 *************** *** 888,896 **** --- 888,906 ---- */ head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; + LIST_FOREACH(inp, head, inp_hash) { if ((inp->inp_vflag & INP_IPV6) == 0) continue; + + /* + * If the inp_socket is NULL the socket is + * already closed and tcp connection is in + * time_wait state so just ignore it + */ + if (NULL == inp->inp_socket) + continue; + if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) && inp->inp_lport == lport) { *************** *** 929,934 **** --- 939,953 ---- wildcard = 0; if ((inp->inp_vflag & INP_IPV6) == 0) continue; + + /* + * If the inp_socket is NULL the socket is + * already closed and tcp connection is in + * time_wait state so just ignore it + */ + if (NULL == inp->inp_socket) + continue; + if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) wildcard++; if (!IN6_IS_ADDR_UNSPECIFIED( --Boundary-00=_ynFW/5DArZtlAdr--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200309051240.02622.jmgm>