Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Sep 2001 02:10:01 -0700 (PDT)
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/16644: Bad comparsion expression in bpf_filter.c
Message-ID:  <200109010910.f819A1v53924@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/16644; it has been noted by GNATS.

From: Bruce Evans <bde@zeta.org.au>
To: "Jin Guojun[ITG]" <j_guojun@lbl.gov>
Cc: <mike@FreeBSD.ORG>, <freebsd-gnats-submit@FreeBSD.ORG>
Subject: Re: kern/16644: Bad comparsion expression in bpf_filter.c
Date: Sat, 1 Sep 2001 19:01:12 +1000 (EST)

 On Fri, 31 Aug 2001, Jin Guojun[ITG] wrote:
 
 > It is still there. I have replied this to the discussion and
 > got no response. For example, in line 220, ">" line is equal to
 > if (k > buflen || k + sizeof(int32_t) > buflen) {
 > or
 > if (k > buflen || k > buflen - sizeof(int32_t)) {
 >
 > if K > BUFLEN then K must > BUFLEN - 4
 
 This doesn't follow.  Example: K = 4U, BUFLEN = 2U, BUFLEN - 4 = UINT_MAX - 2.
 BUFLEN - 4 overflows.  I'm not sure if this overflow can give undefined
 behaviour instead of UINT_MAX - 2.
 
 > so we only want to judge if (k > buflen - sizeof(int32_t)) {
 > which is the "<" of line 220 -- if (k + sizeof(int32_t) > buflen) {
 >
 > Right? rests are ditto. The original design is correct.
 
 No.  Examples:
 
 (1) k = UINT_MAX - 2, buflen = 8U.  Then k + sizeof(int32_t) = 2U, which
     is <= buflen.  But k is much larger than buflen - sizeof(int32_t).
     Here arithmetic overflow occurs in the buffer overflow check and
     the buffer overflow check gives the wrong result.  The overflow
     checks were rewritten in FreeBSD to avoid arithmetic overflow.
 (2) k = -2 (signed int, as in the original design), buflen = 8U.  Then
     k + sizeof(int32_t) = 2U (no change).  This is the same overflow as
     in (1).  k first gets promoted to UINT_MAX - 2, then the addition
     overflows.
 
 > The real problem is at line 550. K is outside 0-BPF_MEMWORDS, not just >.
 > ...
 > 547c550
 > <                   (p->k >= BPF_MEMWORDS || p->k < 0))
 > ---
 > >                   p->k >= BPF_MEMWORDS)
 
 This patch is reversed (it gives the FreeBSD change).  Here FreeBSD
 simplified the check instead of complicating it.  p->k < 0 can't happen
 because p->k is unsigned.  The compiler should optimize away the
 complication and generate identical code, but it migh warn about a
 bogus comparison of an unsigned value with 0.
 
 Bruce
 

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




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