From nobody@FreeBSD.org  Fri Mar  2 17:19:47 2001
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 8E66737B71A
	for <freebsd-gnats-submit@FreeBSD.org>; Fri,  2 Mar 2001 17:19:47 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.1/8.11.1) id f231Jl853311;
	Fri, 2 Mar 2001 17:19:47 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200103030119.f231Jl853311@freefall.freebsd.org>
Date: Fri, 2 Mar 2001 17:19:47 -0800 (PST)
From: jbrowne@jbrowne.com
To: freebsd-gnats-submit@FreeBSD.org
Subject: readudp() in libstand(3) can return incorrect packet lengths
X-Send-Pr-Version: www-1.0

>Number:         25503
>Category:       misc
>Synopsis:       readudp() in libstand(3) can return incorrect packet lengths
>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:   Fri Mar 02 17:20:01 PST 2001
>Closed-Date:    Mon May 28 15:27:18 PDT 2001
>Last-Modified:  Mon May 28 15:27:39 PDT 2001
>Originator:     Jim Browne
>Release:        4.2 RELEASE
>Organization:
>Environment:
FreeBSD XX.XX.com 4.2-STABLE FreeBSD 4.2-STABLE #0: Wed Jan 17 19:10:29 PST 2001     root@XX.XX.com:/usr/src/sys/compile/GENERIC  i386

>Description:
I noticed that readudp() in libstand(3) returns the UDP packet length
to the caller by taking the length of the packet from the netif device
and subtracting the size of a UDP and IP header.  If the netif
interface is unable to strip link-level padding bytes, those extra
bytes will be incorrectly passed on to the caller.

I noticed this problem because my netif driver which works with LANCE
style chips is unable to strip Ethernet padding bytes on short
Ethernet frames since it has no way to determine the true length of
the Ethernet frame and since the LANCE chip does not strip padding
bytes on short Ethernet frames.  So, if the UDP packet was less than
46 bytes long, up to 14 Ethernet padding bytes could be passed up by
the netif driver.  readudp() was happily passing those extra bytes on
to TFTP which meant that TFTP files whose length satisfied:

     ((length % 512) < 14)

would have the incorrect length (up to 14 bytes longer) when TFTPd.

Also, the shortest valid TFTP packet is 4 bytes, not 8.

A patch to fix the problem is included below.

>How-To-Repeat:

>Fix:
bash-2.04$ grep \$FreeBSD /usr/src/lib/libstand/tftp.c
 * $FreeBSD: src/lib/libstand/tftp.c,v 1.2.6.2 2000/05/04 13:47:52 ps Exp $
bash-2.04$ grep \$FreeBSD /usr/src/lib/libstand/udp.c
 * $FreeBSD: src/lib/libstand/udp.c,v 1.1.2.1 2000/04/15 03:09:29 ps Exp $
bash-2.04$ diff -c2p /usr/src/lib/libstand/tftp.c /tmp/tftp.c
*** /usr/src/lib/libstand/tftp.c        Thu May  4 06:47:52 2000
--- /tmp/tftp.c Fri Mar  2 17:06:03 2001
*************** recvtftp(d, pkt, len, tleft)
*** 120,124 ****
        len = readudp(d, pkt, len, tleft);
  
!       if (len < 8)
                return (-1);
  
--- 120,124 ----
        len = readudp(d, pkt, len, tleft);
  
!       if (len < 4)
                return (-1);
  
bash-2.04$ diff -c2p /usr/src/lib/libstand/udp.c /tmp/udp.c
*** /usr/src/lib/libstand/udp.c Fri Apr 14 20:09:29 2000
--- /tmp/udp.c  Fri Mar  2 17:06:29 2001
*************** readudp(d, pkt, len, tleft)
*** 268,272 ****
        }
  
!       n -= sizeof(*ip) + sizeof(*uh);
        return (n);
  }
--- 268,272 ----
        }
  
!       n = n > (ntohs(uh->uh_ulen) - sizeof(*uh)) ? ntohs(uh->uh_ulen) - sizeof(*uh) : n;
        return (n);
  }

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: msmith 
State-Changed-When: Mon May 28 15:27:18 PDT 2001 
State-Changed-Why:  

Patches applied; thanks for the fix! 


http://www.FreeBSD.org/cgi/query-pr.cgi?pr=25503 
>Unformatted:
