From nobody@FreeBSD.org  Sat Jan  3 06:30:22 2004
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 9769E16A4CE
	for <freebsd-gnats-submit@FreeBSD.org>; Sat,  3 Jan 2004 06:30:22 -0800 (PST)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 33FB943D53
	for <freebsd-gnats-submit@FreeBSD.org>; Sat,  3 Jan 2004 06:30:21 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.10/8.12.10) with ESMTP id i03EUKdL059170
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 3 Jan 2004 06:30:20 -0800 (PST)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.10/8.12.10/Submit) id i03EUKkb059168;
	Sat, 3 Jan 2004 06:30:20 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200401031430.i03EUKkb059168@www.freebsd.org>
Date: Sat, 3 Jan 2004 06:30:20 -0800 (PST)
From: Galois Zheng <zyf11@mail.ustc.edu.cn>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] panic at tcp_output(), with TCPDEBUG and INET6, and SO_DEBUG(socket)
X-Send-Pr-Version: www-2.0

>Number:         60856
>Category:       kern
>Synopsis:       [netinet] [patch] panic: at tcp_output(), with TCPDEBUG and INET6, and SO_DEBUG(socket)
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bms
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jan 03 06:40:18 PST 2004
>Closed-Date:    Tue Dec 13 00:50:20 GMT 2005
>Last-Modified:  Tue Dec 13 00:50:20 GMT 2005
>Originator:     Galois Zheng
>Release:        5.2-RC2, 5.2-current
>Organization:
G2 Project, Univ. Science and Technology of China
>Environment:
FreeBSD 5.2-RC2 or 5.2-Current, PIII 866MHz, 256M memory, harddisk:14G Quantum Firewall.
>Description:
     In both 5.2-rc and 5.2-current there exists this problem.
     in .../netinet/tcp_output.c,there is the following lines:
=============================================================
#ifdef TCPDEBUG
    if (so->so_options & SO_DEBUG) {
        u_short save = ipov->ih_len;
        ipov->ih_len = htons(m->m_pkthdr.len);
        tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, void *), th, 0);
        ipov->ih_len = save;
    }
#endif
========================================================
Please notes the variable: "ipov" which is "struct ipovly *" pointer, it used unckeckly. but when sending ipv6 packet, the variable "isipv6" is set to 1, so 682# line: "ipov = (struct ipovly *)ip;" could not be executed. While getting to the above TCPDEBUG code block, ipov point is used uninitializedly.
The kernel will panic with "supervisor read, page not present". 
    It likes that the bad codes are very careless. It is not very complicated.
>How-To-Repeat:
      Compiling the kernel of 5.2-current or 5.2-RC2 with: options INET,INET6,TCPDEBUG. 
      Setting its ipv6 address, such as 3ffe:1111:ffff:1000::2. then set another host's ipv6 addr is 3ffe:1111:ffff:1000::1.
    At the FreeBSD-5.2 box with INET6 and TCPDEBUG options, run commands: "ftp -d 3ffe:1111:ffff:1000::1", and login to another host. 
    Then in ftp environment, run pwd, help..., when running "ps" or "get filename" command, the FreeBSD-5.2 will panic and display some messages like "page not present..., at tcp_output+0xyyy",  and so on.  
>Fix:
      when i met thie panic several times, i objdumped the problem kernel, located the problem codes and created a patch for tcp_output.c(both 5.2-current and 5.2-rc2 can use it):
=======================================================
#diff -u tcp_output.c.orig tcp_output.c > tcp_output.patch
#cat tcp_output.patch
--- tcp_output.c.orig   2003-11-20 20:07:38.000000000 +0000
+++ tcp_output.c        2004-01-03 22:13:47.000000000 +0000
@@ -849,9 +849,19 @@
     * Trace.
     */
    if (so->so_options & SO_DEBUG) {
-       u_short save = ipov->ih_len;
+       u_short save;
+#ifdef INET6
+       if (!isipv6)
+#endif
+           {
+       save = ipov->ih_len;
        ipov->ih_len = htons(m->m_pkthdr.len /* - hdrlen + (th->th_off << 2) */);
+           }
+
        tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, void *), th, 0);
+#ifdef INET6
+       if (!isipv6)
+#endif
        ipov->ih_len = save;
    }
 #endif

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->bms 
Responsible-Changed-By: bms 
Responsible-Changed-When: Fri Jun 18 02:23:58 GMT 2004 
Responsible-Changed-Why:  
I'll try to look at this 

http://www.freebsd.org/cgi/query-pr.cgi?pr=60856 
State-Changed-From-To: open->analyzed 
State-Changed-By: bms 
State-Changed-When: Fri Jun 18 03:18:15 GMT 2004 
State-Changed-Why:  
Looks like a real bug, but haven't reproduced it. Preparing to test 
patch, will hopefully commit shortly. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=60856 
State-Changed-From-To: analyzed->patched 
State-Changed-By: bms 
State-Changed-When: Fri Jun 18 03:31:07 GMT 2004 
State-Changed-Why:  
Committed to HEAD, thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=60856 
State-Changed-From-To: patched->closed 
State-Changed-By: bms 
State-Changed-When: Tue Dec 13 00:49:45 UTC 2005 
State-Changed-Why:  
-CURRENT is now -STABLE 

http://www.freebsd.org/cgi/query-pr.cgi?pr=60856 
>Unformatted:
