NetBSD Problem Report #32928

From pcah8322@artax.karlin.mff.cuni.cz  Sat Feb 25 12:18:09 2006
Return-Path: <pcah8322@artax.karlin.mff.cuni.cz>
Received: from mail.casablanca.cz (mail.casablanca.cz [82.208.31.182])
	by narn.netbsd.org (Postfix) with ESMTP id 32CB063B871
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 25 Feb 2006 12:18:09 +0000 (UTC)
Message-Id: <200602251217.k1PCHtb8000952@beta.martani.n2.repy.czf>
Date: Sat, 25 Feb 2006 13:17:55 +0100 (CET)
From: Pavel Cahyna <pcah8322@artax.karlin.mff.cuni.cz>
Reply-To: pavel.cahyna@st.mff.cuni.cz
To: gnats-bugs@netbsd.org
Subject: bpf filter can fail to extract a 32-bit quantity
X-Send-Pr-Version: 3.95

>Number:         32928
>Category:       kern
>Synopsis:       bpf filter can fail to extract a 32-bit quantity
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Feb 25 12:20:00 +0000 2006
>Last-Modified:  Sat Feb 25 14:35:01 +0000 2006
>Originator:     Pavel Cahyna
>Release:        4.3BSD NET/2 - NetBSD 3.99.15
>Organization:
>Environment:
System: NetBSD beta 3.0_RC5 NetBSD 3.0_RC5 (EV56) #3: Mon Dec 12 20:28:20 CET 2005 pavel@beta:/usr/src/sys/arch/alpha/compile/EV56 alpha
Architecture: alpha
Machine: alpha
>Description:
In net/bpf_filter.c there is a function m_xword() which extracts a
32-bit integer from a mbuf chain at a given offset k.

First, it determines where the integer starts:
	MINDEX(len, m, k);
m is now the first mbuf, len is its length and k is updated to the
offset of the data in the mbuf. Then we test if the whole integer is
in the mbuf:
	if (len >= k + 4) {
		*err = 0;
		return EXTRACT_LONG(cp);
	}
if it is not, we go to the next mbuf:
	m0 = m->m_next;
	if (m0 == 0 || m0->m_len + len - k < 4)
		goto bad;

but the "goto bad" if "m0->m_len + len - k < 4" is wrong - the integer
could legally continue in a third mbuf. Of course removing this check
is not enough - some code must be added to handle this situation.
>How-To-Repeat:
Code inspection.

This will be difficult to trigger (a 1- or 2- byte mbuf in the middle
of a mbuf chain is unlikely), but with functions like bpf_mtap2()
which prepend a short mbuf it could be possible.

>Fix:
I'm working on it. I propose to call m_xhalf() twice and concatenate
the results.

>Audit-Trail:
From: Pavel Cahyna <pavel.cahyna@st.mff.cuni.cz>
To: Rui Paulo <rpaulo@fnop.net>
Cc: gnats-bugs@netbsd.org
Subject: Re: kern/32928: bpf filter can fail to extract a 32-bit quantity
Date: Sat, 25 Feb 2006 14:42:50 +0100

 On Sat, Feb 25, 2006 at 12:51:33PM +0000, Rui Paulo wrote:
 > --- bpf_filter.c.~1.29.~	2006-02-10 20:08:13.000000000 +0000
 > +++ bpf_filter.c	2006-02-25 12:51:07.000000000 +0000
 > @@ -98,9 +98,13 @@ m_xword(struct mbuf *m, uint32_t k, int 
 >  		*err = 0;
 >  		return EXTRACT_LONG(cp);
 >  	}
 > -	m0 = m->m_next;
 > -	if (m0 == 0 || m0->m_len + len - k < 4)
 > -		goto bad;
 > +
 > +	for (m0 = m->m_next; ; m0 = m0->next) {
 > +		if (m0 == 0)
 > +			goto bad;
 > +		if (m0->m_len + len - k >= 4)
 > +			break;
 > +	}

 Sorry, I don't see how this is supposed to work. This would skip the short
 mbuf(s) and read different data than it is supposed to.

 BTW I'm planning to reorganize this code a bit... I just wanted to know if
 this is an actual bug and if calling m_xhalf twice would be OK.

From: Pavel Cahyna <pavel.cahyna@st.mff.cuni.cz>
To: Rui Paulo <rpaulo@fnop.net>
Cc: gnats-bugs@netbsd.org
Subject: Re: kern/32928: bpf filter can fail to extract a 32-bit quantity
Date: Sat, 25 Feb 2006 15:05:25 +0100

 On Sat, Feb 25, 2006 at 01:52:38PM +0000, Rui Paulo wrote:
 > >  BTW I'm planning to reorganize this code a bit... I just wanted to know if
 > >  this is an actual bug and if calling m_xhalf twice would be OK.
 > 
 > Alright. IIUC, m_xhalf will never be called twice with the same mbuf,
 > but I can be completely wrong and you'll probably correct me :-)

 I'm proposing this, so m_xhalf would actually be called twice with the
 same mbuf (of course, error handling is unfinished):

 Index: bpf_filter.c
 ===================================================================
 RCS file: /home/pavel/cvs/src/sys/net/bpf_filter.c,v
 retrieving revision 1.29
 diff -u -c -r1.29 bpf_filter.c
 cvs diff: conflicting specifications of output style
 --- bpf_filter.c	7 Feb 2006 20:10:48 -0000	1.29
 +++ bpf_filter.c	25 Feb 2006 14:01:27 -0000
 @@ -97,27 +97,10 @@
  	if (len >= k + 4) {
  		*err = 0;
  		return EXTRACT_LONG(cp);
 +	} else {
 +		return (m_xhalf(m, k, err) << 16) | m_xhalf(m, k+2, err);
  	}
 -	m0 = m->m_next;
 -	if (m0 == 0 || m0->m_len + len - k < 4)
 -		goto bad;
 -	*err = 0;
 -	np = mtod(m0, u_char *);
 -	switch (len - k) {
 -
 -	case 1:
 -		return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) |
 		np[2];
 -
 -	case 2:
 -		return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) |
 		np[1];

 -	default:
 -		return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) |
 		np[0];
 -	}
 -    bad:
 -	*err = 1;
 -
 -	return 0;
  }

  static int

From: David Laight <david@l8s.co.uk>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/32928: bpf filter can fail to extract a 32-bit quantity
Date: Sat, 25 Feb 2006 14:29:10 +0000

 On Sat, Feb 25, 2006 at 02:10:03PM +0000, Pavel Cahyna wrote:
 >  +	} else {
 >  +		return (m_xhalf(m, k, err) << 16) | m_xhalf(m, k+2, err);

 I suspect you really don't want to be doing that unless the data
 actually crosses 2 mbuf boundaries.
 In which case the correct thing to do is fix the underlying routine.

 	David

 -- 
 David Laight: david@l8s.co.uk

From: Pavel Cahyna <pcah8322@artax.karlin.mff.cuni.cz>
To: gnats-bugs@netbsd.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: kern/32928: bpf filter can fail to extract a 32-bit quantity
Date: Sat, 25 Feb 2006 15:32:07 +0100

 >  >  +	} else {
 >  >  +		return (m_xhalf(m, k, err) << 16) | m_xhalf(m, k+2, err);
 >  
 >  I suspect you really don't want to be doing that unless the data
 >  actually crosses 2 mbuf boundaries.

 Why not? Because of performance, or is such code incorrect?

 Pavel Cahyna

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.