Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Sep 2001 09:50:06 -0700 (PDT)
From:      Jin Guojun <j_guojun@lbl.gov>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/16644: Bad comparsion expression in bpf_filter.c
Message-ID:  <200109041650.f84Go6X90120@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: Jin Guojun <j_guojun@lbl.gov>
To: Bruce Evans <bde@zeta.org.au>
Cc: mike@FreeBSD.ORG, freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: kern/16644: Bad comparsion expression in bpf_filter.c
Date: Tue, 04 Sep 2001 09:47:03 -0700

 Bruce Evans wrote:
 
 > 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
 
 The entire thing is messed up because the k is revised in the lastest BPF
 release.
 k is signed in the lastest release, and all above explanation is beased on signed
 K.
 It fixed the undefined overflow problem. Signed K does not work correctly,
 that is why you had above overflow issue. Overflow is wrong (not intended).
 Below is I explained to someone who asked about is:
 
 -------- original message -----------
 
 Jonathan Lemon wrote:
 
 > Hello -
 >
 >    I'm looking at bpf in FreeBSD, and it appears that our current
 > definition for the bpf_insn structure is:
 >
 >         struct bpf_insn {
 >                 u_short         code;
 >                 u_char          jt;
 >                 u_char          jf;
 >                 bpf_u_int32     k;
 >         };
 >
 > Note the last line has ``k'' being unsigned.  In the LBL releases,
 > it seems that there was a bit of confusion on the definition of
 > this field:
 >
 >         original berkeley release:      long
 >         LBL rev 1.34:                   bpf_u_int32
 >         LBL rev 1.36:                   bpf_int32
 >
 > Not having the RCS logs for the file, its not entirely clear
 > for the differing definitions here.  Is it intended that 'k'
 > may be negative in the bpf_insn structure?
 > --
 > Jonathan
 
 Yes, k may have negtive  value. I cannot recall when FreeBSD changed it,
 but I remember I read the email about it regarding some expression.
 They claimed make k non-negtive can fix their problem, I do not know what.
 
 Later sometime, I checked their expression which is bogus, so I send email
 to the bugs@freebsd.org, and explained that expression has nothing to do
 with int k or uint k. I asked them to change back because uint k breaks the
 kernel BPF functioning. No one was responsed.
 So, I put Kernel BPF patch on my web site in case some encounts problems.
 
     -Jin
 
 
 

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?200109041650.f84Go6X90120>