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>