atom feed1 message in org.freebsd.freebsd-bugsmisc/25503: readudp() in libstand(3) ...
FromSent OnAttachments
jbro...@jbrowne.comMar 2, 2001 5:19 pm 
Subject:misc/25503: readudp() in libstand(3) can return incorrect packet lengths
From:jbro...@jbrowne.com (jbro@jbrowne.com)
Date:Mar 2, 2001 5:19:25 pm
List:org.freebsd.freebsd-bugs

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: open Quarter: Keywords: Date-Required: Class: sw-bug Submitter-Id: current-users Arrival-Date: Fri Mar 02 17:20:01 PST 2001 Closed-Date: Last-Modified: 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
ro@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: Unformatted:

To Unsubscribe: send mail to majo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message