From mluckie@cs.waikato.ac.nz  Sun May  6 23:05:17 2007
Return-Path: <mluckie@cs.waikato.ac.nz>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 0F97916A400
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  6 May 2007 23:05:17 +0000 (UTC)
	(envelope-from mluckie@cs.waikato.ac.nz)
Received: from zombie.scms.waikato.ac.nz (mail.scms.waikato.ac.nz [130.217.241.36])
	by mx1.freebsd.org (Postfix) with ESMTP id AB21613C44C
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  6 May 2007 23:05:16 +0000 (UTC)
	(envelope-from mluckie@cs.waikato.ac.nz)
Received: from sorcerer.cs.waikato.ac.nz ([130.217.251.39])
	by zombie.scms.waikato.ac.nz with esmtps (TLSv1:AES256-SHA:256)
	(Exim 4.52)
	id 1HkpNy-0008IV-0Y
	for FreeBSD-gnats-submit@freebsd.org; Mon, 07 May 2007 10:39:22 +1200
Received: from mluckie by sorcerer.cs.waikato.ac.nz with local (Exim 4.67 (FreeBSD))
	(envelope-from <mluckie@sorcerer.cs.waikato.ac.nz>)
	id 1HkpNw-000P1S-Sp
	for FreeBSD-gnats-submit@freebsd.org; Mon, 07 May 2007 10:39:20 +1200
Message-Id: <E1HkpNw-000P1S-Sp@sorcerer.cs.waikato.ac.nz>
Date: Mon, 07 May 2007 10:39:20 +1200
From: Matthew Luckie <mluckie@cs.waikato.ac.nz>
Sender: Matthew Luckie <mluckie@cs.waikato.ac.nz>
Reply-To: Matthew Luckie <mluckie@cs.waikato.ac.nz>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] sys/netinet/udp_usrreq.c modifies received UDP checksum
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         112471
>Category:       kern
>Synopsis:       [netinet] [patch] sys/netinet/udp_usrreq.c modifies received UDP checksum
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun May 06 23:10:00 GMT 2007
>Closed-Date:    Sun Jun 10 07:44:45 GMT 2007
>Last-Modified:  Tue Jul 10 03:39:36 UTC 2012
>Originator:     Matthew Luckie
>Release:        FreeBSD 6.2-RC2 i386
>Organization:
>Environment:
System: FreeBSD sorcerer.cs.waikato.ac.nz 6.2-RC2 FreeBSD 6.2-RC2 #0: Sun Dec 24 23:42:30 UTC 2006 root@dessler.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP i386


	
>Description:

At the moment, freebsd checks a UDP checksum in place, overwriting
whatever is there.  This has a side effect of the ICMP code sending
back the first eight bytes of the UDP payload with 2 bytes different
to what that system sent.

NetBSD and OpenBSD are more careful with the UDP packet in case it is
needed for ICMP.  See, for example, revision 1.46 of NetBSD
udp_usrreq.c

http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netinet/udp_usrreq.c

Here's an example of the problem.

listening on lo0, link-type NULL (BSD loopback), capture size 1500 bytes
13:41:24.382239 IP localhost.40858 > localhost.33435: UDP, length 12
        0x0000:  0200 0000 4500 0028 9f9b 0000 0111 1c28
        0x0010:  7f00 0001 7f00 0001 9f9a 829b 0014 df8d
        0x0020:  0000 0000 0000 0000 0000 0000
13:41:24.382250 IP localhost > localhost: ICMP localhost udp port 33435 unreachable, length 36
        0x0000:  0200 0000 4500 0038 00cc 0000 4001 7bf7
        0x0010:  7f00 0001 7f00 0001 0303 dab2 0000 0000
        0x0020:  4500 0028 9f9b 0000 0111 1c28 7f00 0001
        0x0030:  7f00 0001 9f9a 829b 0014 0000

With the patch below, the checksum is not checked in place -- i.e.

13:54:47.371646 IP localhost.33826 > localhost.33435: UDP, length 12
        0x0000:  0200 0000 4500 0028 8423 0000 0111 37a0
        0x0010:  7f00 0001 7f00 0001 8422 829b 0014 fb05
        0x0020:  0000 0000 0000 0000 0000 0000
