Date: Thu, 01 Jul 1999 19:51:18 PDT From: Craig Leres <leres@ee.lbl.gov> To: FreeBSD-gnats-submit@freebsd.org Cc: vern@ee.lbl.gov (Vern Paxson), mccanne@eecs.berkeley.edu (Steven McCanne) Subject: kern/12484: [PATCH] bpf_filter() broken Message-ID: <199907020251.TAA28620@hot.ee.lbl.gov>
next in thread | raw e-mail | index | archive | help
>Number: 12484 >Category: kern >Synopsis: [PATCH] bpf_filter() broken >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Jul 1 20:00:01 PDT 1999 >Closed-Date: >Last-Modified: >Originator: Craig Leres >Release: FreeBSD 3.2-RELEASE i386 >Organization: Lawrence Berkeley National Laboratory >Environment: >Description: Revision 1.12 of sys/bpf_filter.c breaks certain packet filters. >How-To-Repeat: We noticed after upgrading our security system from 3.0-980414-SNAP to 3.2-RELEASE that the tcpdump filter: 'tcp[13] & 0x7 != 0' would not capture such packets. Debugging turned up a problem in this case: case BPF_LD|BPF_B|BPF_IND: k = X + pc->k; if (pc->k >= buflen || X >= buflen - k) { The conditional can be rewritten with "k" expanded: if (pc->k >= buflen || X >= buflen - (X + pc->k)) { which is the same as: if (pc->k >= buflen || X + X + pc->k >= buflen) { and is clearly wrong. Other cases where "k" is initialized to "X + pc->k" appear to either be broken or at least contain unnecessary checks. We consider this a serious bug because it breaks security monitoring software (including our "bro" package). >Fix: The appended context changes are against 1.13 (it looks like 3.2-RELEASE shipped with 1.12). RCS file: RCS/bpf_filter.c,v retrieving revision 1.3 diff -c -r1.3 bpf_filter.c *** /tmp/,RCSt1z29845 Thu Jul 1 19:43:31 1999 - --- bpf_filter.c Thu Jul 1 19:42:40 1999 *************** *** 217,223 **** case BPF_LD|BPF_W|BPF_ABS: k = pc->k; ! if (k > buflen || sizeof(int32_t) > buflen - k) { #ifdef KERNEL int merr; - --- 217,223 ---- case BPF_LD|BPF_W|BPF_ABS: k = pc->k; ! if (sizeof(int32_t) > buflen - k) { #ifdef KERNEL int merr; *************** *** 241,247 **** case BPF_LD|BPF_H|BPF_ABS: k = pc->k; ! if (k > buflen || sizeof(int16_t) > buflen - k) { #ifdef KERNEL int merr; - --- 241,247 ---- case BPF_LD|BPF_H|BPF_ABS: k = pc->k; ! if (sizeof(int16_t) > buflen - k) { #ifdef KERNEL int merr; *************** *** 285,292 **** case BPF_LD|BPF_W|BPF_IND: k = X + pc->k; ! if (pc->k > buflen || X > buflen - pc->k || ! sizeof(int32_t) > buflen - k) { #ifdef KERNEL int merr; - --- 285,291 ---- case BPF_LD|BPF_W|BPF_IND: k = X + pc->k; ! if (sizeof(int32_t) > buflen - k) { #ifdef KERNEL int merr; *************** *** 310,317 **** case BPF_LD|BPF_H|BPF_IND: k = X + pc->k; ! if (X > buflen || pc->k > buflen - X || ! sizeof(int16_t) > buflen - k) { #ifdef KERNEL int merr; - --- 309,315 ---- case BPF_LD|BPF_H|BPF_IND: k = X + pc->k; ! if (sizeof(int16_t) > buflen - k) { #ifdef KERNEL int merr; *************** *** 330,336 **** case BPF_LD|BPF_B|BPF_IND: k = X + pc->k; ! if (pc->k >= buflen || X >= buflen - k) { #ifdef KERNEL register struct mbuf *m; - --- 328,334 ---- case BPF_LD|BPF_B|BPF_IND: k = X + pc->k; ! if (k >= buflen) { #ifdef KERNEL register struct mbuf *m; -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQCVAwUBN3wpAr2JLbUEFcrxAQFg8wP8Cs1hzHa/s6VjDMQFy2SSbM8oH5lr272A /MMSl8tlreDcjZUcIhndB8DwVaQlTgMkZG+sAuxvCh4gglFOczxwk/oeikNuUFlt oCahmi/LjnTPAn/VRKvvw+LPA21mZ940V87sOdqhpE/PtOc5s8zNa0oGP0KWXsb/ 3IHfY3c49qI= =I7G8 -----END PGP SIGNATURE----- >Release-Note: >Audit-Trail: >Unformatted: -----BEGIN PGP SIGNED MESSAGE----- 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?199907020251.TAA28620>