Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Aug 2000 17:55:00 +1000 (Australia/NSW)
From:      Darren Reed <avalon@coombs.anu.edu.au>
To:        security@freebsd.org
Subject:   ipfw/bridging problem - 2 weeks.
Message-ID:  <200008130755.RAA19998@cairo.anu.edu.au>

next in thread | raw e-mail | index | archive | help

So ~two weeks have passed in the time since I posted about the bridging
code being less than robust.  It would seem that there were a lot of
people who made noises about "give us advance warning" - but only one
(that I've seen) who's actually looked at it/given any thought to doing
anything about it.

In future, if you're that distressed about something like that going
public before it goes private, before you flame the person(s) who make
it public, give some thought to whether or not you can actually do
something useful as opposed to just flame.  If you can't code up a
patch then don't flame others who don't have the time.

The patch below is the sort of thing which is required.  I've no idea
if this will compile nor if it is correct for the bridging code but
maybe someone else can review it and test it.

Darren

p.s. Yes I probably could have done this then but I was tired then and
needed sleep and was suffering from ENOTIME errors.

p.p.s. I couldn't test this further than doing this so I haven't
committed it.

Index: bridge.c
===================================================================
RCS file: /home/ncvs/src/sys/net/bridge.c,v
retrieving revision 1.23
diff -c -r1.23 bridge.c
*** bridge.c	2000/07/29 02:00:12	1.23
--- bridge.c	2000/08/13 07:43:31
***************
*** 661,667 ****
       */
      if (ip_fw_chk_ptr) {
  	struct ip_fw_chain *rule = NULL ;
! 	int off;
  	struct ip *ip ;
  
  	m = *m0 ;
--- 661,667 ----
       */
      if (ip_fw_chk_ptr) {
  	struct ip_fw_chain *rule = NULL ;
! 	int off, hlen;
  	struct ip *ip ;
  
  	m = *m0 ;
***************
*** 713,718 ****
--- 713,733 ----
  	}
  
  	/*
+ 	 * Sanity checks.  Copied from ip_input() with statistic dropped.
+ 	 * Not clear if ethernet header is present still or not...
+ 	 */
+ 	if (m->m_pkthdr.len < sizeof(struct ip))
+ 		return 0;
+ 	ip = mtod(m, struct ip *);
+ 	hlen = IP_VHL_HL(ip->ip_vhl) << 2;
+ 	if (hlen < sizeof(struct ip))	/* minimum header length */
+ 		return 0;
+ 	if (hlen > m->m_len) {
+ 		if ((m = m_pullup(m, hlen)) == 0)
+ 			return 0;
+ 	}
+ 
+ 	/*
  	 * before calling the firewall, swap fields the same as IP does.
  	 * here we assume the pkt is an IP one and the header is contiguous
  	 */
***************
*** 720,725 ****
--- 735,755 ----
  	NTOHS(ip->ip_len);
  	NTOHS(ip->ip_id);
  	NTOHS(ip->ip_off);
+ 
+ 	if (ip->ip_len < hlen)
+ 		return 0;
+ 	if (m->m_pkthdr.len < ip->ip_len)
+ 		return 0;
+ 	if (m->m_pkthdr.len > ip->ip_len) {
+ 		if (m->m_len == m->m_pkthdr.len) {
+ 			m->m_len = ip->ip_len;
+ 			m->m_pkthdr.len = ip->ip_len;
+ 		} else
+ 			m_adj(m, ip->ip_len - m->m_pkthdr.len);
+ 	}
+ 	/*
+ 	 * Packet should now be okay for firewalling checks.
+ 	 */
  
  	/*
  	 * The third parameter to the firewall code is the dst.  interface.


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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200008130755.RAA19998>