From owner-freebsd-bugs@FreeBSD.ORG Tue Jul 3 14:30:06 2012 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 87B361065670 for ; Tue, 3 Jul 2012 14:30:06 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 5BABB8FC0A for ; Tue, 3 Jul 2012 14:30:06 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q63EU63e056785 for ; Tue, 3 Jul 2012 14:30:06 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q63EU6DC056784; Tue, 3 Jul 2012 14:30:06 GMT (envelope-from gnats) Resent-Date: Tue, 3 Jul 2012 14:30:06 GMT Resent-Message-Id: <201207031430.q63EU6DC056784@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Daniel Hartmeier Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 01314106566B for ; Tue, 3 Jul 2012 14:23:59 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id CA1708FC15 for ; Tue, 3 Jul 2012 14:23:58 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q63ENwjB028350 for ; Tue, 3 Jul 2012 14:23:58 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id q63ENwQI028349; Tue, 3 Jul 2012 14:23:58 GMT (envelope-from nobody) Message-Id: <201207031423.q63ENwQI028349@red.freebsd.org> Date: Tue, 3 Jul 2012 14:23:58 GMT From: Daniel Hartmeier To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: misc/169630: pf fragment reassembly of padded (undersized) fragments X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Jul 2012 14:30:06 -0000 >Number: 169630 >Category: misc >Synopsis: pf fragment reassembly of padded (undersized) fragments >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: Tue Jul 03 14:30:06 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Daniel Hartmeier >Release: 8.3-STABLE >Organization: >Environment: 8.3-STABLE i386 >Description: Some systems produce IP fragments that are so small that the minimum ethernet frame size requires padding. For example, a VOIP server may produce UDP SIP messages with 1516 bytes of UDP payload, using an MTU of 1500, creating a first fragment of 1472 bytes payload (+8 bytes UDP header, +20 bytes IP header, +14 bytes ethernet header), and a second fragment of 16 bytes (+20 bytes IP header, +14 bytes ethernet header, +10 bytes trailing ethernet padding). When pf is reassembling the second fragment, it is seeing an mbuf with m_len == 46 (including the 10 bytes of ethernet padding). The reassembly code will produce a reassembled IP packet that wrongly includes the padding bytes (as invalid ethernet checksum), which causes the IP packet to be dropped (usually after re-fragmentation) on the destination (or intermediate hops). >How-To-Repeat: Use two hosts, each with two interfaces (em0 and em1). Configure the second host as a bridge filtering with pf doing fragment reassembly. Connect them so the second host bridges between the first host's two interfaces. On the first host, send two fragments through the bridge. Expect the fragments to arrive at the bridge, get reassembled by pf, get re-fragmented, then arrive back at the first host. Instead, the first fragment will either not make it back, or is corrupted. #!/bin/sh dd if=/dev/random bs=1 count=1472 | \ dnet udp sport 5060 dport 5060 | \ dnet ip tos 104 id 49430 off 0+ ttl 63 proto udp src 172.19.243.20 dst 172.19.241.49 | \ dnet eth type ip src 00:50:56:9b:00:02 dst 00:50:56:9b:00:0b | \ dnet send em0 dnet hex "nt-Length: 0\r\n\r\n" | \ dnet ip tos 104 id 49430 off 1480 ttl 63 proto udp src 172.19.243.20 dst 172.19.241.49 | \ dnet eth type ip src 00:50:56:9b:00:02 dst 00:50:56:9b:00:0b | \ dnet send em0 >Fix: Index: sys/contrib/pf/net/pf_norm.c =================================================================== RCS file: /home/ncvs/src/sys/contrib/pf/net/pf_norm.c,v retrieving revision 1.19.10.1 diff -u -r1.19.10.1 pf_norm.c --- sys/contrib/pf/net/pf_norm.c 3 Aug 2009 08:13:06 -0000 1.19.10.1 +++ sys/contrib/pf/net/pf_norm.c 3 Jul 2012 10:57:25 -0000 @@ -413,6 +413,10 @@ /* Strip off ip header */ m->m_data += hlen; m->m_len -= hlen; + if (m->m_len > ip_len) { + DPFPRINTF(("truncating m_len %d -> %d\n", m->m_len, ip_len)); + m->m_len = ip_len; + } /* Create a new reassembly queue for this packet */ if (*frag == NULL) { >Release-Note: >Audit-Trail: >Unformatted: