From owner-freebsd-bugs Fri Sep 5 03:00:35 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id DAA28857 for bugs-outgoing; Fri, 5 Sep 1997 03:00:35 -0700 (PDT) Received: from oskar.nanoteq.co.za (oskar.nanoteq.co.za [163.195.220.170]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id DAA28846; Fri, 5 Sep 1997 03:00:20 -0700 (PDT) Received: (from rbezuide@localhost) by oskar.nanoteq.co.za (8.8.7/8.8.5) id LAA04328; Fri, 5 Sep 1997 11:56:47 +0200 (SAT) From: Reinier Bezuidenhout Message-Id: <199709050956.LAA04328@oskar.nanoteq.co.za> Subject: Re: Bug in IPFW code ? In-Reply-To: <5816.873389344@critter.freebsd.dk> from Poul-Henning Kamp at "Sep 4, 97 06:09:04 pm" To: phk@critter.freebsd.dk (Poul-Henning Kamp) Date: Fri, 5 Sep 1997 11:56:47 +0200 (SAT) Cc: mickey@deadline.snafu.de, bugs@FreeBSD.ORG, alex@FreeBSD.ORG X-Mailer: ELM [version 2.4ME+ PL28 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-bugs@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk > >.121.229.34:17732 in via sl0 Fragment = 123 > > > >This packet was dropped, although it is not directed to the sunrpc port. > > > >Am I missing something, or is this definately a BUG? > > It's an IP-fragment, they have special security problems, and are denied, > unless you allow them. RTFM/YTSL I'm not sure I agree with this, if I'm wrong, please enlighten me :) Out of the info that is logged for this dropped packet, it seems to me that it can't be the first fragment, unless it doesn't contain the ports ? ... the value that is logged "Fragment = 123" is the offset field and according to RFC 1858, only packets with offset = 1 should be dropped not = 123 ?? Extract from /usr/src/sys/netinet/ip_fw.c line 436 offset = (ip->ip_off & IP_OFFMASK); .... line 445 if (offset == 1) /* cf. RFC 1858 */ goto bogusfrag; if (offset != 0) /* Flags, ports aren't valid */ break; This code is fine ... but let's now see what happens if this is a valid fragment and we break at "if (offset != 0)" .... We move out of the case statement (not checking the ports and flags) which is fine, but going throught the rest we fall straight through to the deny at the bottom, for this rule !! We should do a check just before the deny, checking the following: /* If this is a legal fragment and fragment flag is not set ... let it pass */ if ((offset > 1) && !(f->fw_flg & IP_FW_F_FRAG)) continue; line 550 /* Deny/reject this packet using this rule */ rule = f; break; So to conclude .. it does match the rule, because of the src and dst IP's, but because it's a fragment (legal size), and the rule is a DENY rule (it could have been any DENY rule with matching src and dst IP's), the packet is discarded. I include the diff (THIS HAS NOT BEEN TESTED!!!!), please Alex check me on this .... Reinier Bezuidenhout *** ip_fw.c.old Fri Sep 5 11:48:50 1997 --- ip_fw.c Fri Sep 5 11:49:42 1997 *************** *** 547,552 **** --- 547,558 ---- continue; } + /* If this is a legal fragment and fragment + * flag is not set ... let it pass + */ + if ((offset > 1) && !(f->fw_flg & IP_FW_F_FRAG)) + continue; + /* Deny/reject this packet using this rule */ rule = f; break;