13:54:47.371658 IP localhost > localhost: ICMP localhost udp port 33435 unreachable, length 36
        0x0000:  0200 0000 4500 0038 001b 0000 4001 7ca8
        0x0010:  7f00 0001 7f00 0001 0303 fb24 0000 0000
        0x0020:  4500 0028 8423 0000 0111 37a0 7f00 0001
        0x0030:  7f00 0001 8422 829b 0014 fb05

Patch is against -current, but applies to FreeBSD 6.2 as well.

>How-To-Repeat:
	tcpdump -i lo0 -s 1500 -xx
	traceroute -q 1 -n 127.0.0.1
>Fix:

	

--- udp_usrreq.c.patch begins here ---
--- udp_usrreq.c.orig	Thu May  3 12:24:55 2007
+++ udp_usrreq.c	Thu May  3 12:26:47 2007
@@ -248,23 +248,24 @@
 	 * Checksum extended UDP header and data.
 	 */
 	if (uh->uh_sum) {
+		u_short uh_sum;
 		if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
 			if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
-				uh->uh_sum = m->m_pkthdr.csum_data;
+				uh_sum = m->m_pkthdr.csum_data;
 			else
-				uh->uh_sum = in_pseudo(ip->ip_src.s_addr,
+				uh_sum = in_pseudo(ip->ip_src.s_addr,
 				    ip->ip_dst.s_addr, htonl((u_short)len +
 				    m->m_pkthdr.csum_data + IPPROTO_UDP));
-			uh->uh_sum ^= 0xffff;
+			uh_sum ^= 0xffff;
 		} else {
 			char b[9];
 			bcopy(((struct ipovly *)ip)->ih_x1, b, 9);
 			bzero(((struct ipovly *)ip)->ih_x1, 9);
 			((struct ipovly *)ip)->ih_len = uh->uh_ulen;
-			uh->uh_sum = in_cksum(m, len + sizeof (struct ip));
+			uh_sum = in_cksum(m, len + sizeof (struct ip));
 			bcopy(b, ((struct ipovly *)ip)->ih_x1, 9);
 		}
-		if (uh->uh_sum) {
+		if (uh_sum) {
 			udpstat.udps_badsum++;
 			m_freem(m);
 			return;
--- udp_usrreq.c.patch ends here ---


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun May 6 23:32:25 UTC 2007 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=112471 
Responsible-Changed-From-To: freebsd-net->andre 
Responsible-Changed-By: andre 
Responsible-Changed-When: Sun May 13 18:40:16 UTC 2007 
Responsible-Changed-Why:  
Take over. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=112471 
Responsible-Changed-From-To: andre->dwmalone 
Responsible-Changed-By: dwmalone 
Responsible-Changed-When: Wed May 16 04:38:56 UTC 2007 
Responsible-Changed-Why:  
I've already had a look at this problem, so I said to Andre 
that I'd deal with the PR. 

David. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/112471: commit references a PR
Date: Wed, 16 May 2007 09:12:24 +0000 (UTC)

 dwmalone    2007-05-16 09:12:16 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/netinet          udp_usrreq.c 
   Log:
   When verifying the IPv4 UDP checksum, don't overwrite the checksum
   value in the mbuf with the result of the calculation. Previously,
   if we chose to return an ICMP message, the quoted UDP checksum bytes
   would be different to what was sent.
   
   PR:             112471
   Submitted by:   Matthew Luckie <mluckie@cs.waikato.ac.nz>
   MFC after:      3 weeks
   
   Revision  Changes    Path
   1.209     +7 -5      src/sys/netinet/udp_usrreq.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"
 
State-Changed-From-To: open->closed 
State-Changed-By: dwmalone 
State-Changed-When: Sun Jun 10 07:44:04 UTC 2007 
State-Changed-Why:  
Now fixed in RELENG_4 - HEAD. Thanks for the patch. 

David. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=112471 
Responsible-Changed-From-To: dwmalone->freebsd-bugs 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Tue Jul 10 03:39:35 UTC 2012 
Responsible-Changed-Why:  
over to the pool (approved by bugmeister) 

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