From nobody@FreeBSD.org  Wed Dec  5 23:31:28 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 0A9C016A417
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  5 Dec 2007 23:31:28 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id F11E113C478
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  5 Dec 2007 23:31:27 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id lB5NVO3f076182
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 5 Dec 2007 23:31:24 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id lB5NVOGn076181;
	Wed, 5 Dec 2007 23:31:24 GMT
	(envelope-from nobody)
Message-Id: <200712052331.lB5NVOGn076181@www.freebsd.org>
Date: Wed, 5 Dec 2007 23:31:24 GMT
From: Tom Parker <tom@tparker.ca>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Panic with MD5 options on a TCP socket
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         118455
>Category:       kern
>Synopsis:       [tcp] [panic] Panic with MD5 options on a TCP socket
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bz
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Dec 05 23:40:01 UTC 2007
>Closed-Date:    Wed Sep 10 17:38:25 UTC 2008
>Last-Modified:  Wed Sep 10 17:38:25 UTC 2008
>Originator:     Tom Parker
>Release:        N/A
>Organization:
>Environment:
>Description:
We're used a ported version of the BSD stack in a system in which we've just seen reproducible panics with MD5 options where the window size is shrunk.

I guess this might be able to be remotely exploited, not sure.

Referring to 1.145 of tcp_output.cpp

	if (len + optlen + ipoptlen > tp->t_maxopd) {
		flags &= ~TH_FIN;
		if (tso) {
			if (len > TCP_MAXWIN - hdrlen - optlen) {
				len = TCP_MAXWIN - hdrlen - optlen;
				len = len - (len % (tp->t_maxopd - optlen));
				sendalot = 1;
			} else if (tp->t_flags & TF_NEEDFIN)
				sendalot = 1;
		} else {
			len = tp->t_maxopd - optlen - ipoptlen;
			sendalot = 1;
		}
	}

In the above code we saw that without tso maxopd (=4) had shrunk to less than the optlen (=20 with MD5).  This gave a negative len which paniced in m_copym.  

		/*
		 * Start the m_copy functions from the closest mbuf
		 * to the offset in the socket buffer chain.
		 */
		mb = sbsndptr(&so->so_snd, off, len, &moff);

		if (len <= MHLEN - hdrlen - max_linkhdr) {
			m_copydata(mb, moff, (int)len,
			    mtod(m, caddr_t) + hdrlen);
			m->m_len += len;
		} else {
			m->m_next = m_copy(mb, moff, (int)len);
			if (m->m_next == NULL) {
				SOCKBUF_UNLOCK(&so->so_snd);
				(void) m_free(m);
				error = ENOBUFS;
				goto out;
			}
		}
We are using an older version but I believe the code above would panic given a negative len.


>How-To-Repeat:
Not sure, should be fixable by code inspection.
>Fix:
Our solution was to switch the test below from ==0 to >0, this causes no data to be sent.

	/*
	 * Grab a header mbuf, attaching a copy of data to
	 * be transmitted, and initialize the header from
	 * the template for sends on this connection.
	 */
	if (len) {

The real problem might be maxopd falling less than the mss.  The fix above makes the code safer in the mean time. 



>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->bz 
Responsible-Changed-By: rwatson 
Responsible-Changed-When: Wed Dec 5 23:49:00 UTC 2007 
Responsible-Changed-Why:  
Assign to bz, since he has been looking at this code recently. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=118455 

From: "Bjoern A. Zeeb" <bz@FreeBSD.org>
To: Tom Parker <tom@tparker.ca>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/118455: Panic with MD5 options on a TCP socket
Date: Thu, 6 Dec 2007 09:16:46 +0000 (UTC)

 On Wed, 5 Dec 2007, Tom Parker wrote:
 
 Hi,
 
 > We're used a ported version of the BSD stack in a system in which
 > we've just seen reproducible panics with MD5 options where the
 > window size is shrunk.
 
 
 
 > Referring to 1.145 of tcp_output.cpp
 
 you mean tcp_output.c I guess, as there is no .cpp file in our network stack.
 
 
 > 	if (len + optlen + ipoptlen > tp->t_maxopd) {
 > 		flags &= ~TH_FIN;
 > 		if (tso) {
 >			[..]
 > 		} else {
 > 			len = tp->t_maxopd - optlen - ipoptlen;
 > 			sendalot = 1;
 > 		}
 > 	}
 >
 > In the above code we saw that without tso maxopd (=4) had shrunk to
 > less than the optlen (=20 with MD5).  This gave a negative len which
 > paniced in m_copym.
 
 Yeah, so guess that could be a general problem just more easily
 triggered with MD5 because of more data put into options?
 
 
 > We are using an older version but I believe the code above would
 > panic given a negative len.
 
 You are aware that tcp-md5 was fixed recently? How much different is
 your code to what is in the FreeBSD tree?
 
 
 
 > Our solution was to switch the test below from ==0 to >0, this causes no data to be sent.
 
 You mean from !=0 to >0 I suppose?
 
 
 > 	/*
 > 	 * Grab a header mbuf, attaching a copy of data to
 > 	 * be transmitted, and initialize the header from
 > 	 * the template for sends on this connection.
 > 	 */
 > 	if (len) {
 >
 > The real problem might be maxopd falling less than the mss.
 > The fix above makes the code safer in the mean time.
 
 .. and hides the actual problem, so it's not good.
 
 We should try to concentrate on finding the real problem.
 
 
 Do you have a core file, panic message or backtrace?
 
 -- 
 Bjoern A. Zeeb                                 bzeeb at Zabbadoz dot NeT
 Software is harder than hardware  so better get it right the first time.
State-Changed-From-To: open->analyzed 
State-Changed-By: bz 
State-Changed-When: Thu Jan 3 00:12:12 UTC 2008 
State-Changed-Why:  


http://www.freebsd.org/cgi/query-pr.cgi?pr=118455 
State-Changed-From-To: analyzed->patched 
State-Changed-By: bz 
State-Changed-When: Wed Sep 3 19:36:54 UTC 2008 
State-Changed-Why:  
As of today this was addressed and could be closed. 
I am leaving it open as there will be a few follow-up commits 
so we can track those here as well. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=118455 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/118455: commit references a PR
Date: Sun,  7 Sep 2008 14:45:17 +0000 (UTC)

 bz          2008-09-07 14:44:55 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/netinet          tcp_subr.c 
   Log:
   SVN rev 182846 on 2008-09-07 14:44:55Z by bz
   
   Convert SYSCTL_INTs for tcp_mssdflt and tcp_v6mssdflt to
   SYSCTL_PROCs and check that the default mss for neither v4 nor
   v6 goes below the minimum MSS constant (216).
   
   This prevents people from shooting themselves in the foot.
   
   PR:             kern/118455 (remotely related)
   Reviewed by:    silby (as part of a larger patch in March)
   MFC after:      2 months
   
   Revision  Changes    Path
   1.312     +42 -6     src/sys/netinet/tcp_subr.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 

From: "Bjoern A. Zeeb" <bz@FreeBSD.org>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/118455: [tcp] [panic] Panic with MD5 options on a TCP socket
Date: Sun, 7 Sep 2008 14:46:22 +0000 (UTC)

 Date: Sun, 7 Sep 2008 14:30:47 +0000 (UTC)
 From: Bjoern A. Zeeb <bz@FreeBSD.org>
 To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org
 Subject: Re: cvs commit: src/sys/netinet tcp_output.c
 
 On Sun, 7 Sep 2008, Bjoern A. Zeeb wrote:
 
 > bz          2008-09-07 11:38:30 UTC
 >
 >  FreeBSD src repository
 >
 >  Modified files:
 >    sys/netinet          tcp_output.c
 >  Log:
 >  SVN rev 182841 on 2008-09-07 11:38:30Z by bz
 >
 >  Add a second KASSERT checking for len >= 0 in the tcp output path.
 >
 >  This is different to the first one (as len gets updated between those
 >  two) and would have caught various edge cases (read bugs) at a well
 >  defined place I had been debugging the last months instead of
 >  triggering (random) panics further down the call graph.
 >
 >  MFC after:      2 months
 
 PR:	kern/118455
 
 
 >  Revision  Changes    Path
 >  1.154     +7 -1      src/sys/netinet/tcp_output.c
 >

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/118455: commit references a PR
Date: Sun,  7 Sep 2008 18:50:48 +0000 (UTC)

 bz          2008-09-07 18:50:25 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/netinet          tcp_input.c tcp_subr.c tcp_var.h 
   Log:
   SVN rev 182851 on 2008-09-07 18:50:25Z by bz
   
   Split tcp_mss() in tcp_mss() and tcp_mss_update() where the former
   calls the latter.
   
   Merge tcp_mss_update() with code from tcp_mtudisc() basically
   doing the same thing.
   
   This gives us one central place where we calcuate and check mss values
   to update t_maxopd (maximum mss + options length) instead of two slightly
   different but almost equal implementations to maintain.
   
   PR:             kern/118455
   Reviewed by:    silby (back in March)
   MFC after:      2 months
   
   Revision  Changes    Path
   1.380     +56 -15    src/sys/netinet/tcp_input.c
   1.314     +9 -73     src/sys/netinet/tcp_subr.c
   1.164     +1 -0      src/sys/netinet/tcp_var.h
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: bz 
State-Changed-When: Wed Sep 10 17:37:30 UTC 2008 
State-Changed-Why:  
Follow-up patches had been comitted to HEAD and will be 
merged in two months. 
Thanks a lot for submitting and helping debugging. 

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