From owner-freebsd-bugs@FreeBSD.ORG Wed Nov 30 08:50:04 2005 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 32E3316A41F for ; Wed, 30 Nov 2005 08:50:04 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id D25BC43D66 for ; Wed, 30 Nov 2005 08:50:02 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.3/8.13.3) with ESMTP id jAU8o2kQ017471 for ; Wed, 30 Nov 2005 08:50:02 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.3/8.13.1/Submit) id jAU8o2OL017470; Wed, 30 Nov 2005 08:50:02 GMT (envelope-from gnats) Resent-Date: Wed, 30 Nov 2005 08:50:02 GMT Resent-Message-Id: <200511300850.jAU8o2OL017470@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Guy Harris Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EB9B316A41F for ; Wed, 30 Nov 2005 08:49:49 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9A8C143D45 for ; Wed, 30 Nov 2005 08:49:49 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id jAU8nnpr048825 for ; Wed, 30 Nov 2005 08:49:49 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id jAU8nnAo048824; Wed, 30 Nov 2005 08:49:49 GMT (envelope-from nobody) Message-Id: <200511300849.jAU8nnAo048824@www.freebsd.org> Date: Wed, 30 Nov 2005 08:49:49 GMT From: Guy Harris To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-2.3 Cc: Subject: kern/89748: BPF indexed byte load can sign extend X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Nov 2005 08:50:04 -0000 >Number: 89748 >Category: kern >Synopsis: BPF indexed byte load can sign extend >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Nov 30 08:50:02 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Guy Harris >Release: >Organization: >Environment: >Description: The code to handle BPF non-indexed loads in bpf_filter() in bpf_filter.c is: case BPF_LD|BPF_B|BPF_ABS: k = pc->k; if (k >= buflen) { #ifdef _KERNEL struct mbuf *m; int len; if (buflen != 0) return 0; m = (struct mbuf *)p; MINDEX(len, m, k); A = mtod(m, u_char *)[k]; continue; #else return 0; #endif } A = p[k]; continue; which will load the byte at the offset in the instruction into the accumulator, zero-extending it. The code to handle indexed loads is case BPF_LD|BPF_B|BPF_IND: k = X + pc->k; if (k >= buflen) { #ifdef _KERNEL struct mbuf *m; int len; if (buflen != 0) return 0; m = (struct mbuf *)p; MINDEX(len, m, k); A = mtod(m, char *)[k]; continue; #else return 0; #endif } A = p[k]; continue; which will load the byte at the offset that's the sum of the offset in the instruction and the contents of the index register; if buflen is 0, as is the case when this is called from bpf_mtap(), it will sign-extend it on most if not all platforms, as the mbuf data pointer is cast to "char *" rather than "u_char *". Otherwise, as is the case when this is called from bpf_tap(), it'll zero-extend it, as "p" is a "u_char *". Presumably those semantics are not intended, as the same instruction behaves differently depending on how the tapping is being done, and on whether the load is indexed or not. (In libpcap's user-mode filter, it's never sign-extended.) In NetBSD, it's "u_char" in both "mtod()" calls, fixing that. >How-To-Repeat: >Fix: Index: bpf_filter.c =================================================================== RCS file: /cvs/src/sys/net/bpf_filter.c,v retrieving revision 1.15 diff -c -r1.15 bpf_filter.c *** bpf_filter.c 28 Sep 2005 20:53:56 -0000 1.15 --- bpf_filter.c 30 Nov 2005 07:58:29 -0000 *************** *** 301,307 **** return 0; m = (struct mbuf *)p; MINDEX(len, m, k); ! A = mtod(m, char *)[k]; continue; #else return 0; --- 301,307 ---- return 0; m = (struct mbuf *)p; MINDEX(len, m, k); ! A = mtod(m, u_char *)[k]; continue; #else return 0; >Release-Note: >Audit-Trail: >Unformatted: